windsor mvc controller registration

This is the first in a series of posts illustrating custom Windsor registration that I outlined previously on this blog.

The first thing I want to do is revise my Windsor registration code and to pull the registration of the MVC controllers out into a static class and I begin by writing the following specification:

namespace Apollo.Infrastructure.Windsor 
{ 
    [Observations] 
    public class when_registering_mvc_controllers : observations_for_a_static_sut
    { 
        private static Assembly assembly; 
        private static IWindsorContainer container; 
        private static IController resolvedController; 

        private context c = () => 
            { 
                assembly = Assembly.GetAssembly(typeof(FakeController)); 
                container = new WindsorContainer(); 
            }; 

        private because b = () => 
            { 
                WindsorControllerRegistration.RegisterControllersFrom(assembly, container); 
                resolvedController = container.Resolve<IController>(typeof(FakeController)
                                              .FullName.ToLower()); 
            }; 

        [Observation] 
        public void should_be_able_to_resolve_a_known_controller_from_the_container() 
        { 
            resolvedController.should_not_be_null(); 
        } 
    } 

    public class FakeController : IController 
    { 
        public void Execute(RequestContext requestContext) 
        { 
            // do nothing 
        } 
    } 
}

In the context I am creating a new Windsor container and retrieving the assembly of a known type I want to resolve.
I then perform the action I am testing (in the because method) by registering the controllers and then resolving the controller. Finally I assert that the controller should not be null.

My first implementation of this is:

using System.Reflection; 
using System.Web.Mvc; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 

namespace Apollo.Infrastructure.Windsor 
{ 
    public static class WindsorControllerRegistration
    { 
       public static void RegisterControllersFrom(Assembly assembly,IWindsorContainer container) 
       { 
           container.Register(Component.For<IController>()
                                   .ImplementedBy<FakeController>()
                                   .LifeStyle.Transient
                                   .Named(typeof(FakeController).FullName.ToLower()));
       } 
    } 
}

And I now add a second observation to drive registering all controllers from an assembly:

namespace Apollo.Infrastructure.Windsor 
{ 
    [Observations] 
    public class when_registering_mvc_controllers : observations_for_a_static_sut
    { 
        private static Assembly assembly; 
        private static IWindsorContainer container; 
        private static IController resolvedController; 
        private static IController resolvedController2; 

        private context c = () => 
            { 
                assembly = Assembly.GetAssembly(typeof(FakeController)); 
                container = new WindsorContainer(); 
            }; 

        private because b = () => 
            { 
                WindsorControllerRegistration.RegisterControllersFrom(assembly, container);  
                resolvedController = container.Resolve<IController>(typeof(FakeController)
                                              .FullName.ToLower()); 
                resolvedController2 = container.Resolve<IController>(typeof(FakeController2)
                                              .FullName.ToLower()); 
            }; 

        [Observation] 
        public void should_be_able_to_resolve_a_known_controller_from_the_container() 
        { 
            resolvedController.should_not_be_null(); 
        } 

        [Observation] 
        public void should_be_able_to_resolve_a_second_known_controller_from_the_container() 
        { 
            resolvedController2.should_not_be_null(); 
        } 
    } 

    public class FakeController : IController 
    { 
        public void Execute(RequestContext requestContext) 
        { 
            // do nothing 
        } 
    } 

    public class FakeController2 : IController 
    { 
        public void Execute(RequestContext requestContext) 
        { 
            //do nothing 
        } 
    } 
}

This drives the final implementation as follows:

using System.Reflection; 
using System.Web.Mvc; 
using Castle.MicroKernel.Registration; 
using Castle.Windsor; 

namespace Apollo.Infrastructure.Windsor 
{ 
    public static class WindsorControllerRegistration 
    { 
       public static void RegisterControllersFrom(Assembly assembly,IWindsorContainer container) 
       { 
           container.Register(AllTypes.FromAssembly(assembly) 
                                .BasedOn<IController>() 
                                .Configure(c => c.LifeStyle.Transient) 
                                .Configure(c => c.Named(c.Implementation.FullName.ToLower()))); 
       } 
    } 
}

I have now separated my controller registration into its own static class making the way for this to become part of an extensible registration framework in the future.

Posted at at 7:05 PM on Thursday, October 22, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: , ,

grow your own windsor registration

Recently I have been working on an ASP.NET MVC application that uses Castle WIndsor as the inversion of control container. As I am using dependency injection throughout the code base, it became evident that the growing number of registrations were polluting the MVC application class in the Application_Start() method. bonsai

Fixing this was relatively easy - a designated IocContainer or similar class could isolate all the registrations but this soon began to grow and was violating the open/closed principle - "(classes) should be open for extension, but closed for modification".
Each time I revisited this IocContainer class I was modifying it and adding more registrations. Was there a better way of doing this? How could I make this extensible?

I decided to roll my own Windsor registration framework into the application and I will aim to illustrate how this was achieved in a series of posts that show building it up with test driven development.
I started from scratch with the controller registration process and then moved onto the controller factory before beginning the framework itself.

I'll keep an index of all the Windsor Registration posts here:

  1. windsor controller registration
  2. implementing windsor controller registration
  3. windsor mvc controller factory
  4. revising the windsor mvc controller factory
  5. more windsor mvc controller factory
  6. adding to the windsor mvc controller factory
  7. finshing the windsor mvc controller factory
  8. implementing the windsor controller factory

Posted at at 8:12 AM on Tuesday, October 13, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,

production constants in tests

When is it acceptable to share constants between the production code and the test code you are writing when practicing test first development?

I hadn't really thought about this until I came across a piece of code I was writing that used constants shared between test code and production code - as I was writing them something didn't sit right and I was getting the familiar code smell feeling.
Let me present the scenario first - I have a command builder that will return a SqlCommand and my test first process is evaluating the state of the SqlCommand object that gets returned. My context specification code is illustrated below, although the names have been made generic::

public class when_building_a_command_object_for_writing_data 
               : observations_for_a_sut_without_a_contract<DataCommandBuilder> 
{ 
     protected static SqlCommand command; 
     private static Data data; 
private context c = () => data = new Data() {Contact = "contact1";};
private because b = () => command = sut.GetCommandWithParametersDerivedFrom(data); [Observation] public void should_have_contact_parameter_with_correct_value() { command.Parameters[CustomParameters.Contact].Value .should_be_equal_to(data.Contact); } [Observation] public void should_have_contact_parameter_of_correct_size() { command.Parameters[CustomParameters.Contact].Size .should_be_equal_to(CustomParameterSizeFor.Contact); } } public static class CustomParameters { public const string Contact = "DataContact"; (...) } public static class CustomParameterSizeFor { public static int Contact = 25; }

Part of the actual implementation code is as follows:

     command.Parameters.Add(new SqlParameter() 
                         { ParameterName = CustomParameters.Contact,
                           SqlDbType = SqlDbType.VarChar, 
                           Size = CustomParameterSizeFor.Contact, 
                           Value = data.Contact });

This snippet of code above is the result of test driven process using the specification illustrated above it amongst other specs.
Can you spot the problem?

What was of immediate concern to me was the way the Size specification shared the same constant as the production code Size assignment does. At the moment the value is specified as 25 and the tests pass so the code appears great at first glance.

Let's suppose a scenario though where sometime later a different developer wants to change the size of the AdditionalContacts parameter to 10 (which isn't shown and is just hypothetical) but due to distractions she actually modifies the contact constant by mistake:

public static class CustomParameterSizeFor 
{
     public static int Contact = 10; 
}

What happens now is that the production code for the contact parameter size changes at runtime, but because the specification points at the constant it is changed too and the tests still pass.
Because the two are so intrinsically linked the test will never fail.

But what of the other constant sitting in the code ("CustomParameters.Contact") that represents the parameter name? Is this incorrect also?
I don't think it is - it is an identifier that enables the test to work with the same parameter name as the production code does and this is perfectly acceptable... we are not asserting anything on this value just using it.

So my conclusion is that shared constants are fine for identifiers but not for assertion values - pretty obvious when you step back and think about it.

Posted at at 7:52 AM on Monday, October 5, 2009 by Posted by Justin Davies | 0 comments Links to this post   | Filed under: ,