Tuesday, 28 September 2010

Why you can’t assert a return type of an MVC Controller Action using reflection!

I recently asked this question on Stack Overflow.  I was using reflection and MethodInfo to confirm that a controller contained an action with the required method parameters.  If one was found, this would then allow my code to unit test that the correct Action Filter Attributes were being assigned to the controller action (so a particular action could only respond to an HTTP GET or POST as an example).  

This was all working fantastically well but I made the mistake of trying a unit test too far and was surprised by the outcome.  I was attempting to assert/validate the return type was of the desired type (e.g. ActionResult or JSONResult) but my assertion was failing.  In the debug watch window I could see the return parameter was of the desired type but it was wrapped up inside a RuntimeType.  No amount of fiddling / casting would get the test to pass.  Another SO user helpfully pointed out that an MVC action might actually return RedirectToRouteResult, etc. so the wrapping was a requirement of the call – it was working as intended.

Thinking this through to it’s conclusion my original test was flawed, even if it was possible there is no need to test the return type of the reflected method info.   Only when I am testing actual calls to the controller am I interested in what the returned type is and what it contains!

del.icio.us Tags: ,

Team Foundation Server 2010 Licensing

UPDATE: Since putting this article together MS have released their VS2010 and MSDN Licensing White Paper, which whilst it confirms all of the following should be used in preference to this information.

Original Article:

Firstly, a bit of a disclaimer - the following are just my observations / opinions only and should not be used to plan any purchase or decision.  I also have no association with Microsoft or any reseller.

As part of a new role I've recently been looking into the costs associated with rolling out TFS 2010 and whilst Microsoft seem to be making their product structure / licensing easier if the confusion surrounding TFS is anything to go by then they've still got a little more to do.

There are two main ways to obtain TFS:

  1. As part of VS2010 + MSDN, or
  2. As a stand alone product.

As far as I can ascertain both include exactly the same version of TFS. Along the VS2010 MSDN subscription a developer receives 1 Client Access License (CAL) for use with TFS.  This allows that developer to connect to any instance of TFS. The stand-alone TFS product does not come with any CALs, these must be purchased separately. However it does come with 5 EULA exception licenses (see following blog article). This allows up to 5 users to connect to that instance of TFS without needing a CAL. Note: you can not coalesce / merge these EULA licensed exceptions in that if you purchased two instances of TFS you would have 2x5 EULA exception licenses - if you had 4 users on one instance and wanted to add a 6th user to the other instance you would need to purchase a full TFS CAL for that 6th user, you could not transfer the unused license from the 1st instance to the other server. Also worth noting that in this scenario the 6th user that has the CAL would be able to use the 1st instance without using up that 5th EULA exception license.

Therefore if only developers are going to be accessing / using TFS and they all have MSDN subscriptions you do not need to purchase the standalone product.  However, if you wish for product managers and testers to access / use TFS, then you should probably purchase the stand alone product too, then up to another 5 people can connect to that instance of TFS along with the developers.

Injecting HttpContextBase into an MVC Controller

It is a shame that when the ASP.NET MVC framework was released they did not think to build IoC support into the infrastructure. All the major components of the MVC engine appear to magically inherit instances of HttpContext and it’s related objects – which can cause no end of problems if you are trying to utilise Unit Testing and IoC. Reading around various articles on the subject just to get around this one problem requires the implementation of several different concepts and you are still left with a work around. The code below, along with the other links referenced in this article is my stab at resolving the issue. There’s probably nothing new here, but it does attempt to relate all the information needed to do this for Castle Windsor. The overview is that all controllers will need to inherit from a base controller, which takes an instance of HttpContext into it’s constructor. It then overrides the property HttpContext in the main controller class, supplying it’s own version instead.

Note: I’m still not sure if providing a default constructor that takes the base instance of HttpContext is a good idea as I’ve not had chance to fully test that functionality – it’s there as a concept that it could be done but from what I’ve learnt recently in injecting HttpContext into Action Filter Attributes I think it will cause problems. Use that constructor with caution!

public abstract class BaseController : Controller
{
public new HttpContextBase HttpContext { get; private set; }

protected BaseController()
{
this.HttpContext = base.HttpContext;
}

protected BaseController(HttpContextBase httpContext)
{
if(httpContext == null)
{
throw new ArgumentNullException("httpContext");
}
HttpContext = httpContext;
}
}

This partial class can then be inherited and used as shown below. Using this ControllerFactory the injection of the HttpContextBase instance will be handled by the IoC container.

public partial class RealWorldController : BaseController
{
public ReadWorldController(HttpContextBase httpContext)
: base(httpContext)
{
...
}
...
}

Now along with Mocking HttpContextBase your controllers should be easy to inject and unit test!

Controller Factory for Castle Windsor v2.5.0, with HttpContext Resolution/Injection

The code below defines an object that holds an instance of the Castle Windsor container and sets it up to handle all requests to resolve ASP.NET MVC Controllers.  It also includes code to inject instances of HttpRequest and HttpContextBase.  This means that you can define injected objects that contain references to HttpContextBase in their constructors (which can be your MVC controllers) and they will receive populated instances of these objects.  It is worth noting that if you reference an instance of HttpContext that has not been resolved / injected by your IoC container then there is a high likely hood that you will end up with two or more separate instances which will cause problems (see this article on Injecting into Action Filter Attributes that can suffer this issue).

Please feel free to use this code and let me know if you run into any issues or have recommendations on how it could be improved.

public class WindsorControllerFactory : DefaultControllerFactory
{
IWindsorContainer Container { get; set; }

public WindsorControllerFactory(IWindsorContainer container)
{
Container = container;
Container.Register(AllTypes.FromThisAssembly().BasedOn(typeof(IController)).Configure(c => c.LifeStyle.Is(LifestyleType.Transient)));

Container.Register(Component.For<HttpRequestBase>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => new HttpRequestWrapper(HttpContext.Current.Request)));

Container.Register(Component.For<HttpContextBase>()
.LifeStyle.PerWebRequest
.UsingFactoryMethod(() => new HttpContextWrapper(HttpContext.Current)));

Container.Register(Component.For<HttpContext>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => HttpContext.Current));
}

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return (IController)Container.Resolve(controllerType);
}

public override void ReleaseController(IController controller)
{
Container.Release(controller);
}
}

This can then just be simple called by adding the following to your global.asax code.  Note: This expects a “castle” section to be defined in your web.config to resolve non-controller references handled within the WindsorControllerFactory.

public static IWindsorContainer WindsorContainer { get; private set; }

protected void Application_Start()
{
WindsorContainer = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(WindsorContainer));
...

IoC and MVC Action Filter Attributes

As I’ve previously mentioned anyone starting out with IoC and ASP.NET MVC quickly encounters problems injecting HttpContext and related classes into controllers, etc.  A similar issue surrounds Action Filter Attributes but is not limited to just HttpContext as objects inheriting from ActionFilterAttribute must contain a “parameter less” default constructor.  Without a “parameter less” constructor these objects can not be created when used to decorate a class or action declaration.  Also, the MVC engine is responsible for the creation of the attributes when they are decorating class/action declarations, completely by-passing the IoC container and any hope of using property injectors. 

The only way to gain access to the IoC container is to make sure that it is available through a static public object (such as global.asax) and reference the container directly in the filter constructor.  This is not ideal, but checking other articles on the web, there does not appear to be any better solution available.   It is also a good idea to provide a constructor that can be used for DI for Unit Testing the action filter in isolation.

It is also worth noting that if you control the creation/injection of HttpContextBase within your IoC container, then the version of HttpContext that is held in filterContext in “OnActionExecuting” will be a different instance to that supplied in the IoC container.  In this example I attempted to use filerContext.HttpContext.Response to write cookie values that were checked later.  This code failed because the Action Filter and IoC container worked against separate instances – I would write the cookie, but the subsequent read would not find it.  Also the Response object in the filter would always record that the client was not connected.

public class RequiresAuthenticationAttribute : ActionFilterAttribute
{
// As you can't inject directly into an action filter, this allows full control for
// unit testing, whilst providing auto creation for actual code.
private IAuthenticationCookie _authenticationCookie;

public RequiresAuthenticationAttribute()
{
_authenticationCookie = MvcApplication.WindsorContainer.Resolve<IAuthenticationCookie>();
}

public RequiresAuthenticationAttribute(IAuthenticationCookie authenticationCookie)
{
if (authenticationCookie == null) throw new ArgumentNullException("authenticationCookie");
_authenticationCookie = authenticationCookie;
}

public string Controller { get; set; }
public string Action { get; set; }

public override void OnActionExecuting(ActionExecutingContext filterContext)
{



del.icio.us Tags: ,,

Updating NServiceBus to use another version of Castle Windsor

Having recently taken a look at NServiceBus, the first obstacle that I encountered was that it was not compatible with the version of Castle Windsor which we were using.  Luckily due to the design of NServiceBus adding a new version of an IoC framework is relatively painless if you follow a couple of basic steps and follow the format laid out by the existing framework.  Whilst the NServiceBus documentation say what you need to do, it does not say why or how.  It probably took longer than it should for me to realise that I could easily download the source code and modify the existing Castle Windsor object builder instance for the version that we were using. 

As recommended within NServiceBus I created a new VS project called “NServiceBus.ObjectBuilder.CastleWindsor.2.5.0” adding a reference to the Castle binaries we would be using (as you may have guessed from the project name, that was v2.5.0).  The project only needed two classes defined (Windsor250ObjectBuilder & ConfigureWindsorBuilder) the code for which is listed below.   Please feel free to copy / modify this code as needed – if you find any obvious issues please let me know.  As I’m only just starting out with NServiceBus and Castle Windsor, I’m not sure if I will be able to assist much – but at the very least I can either update this article with a relevant note or improvement.

namespace NServiceBus.ObjectBuilder.CastleWindsor
{
    usingSystem;
    usingSystem.Collections.Generic;
    usingSystem.Linq;
    usingCastle.MicroKernel.Releasers;
    usingCommon;
    usingCastle.Windsor;
    usingCastle.MicroKernel;
    usingCastle.Core;
    usingCastle.MicroKernel.Registration;

    /// <summary>
    ///
Castle Windsor implementaton of IContainer.
  
/// </summary>
  
public classWindsor250ObjectBuilder: IContainer
  
{
        /// <summary>
        ///
The container itself.
      
/// </summary>
      
publicIWindsorContainer Container { get; set; }

        /// <summary>
        ///
Instantites the class with a new WindsorContainer setting the NoTrackingReleasePolicy.
      
/// </summary>
      
publicWindsor250ObjectBuilder()
        {
            Container = newWindsorContainer();
            Container.Kernel.ReleasePolicy = newNoTrackingReleasePolicy();
        }

        /// <summary>
        ///
Instantiates the class saving the given container.
      
/// </summary>
        /// <param name="container"></param>
      
publicWindsor250ObjectBuilder(IWindsorContainer container)
        {
            Container = container;
        }

        voidIContainer.Configure(TypeconcreteComponent, ComponentCallModelEnum callModel)
        {
            var handler = GetHandlerForType(concreteComponent);
            if(handler == null)
            {
                var lifestyle = GetLifestyleTypeFrom(callModel);

                var reg = Component.For(GetAllServiceTypesFor(concreteComponent)).ImplementedBy(concreteComponent);
                reg.LifeStyle.Is(lifestyle);

                Container.Kernel.Register(reg);
            }
        }

        voidIContainer.ConfigureProperty(Typecomponent, stringproperty, objectvalue)
        {
            var handler = GetHandlerForType(component);
            if(handler == null)
                throw newInvalidOperationException("Cannot configure property for a type which hadn't been configured yet. Please call 'Configure' first.");

            handler.AddCustomDependencyValue(property, value);
        }

        voidIContainer.RegisterSingleton(TypelookupType, objectinstance)
        {
            //Container.Kernel.AddComponentInstance(Guid.NewGuid().ToString(), lookupType, instance);
          
Container.Register(Component.For(lookupType).Named(Guid.NewGuid().ToString()).Instance(instance));
        }

        objectIContainer.Build(TypetypeToBuild)
        {
            try
          
{
                returnContainer.Resolve(typeToBuild);
            }
            catch(ComponentNotFoundException)
            {
                return null;
            }
        }

        IEnumerable<object> IContainer.BuildAll(TypetypeToBuild)
        {
            returnContainer.ResolveAll(typeToBuild).Cast<object>();
        }

        private staticLifestyleType GetLifestyleTypeFrom(ComponentCallModelEnum callModel)
        {
            switch(callModel)
            {
                caseComponentCallModelEnum.Singlecall: returnLifestyleType.Transient;
                caseComponentCallModelEnum.Singleton: returnLifestyleType.Singleton;
            }

            returnLifestyleType.Undefined;
        }

        private staticIEnumerable<Type> GetAllServiceTypesFor(Typet)
        {
            if(t == null)
                return newList<Type>();

            var result = newList<Type>(t.GetInterfaces()) { t };

            foreach (var interfaceType int.GetInterfaces())
                result.AddRange(GetAllServiceTypesFor(interfaceType));

            returnresult;
        }

        privateIHandler GetHandlerForType(TypeconcreteComponent)
        {
            returnContainer.Kernel.GetAssignableHandlers(typeof(object))
                .Where(h => h.ComponentModel.Implementation == concreteComponent)
                .FirstOrDefault();
        }
    }
}

namespace NServiceBus
{
using ObjectBuilder.Common.Config;
using Castle.Windsor;

using ObjectBuilder.CastleWindsor;

/// <summary>
///
Contains extension methods to NServiceBus.Configure.
/// </summary>
public static class ConfigureWindsorBuilder
{
/// <summary>
///
Use the Castle Windsor builder with the NoTrackingReleasePolicy.
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public static Configure CastleWindsor250Builder(this Configure config)
{
ConfigureCommon.With(config, new Windsor250ObjectBuilder());

return config;
}

/// <summary>
///
Use the Castle Windsor builder passing in a preconfigured container to be used by nServiceBus.
/// </summary>
/// <param name="config"></param>
/// <param name="container"></param>
/// <returns></returns>
public static Configure CastleWindsor250Builder(this Configure config, IWindsorContainer container)
{
ConfigureCommon.With(config, new Windsor250ObjectBuilder(container));

return config;
}
}
}


del.icio.us Tags: ,

Monday, 27 September 2010

Unit Testing: Selecting an Action from an MVC Controller

To fully test an MVC web site it is important to test (in isolation) the following:
  1. Behaviour of controller actions
  2. Behaviour of any custom action filters.
  3. The decoration of action filter attributes on controller actions.

To test the 3rd point, you must use reflection to select the desired action from the controller.  The following method takes an action name and a Tuple array of "Type" and "String". Used together this combination should be enough to isolate a desired action.  Note: an empty tuple array is used to define no input parameters, which a null tuple array specifies that this shouldn't be used to restrict the action (in this case the action name must be null)

  1. public MethodInfo SelectAction(Controller controller, string actionName, Tuple[] expectedParameters = null)
  2. {
  3.     var methods = controller.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(mi => mi.Name.Equals(actionName));
  4.     if (expectedParameters != null) methods = methods.Where(mi => CompareParameters(mi.GetParameters(), expectedParameters));
  5.     if (methods.Count() == 1) return methods.First();
  6.     var ex = new Exception((methods.Count() == 0) ? "No matching actions could be found on controller" : "More than one matching action could be found on controller"); ex.Data.Add("Controller", controller.GetType()); ex.Data.Add("Action", actionName); if (expectedParameters != null)
  7.     {
  8.         var parameterList = new StringBuilder(); foreach (var expectedParameter in expectedParameters)
  9.         {
  10.             if (parameterList.Length > 0) parameterList.Append(", "); parameterList.AppendFormat("{0} {1}", expectedParameter.Item1.Name, expectedParameter.Item2);
  11.         } ex.Data.Add("ParameterList", string.Format("({0}", parameterList.ToString()));
  12.     } ex.Data.Add("Matching Actions", methods.Count()); throw ex;
  13. }

This can then be called using the simple format below.  This code confirms that the controller has two search actions.  One taking no input parameters, whilst the other takes a bound input model.

  1. public MethodInfo SelectAction(Controller controller, string actionName, Tuple[] expectedParameters = null)
  2. {
  3.     MethodInfo action = null;
  4.     Assert.DoesNotThrow(() => action = SelectAction(new CustomerController((new MockHttpContext()).Object), "Search", new Tuple[] { }));
  5.     Assert.That(action.Name, Is.EqualTo("Search"));
  6.  
  7.  
  8.     Assert.DoesNotThrow(() => action = SelectAction(new CustomerController((new MockHttpContext()).Object), "Search", new[] { new Tuple(typeof(CustomerSearchInputModel), "inputModel") }));
  9.     Assert.That(action.Name, Is.EqualTo("Search"));
  10. }

In the next post I will cover how to use this to assert the decoration of action filter attributes.

del.icio.us Tags: ,

Sunday, 26 September 2010

Injecting AutoMapper with IoC

Update - 14th February 2016:
Looking in my blog stats, this continues to be one of my most popular articles, so it is most definitely worth an update. As of v4.2.0 Automapper has been updated to remove the static implementation. I've not had chance to play with the new version yet but I would imagine this version will now work with any IoC container you wish to use it with.


Original Article:
The main “Mapper” class of the AutoMapper framework is a static class which does make the initial testing and usage really easy but quickly causes problems if you’re using an Inversion of Control framework such as a Castle Windsor.  Also being static it is far harder to abstract the AutoMapper framework out of any unit tests using mocking frame such as MOQ.  As a final point for all these reasons using AutoMapper directly could cause problems in the future if it was decided to switch to another mapping framework.
The following code handles all of the above concerns / issues by wrapping the AutoMapper static instance up into a single bespoke mapping class.  At a first glance this would appear to be a step backwards as it requires each object to object mapping to be defined as a method in the interface and implementing class.   However for very little overhead or extra coding this comes with a benefit of abstracting the “how” of the mapping from the calling code.  It would be easy to add another mapping framework into the Mapper class below and then update individual methods to use that new mapping framework.  It also helps prevent any premature optimisations as the code can be deployed with new methods using mappings that provide the maximum automation and minimal manual configuration.  If performance issues then arise during testing or live usage, individual methods/mappings can be tackled to provide better performance – which for maximum throughput if the situation required it could result in the mapping framework(s) being by-passed completely and all initialisation of the target class performed directly within the mapping method.

using am = Automapper;

namespace Tools

{

public interface IMapper

{

CustomerEntity MapCustomer(CreateCustomerMsg msg);

CustomerEntity MapCustomer(UpdateCustomerMsg msg);
}


public class Mapper : IMapper

{

static Mapper()

{

// All creation code in the static constructor
am.Mapper.CreateMap<CreateCustomerMsg, CustomerEntity>();
am.Mapper.CreateMap<UpdateCustomerMsg, CustomerEntity> ();
}
public CustomerEntity MapCustomer(CreateCustomerMsg msg)
{
return am.Mapper.Map<CreateCustomerMsg,CustomerEntity>(msg);
}
public CustomerEntity MapCustomer(UpdateCustomerMsg msg);
{
return am.Mapper.Map<(UpdateCustomerMsg,CustomerEntity>(msg);
}
}
}




del.icio.us Tags: ,,

Playing with AutoMapper

In my current role we have come across a requirement to map message objects to more complex domain entities.  As anyone that has done this previously will quickly tell you, manually writing code to do this is very boring and repetitive.  With very limited time and resources, that effort could be better spent elsewhere on the project.  As it seemed very simple to set up and start using we’ve decided to use AutoMapper.

Configuring / Using
Setting up a basic mapper is as simple as:
Mapper.CreateMap<Source,Target>();
var target = Mapper.Map<Source,Target>(source);
The call to CreateMap only needs to be made once for the duration of the AppDomain, calls to Map are then made as needed.
As was as direct property name mapping several other more complex mappings are provided “out of the box”.  This includes flattening properties of child objects into named properties in the target object.   AutoMapper also provides several different methods to provide custom mappings either inline in the form:

Mapper.CreateMap<CalendarEvent, CalendarEventForm>()

.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.EventDate.Date))

.ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.EventDate.Hour))

.ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.EventDate.Minute));
Or using custom formatting classes in the form:


  1. Mapper.CreateMap<string, DateTime>().ConvertUsing(new DateTimeTypeConverter());
  2. public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
  3. {
  4.     public DateTime Convert(string source)
  5.     {
  6.         return System.Convert.ToDateTime(source);
  7.     }
  8. }


Performance
Initial tests have thrown up no surprises; the flexibility that Automapper provides does come with some overhead – but in most cases I’m sure that the performance is going to be fine for the project in question.  Being able to quickly map messages to domain objects and move on is going to improve the speed in which we can develop the project.  If problems are encountered once the code base is live, there is nothing to stop the areas in question being re-investigated and/or rolled back to manual mappings.


del.icio.us Tags:

Wednesday, 22 September 2010

Mocking HttpCookieCollection in HttpRequestBase

When unit testing ASP.NET MVC2 projects the issue of injecting HttpContext is quickly encountered.  There seem to be many different ways / recommendations for mocking HttpContextBase to improve the testability of controllers and their actions.  My investigations into that will probably be a separate blog post in the near future but for now I want to cover something that had me stuck for longer than it probably should have.  That is how to mock non abstract/interfaced classes within HttpRequestBase and HttpResponseBase – namely the HttpCookieCollection class.   The code sample below illustrates how it can be used within a mocked instance of HttpRequestBase.  Cookies can be added / modified within the unit test code prior to being passed into the code being tested.   After it’s been called, using a combination of MOQ’s Verify and NUnit’s Assert it is possible to check how many times the collection is accessed (but you have to include the set up calls) and that the relevant cookies have been added / set up.

 

MOQ / NUnit Code Sample
  1. namespace Tests
  2. {
  3.     using System.Web;
  4.     using Moq;
  5.     using NUnit.Framework;
  6.  
  7.     [TestFixture]
  8.     public class HttpRequestBaseTests
  9.     {
  10.         [Test]
  11.         public void Test()
  12.         {
  13.             var request = new Mock<HttpRequestBase>();
  14.             request.SetupGet(r => r.Cookies).Returns(new HttpCookieCollection());
  15.             request.Object.Cookies.Add(new HttpCookie("TestCookie", "TestValue"));
  16.             request.Object.Cookies.Add(new HttpCookie("AnotherCookie"));
  17.  
  18.             var instance = request.Object;
  19.             var cookie = instance.Cookies["TestCookie"];
  20.  
  21.             request.Verify(r => r.Cookies, Times.Exactly(3));  // Include the one expected reference, plus two setup calls.
  22.  
  23.             Assert.That(cookie, Is.Not.Null.And.InstanceOf(typeof(HttpCookie)));
  24.             Assert.That(cookie.Name, Is.Not.Null.And.InstanceOf(typeof(string)).And.EqualTo("TestCookie"));
  25.             Assert.That(cookie.Value, Is.Not.Null.And.InstanceOf(typeof(string)).And.EqualTo("TestValue"));
  26.         }
  27.     }
  28. }