Screencast: Testing, Mocking and Dependency Injection: more than just buzz-words
This 40 minute screencast covers unit testing, mocking, dependency injection, and inversion of control.
The idea is again that this will be is very much a hands-on, practical screencast. Not technology for its own sake, but reviewing how and why these concepts evolved, and how they can be used in practice.
I'm not a TDD (Test Driven Development) fanatic, I don't think we should always have 100% code coverage with our tests, but I do think there is a lot of value in testing, and in making our code testable.
The screencast is available here http://damianblog.com/TestingMockingAndDependencyInjection.wmv
Screencast intro to VS 2008 & .NET 3.5
I recently gave a presentation at work introducing some of the new features of VS 2008 and .NET 3.5. No slides, just code. And no pre-prepared chunks of code that are pasted into the editor either - everything written by hand.
In this 40 minute screencast I blast through Automatic Properties, Collection Initializers (Lists & Dictionaries), Implicit Typing, Anonymous Types, Extensions Methods, "Normal" Delegates, Anonymous Delegates, a natural evolution of delegates to Lambda expressions, Linq to objects using method chaining, Linq to objects using the natural Linq syntax, and finally Linq to XML.
Download or watch the screencast here: http://damianblog.com/WhatsNewInVS2008and.NET3.5.wmv
Microsoft fixed my bug
Like a lot of people, when I first began developing on a "proper" Operating System (as opposed to the 8 bit computers I started with), sooner or later I convinced myself I'd found a bug in the operating system.
Of course I'd be wrong, and after suffering the embarrassment of discovering that it was my own stupidity, rather than an OS bug, that was causing the errors, I eventually acquired an automatic reflex to never ever believe that there was a bug in the OS. It had to be a bug in my code. This was a good thing, since I was always right.
Despite this, it seems that I never fully learned this lesson. And so it was that last May I opened a bug report on Microsoft Connect, fully expecting to be gently, but firmly rebuffed, with an explanation of where exactly I'd gone wrong.
The issue that I was facing was in detecting whether a connection to my web application was coming from the local machine (running the web application), or from a remote machine. I was calling the HttpListenerContext.Request.IsLocal method, and it was always returning false, even though the client was definitely local.
A little digging with Reflector showed that the method was implemented using "==" to compare the local address with the remote address, instead of the Equals method. If the "==" operator had been overloaded then it would have worked.
A couple of days ago, I got a message saying that this was indeed a bug, and that it was fixed in version 4.0 of the .NET framework. So it looks like I have finally actually discovered an honest-to-goodness bug.
Or perhaps they are just being kind to me.
Small utility to generate summary of your Media Center recorded movies
I've created a small simple utility to create an HTML summary document listing all the movies I've recorded using Vista Media Center.
I did this to get a compact record which I can browse without firing up Media Center, and which I can print out to give to visitors that are not familiar with Media Center.
This is what the output looks like:
The links you can see are links to IMDB.
When you run the utility you can choose the directories it should look in, and the name of the output file:
The first checkbox lets you tell the utility to only output films that it has found duplicated -- I added this so that I could easily find films that I'd recorded twice by accident. The second checkbox tells it to also output the locations of the media files so that you can see where they are.
This tool is free, unsupported, and is to be used entirely at your own risk. You can download it here.
You might also want to check out this other utility which you can use to download image files for your films so that the images appear in generated html and also in Windows Media Center.
Dealing with WCF Error: Cannot create a service reference with namespace X because the name is already in use by an existing service reference, folder or file
If you get the above error when trying to add a WCF service reference that you have previously deleted then try:
- deleting the Service References.DeviceService.Reference.cs.dll file you'll find under obj\Debug\TempPE.
- deleting the service folder you'll still find under Service References on disk, even though you deleted the reference in Visual Studio.
- commenting out all references to the service's namespace in your code
- rebuilding
My PDC 2008 "Show Off" entry: Using .NET code injection to do the seemingly impossible
Having come third in the first event "Show Off" entry, for PDC 2005, I decided to submit an entry for the 2008 PDC.
I decided to base my entry on a .NET code injection blog article I'd written a couple of months ago. I got a very positive response from the people running the contest, although on the night I didn't actually win.
I missed the showing of my entry because I was attending a dinner thrown by Microsoft Switzerland for the people that attended the PDC from Switzerland.
In any event, here is my entry: http://damianblog.com/DamianMehersPDC2008ShowOff.wmv
WCF REST Services: Setting the response format based on request’s expected type
I just attended the Microsoft PDC in LA. One of the many excellent sessions was a pre-conference on WCF, part of which was presented by Ron Jacobs. Ron did a fantastic job of explaining WCF REST Services and the WCF REST Starter Kit.
One of the examples he showed from the WCF REST Starter kit was an example where the response type (JSON or XML) is dynamically set based on the HTTP request's requested content type in the "Accepts" HTTP Header.
That example works by switching between two different operation implementations (methods).
I liked the idea of using the requested content type to automatically return JSON or XML depending on the requested content type, but I wasn't so keen on having to implement two methods.
I thought I'd try to get a similar thing working but using a single operation implementation which is called no matter whether or JSON or XML are requested.
The DynamicResponseType attribute
This is how it works. You decorate your method with an additional DynamicResponseType attribute which I have defined:
1: [ServiceContract]
2: [ServiceBehavior(IncludeExceptionDetailInFaults = true, InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
3: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
4: public class Service1
5: {
6: [OperationContract]
7: [WebGet(UriTemplate = "GetData?param1={i}¶m2={s}")]
8: [DynamicResponseType]
9: public SampleResponseBody GetData(int i, string s)
10: {
11: return new SampleResponseBody() {
12: Name = "Test",
13: Value = s,
14: Time = DateTime.Now.ToShortTimeString()
15: };
16: }
17: }
18:
19: public class SampleResponseBody
20: {
21: public string Name { get; set; }
22: public string Value { get; set; }
23: public int IntValue { get; set; }
24: public string Time { get; set; }
25: }
An example client
Then when the client requests a specific type (XML or JSON), it is served automatically.
Below I have a pure HTML/Javascript client with two buttons, each of which call the same GetWebRequest function when they are clicked but passing a different requested content type as a parameter. The GetWebRequest function issues an HTTP request to the WCF operation I showed above.
The first button says it wants JSON, and the second XML. This is done by setting the "Accept" request header:
1: <body>
2: <form id="form1" runat="server">
3: <div>
4:
5: <input type="button" value="Click to request JSON"
6: onclick="GetWebRequest('application/json');" />
7:
8: <input type="button" value="Click to request XML"
9: onclick="GetWebRequest('application/xml');" />
10:
11: </div>
12: <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
13: </form>
14:
15: <script type="text/javascript">1:2: function GetWebRequest(acceptType) {3: var wRequest = new Sys.Net.WebRequest();4: wRequest.get_headers()["Accept"] = acceptType;5: var url = "/Service1.svc/GetData?param1=12¶m2=";6: wRequest.set_url(url + new Date());7: wRequest.set_httpVerb("GET");8: wRequest.add_completed(OnWebRequestCompleted);9: wRequest.invoke();10: }11:12: function OnWebRequestCompleted(executor, eventArgs) {13: alert(executor.get_responseData());14: }</script>
16: </body>
This is the form that gets displayed initially:
When you click on the first button we request JSON from the WCF Service operation:
When you click on the second button we request XML from the same WCF Service operation:
How it works.
I've created my own WCF ServiceHostFactory which I wire up in the SVC file:
1: <%@ ServiceHost Language="C#"
2: Debug="true"
3: Service="WcfService2.Service1"
4: CodeBehind="Service1.svc.cs"
5: Factory="DamianBlog.ServiceHostFactory2Ex" %>
In my ServiceHostFactory2Ex class I ensure that my own WebServiceHost class gets created.
Then in my own WebServiceHost I ensure that my own WebHttpBehavior replaces the standard one.
Next in my own WebHttpBehavior I override the GetReplyDispatchFormatter method and return my own IDispatchMessageFormatter.
In my own IDispatchMessageFormatter I implement the SerializeReply method and then use a JSON formatter or XML formatter depending on the "Accepts" HTTP request header which I pick up from the OperationContext.Current.RequestContext.RequestMessage.
The full source is available for download here http://damianblog.com/WCFDynamicResponseDemo.zip.
Rob Jacobs blogs at http://blogs.msdn.com/rjacobs/
To right click running Vista on new (late 2008) MacBook Pros
All the documentation says to press two-fingers and click, but actually you must press down three fingers and then click to right-click when running Vista, Boot Camped on the new MacBook Pros (late 2008).
ASP.NET MVC with the AJAX Control Toolkit: automatically getting control dependencies
[Edited 23rd Oct to compress returned JavaScript]
I recently wrote a blog post showing how you can use controls from the AJAX Control Toolkit in ASP.NET MVC applications, specifically the ListSearchExtender. Stephen Walther also wrote one on using the Calendar control here.
One thing that bugged me was that it was painful to find out what scripts a particular control depended on, so that they could be included in the JavaScript used to initialize a control.
I decided to create a simple MVC Controller/View that would return back all the JavaScript required for any particular ASP.NET AJAX Control Toolkit control.
This is the old code for using the ListSearchExtender in an ASP.NET MVC View:
<select id="Countries"> <option>Switzerland</option> <option>United Kindom</option> <option>United States</option> </select> <script src="/Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.Common.Common.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.ExtenderBase.BaseScripts.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.DynamicPopulate.DynamicPopulateBehavior.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.Compat.Timer.Timer.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.Animation.Animations.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.Animation.AnimationBehavior.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.PopupExtender.PopupBehavior.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.PopupControl.PopupControlBehavior.js" type="text/javascript"></script> <script src="/Scripts/AjaxControlToolkit.ListSearch.ListSearchBehavior.js" type="text/javascript"></script> <script type="text/javascript"> Sys.Application.initialize(); Sys.Application.add_init(function() { $create(AjaxControlToolkit.ListSearchBehavior, { "id": "ListBox1_ListSearchExtender" }, null, null, $get("Countries")); }); </script>
This is the new code to pull in the dependencies:
<select id="Countries"> <option>Switzerland</option> <option>United Kindom</option> <option>United States</option> </select> <script src="/ControlDependencies/Get?extenderTypeName=AjaxControlToolkit.ListSearchExtender" type="text/javascript"></script> <script type="text/javascript"> Sys.Application.initialize(); Sys.Application.add_init(function() { $create(AjaxControlToolkit.ListSearchBehavior, { "id": "ListBox1_ListSearchExtender" }, null, null, $get("Countries")); }); </script>
You'll see that all the individual script includes have been replaced by a single call to the Get action on the ControlDependencies controller.
This is the source to the controller:
using System; using System.Collections.Generic; using System.Reflection; using System.Web.Mvc; using AjaxControlToolkit; namespace TestDependencies.Controllers { public class ControlDependenciesController : Controller { readonly Assembly toolkitAssembly = typeof(AjaxControlToolkit.Utility).Assembly; [OutputCache(VaryByParam = "extenderTypeName", Duration = 86400, // One day Location = System.Web.UI.OutputCacheLocation.Client)] public ActionResult Get(string extenderTypeName) { if (string.IsNullOrEmpty(extenderTypeName)) { return new EmptyResult(); } // Get the type representing the extender we are handling Type extenderType = toolkitAssembly.GetType(extenderTypeName, false); if(extenderType == null) { return new EmptyResult(); } // What other extenders does this one depend on? Stack<Type> dependencies = new Stack<Type>(); AddDependencies(extenderType, dependencies); // What scripts do those extenders require? List<string> scriptsToInclude = new List<string>(); GetDependencyScripts(dependencies, scriptsToInclude); return PartialView(scriptsToInclude); } // Find the types that the specified extender type depends on static void AddDependencies(Type extenderType, Stack<Type> dependencies) { dependencies.Push(extenderType); Attribute[] attributes = Attribute.GetCustomAttributes(extenderType, typeof(RequiredScriptAttribute)); foreach (RequiredScriptAttribute attribute in attributes) { AddDependencies(attribute.ExtenderType, dependencies); } } // Find the scripts used by the specified extender types static void GetDependencyScripts(IEnumerable<Type> dependencies, ICollection<string> scripts) { foreach (Type dependency in dependencies) { Attribute[] attributes = Attribute.GetCustomAttributes(dependency, typeof(ClientScriptResourceAttribute)); foreach (ClientScriptResourceAttribute attribute in attributes) { if (!scripts.Contains(attribute.ResourcePath)) { scripts.Add(attribute.ResourcePath); } } } } } }
The View is a User Control that simply outputs all of the required scripts. This is the code-behind:
using System; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Web.Mvc; namespace TestDependencies.Views.ControlDependencies { public partial class Get : ViewUserControl<List<string>> { protected void Page_Load(object sender, EventArgs e) { Response.ContentType = "application/x-javascript"; // Get compressed stream if possible Stream outputStream = GetOutputStream(); using(StreamWriter outputWriter = new StreamWriter(outputStream)) { // Standard AJAX library string script = File.ReadAllText( MapPath("/Scripts/MicrosoftAjax.js")); outputWriter.WriteLine(script); // Required scripts foreach(string scriptPath in ViewData.Model) { script = File.ReadAllText(MapPath("/Scripts/" + scriptPath)); outputWriter.WriteLine(script); } } Response.End(); } // Compress scripts if possible -- stolen from ToolkitScriptManager // in AJAX Control Toolkit private Stream GetOutputStream() { Stream outputStream = Response.OutputStream; if(!Request.Browser.IsBrowser("IE") || (6 < Request.Browser.MajorVersion)) { foreach( string acceptEncoding in (Request.Headers["Accept-Encoding"] ?? "").ToUpperInvariant().Split(',')) { if("GZIP" == acceptEncoding) { Response.AddHeader("Content-encoding", "gzip"); outputStream = new GZipStream(outputStream, CompressionMode.Compress); break; } if("DEFLATE" == acceptEncoding) { Response.AddHeader("Content-encoding", "deflate"); outputStream = new DeflateStream(outputStream, CompressionMode.Compress); break; } } } return outputStream; } } }
The ASCX is empty:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Get.ascx.cs" Inherits="TestDependencies.Views.ControlDependencies.Get" %>
There are two advantages to using this technique. Firstly performance should be increased since all the required scripts are returned in a single response. Secondly you don't have to manually work out the dependencies for a particular ASP.NET AJAX Control Toolkit control.
Using Moq ExpectSet
I am trying out Moq, having used RhinoMocks a fair bit in the past.
I was having trouble using the ExpectSet method which verifies that a property has been set, and a google search found nothing that directly answered my question. I wanted to know how to verify that the value set is what was expected.
It turns out that you need to define a callback in which you have the assertion to verify that the property has been set to the correct value.
[TestMethod] public void TestAppleShiner() { // Mock the interface being passed to the class to be tested var fruit = new Mock<IFruit>(); // Define the expectation that the Colour property will be // set to Green fruit.ExpectSet(f=>f.Colour).Callback( setColor=>Assert.AreEqual("Green", setColor)).Verifiable(); // Run the test ApplePolisher applePolisher = new ApplePolisher(); applePolisher.Polish(fruit.Object); // Verify that the test passed (note .Verifiable on the ExpectSet) fruit.VerifyAll(); } public interface IFruit { string Colour { get; set; } } public class ApplePolisher { public void Polish(IFruit fruit) { fruit.Colour = "Green"; } }