Archive

Archive for the ‘Castle Windsor’ Category

Managing and Testing Component Registrations with Castle Windsor

September 11, 2009 2 comments

This post is an extension of an earlier post on testing container registrations.  In this post I cover testing again as well as how I manage component registrations to reduce the amount of xml needed and how I automate component registration as much as possible.

First up, the scenario within which I am using a container:

  • ASP.NET MVC application
  • controllers managed via the WindsorControllerFactory from MVCContrib.
  • actions have only 1 parameter and that type is an interface – the container manages the parameter types via a custom model binder.
  • Parameters are 1 of 3 types:
    1. Commands – do something to the domain and return a result that cannot cause side-effects ( ideally immutable but you cannot use structs in views ).
    2. Queries – retrieve data from the system and pack it into a return type that is effectively a view model.
    3. UrlActions – some actions need both commands and queries and must share request state ( form data, query parameters or route parameters ) so until I use special classes that combine commands and queries for this.
  • A custom validation approach that is similar to FluentValidation
  • NHibernate + NHibernateIntegrationFacility + FluentNHibernate

Semi-automatic Component Registration

Using base or marker interfaces allows you to define a few bulk registrations, rather than a large number of fine-grained registrations.  The design of the application outlined above provides four places where I usually add features into the sytem.  Each one of these extension points is identified by a base interface, this makes it easier to find and automatically register the associated components.  The extension points are:

  • Commands – ICommand<T>
  • Queries – IQuery<T>
  • UrlActions – IUrlAction
  • Validators – IValidator<T>

To add a feature ( e.g. logon ), I usually implement a query, a command and two validators.  All of these components are covered by bulk registrations, therefore I don’t have to “remember” to register them in the container before using them – it happens automatically.

public static class ComponentRegistrations
    {
        public static readonly Assembly CommandsAssembly = typeof( RegistrationCommand ).Assembly;

        public static readonly IRegistration Commands =
            AllTypes.Of( typeof( ICommand<> ) )
                .FromAssembly( CommandsAssembly )
                .WithService.Select((t, b) => new List<Type> {t.FindMostSpecificChildInterfaceOf( b )} )
                .Unless( t => t.IsAbstract || t.IsInterface )
                .Configure( c => c.LifeStyle.Transient );
    }

Simple Component Registration Testing

Placing all of the registrations in a class like ComponentRegistrations greatly simplifies unit testing. I use a helper class that converts the single registration defined by AllTypes.Of(...) into individual registrations.

When testing registrations, you only need to test the “extra bits”.  In the above registration that equates to the .WithService.Select(...) bit.  The test looks like this:

    [Specification]
    public class When_registering_commands
    {
        private CompontentRegistrationsTestContext _context;

        public void Given(CompontentRegistrationsTestContext context)
        {
            _context = context;
        }

        public void When()
        {
            _context.WhenRegisteringWith( ComponentRegistrations.Commands );
        }

        [Then]
        public void the_service_should_be_defined_by_the_most_specific_interface_inheriting_from_ICommand()
        {
            _context.AllRegistrations(
                r => r.ServiceType.ShouldEqual(
                         r.Implementation.FindMostSpecificChildInterfaceOf( typeof(ICommand<>)) ) );
        }
    }

The context class that converts the registrations uses an IKernel stub to convert bulk registrations like BasedOnDescriptor into ComponentRegistration instances.

    public class CompontentRegistrationsTestContext
    {
        private List<ComponentRegistration> _registrations;

        public void WhenRegisteringWith( IRegistration registration )
        {
            _registrations = new List<ComponentRegistration>();

            var componentRegistration = registration as ComponentRegistration;
            if( componentRegistration != null )
            {
                // We want to capture the component registrations, not execute them
                _registrations.Add( componentRegistration );
                return;
            }

            // If they are not component registrations, they will be descriptors that
            // generate numerous registrations ( i.e. BasedOnDescriptor )
            var kernel = MockRepository.GenerateStub<IKernel>();
            kernel.Stub( stub => stub.Register( null ) )
                .IgnoreArguments()
                .Callback( new RegisterDelegate( CaptureRegistrations ) )
                .Return( kernel );

            registration.Register( kernel );
        }

        public void AllRegistrations( Action<ComponentRegistration> assertion )
        {
            _registrations.Do( assertion );
        }

        public bool ContainsRegistration( Func<ComponentRegistration, bool> matchCriteria )
        {
            return _registrations.Any( matchCriteria );
        }

        private delegate bool RegisterDelegate(IRegistration[] registrations);
        private bool CaptureRegistrations(IRegistration[] registrations)
        {
            _registrations.AddRange(registrations
                .Select(r => (ComponentRegistration)r));
            return true;
        }
    }

Simplify Complex Component Registrations

Where I need more complex registrations that need to work with the configuration, I write a custom IRegistration implementation. The following example registers a component to intercept and redirect emails being sent from the website.  Usign a custom registration means that I can add all of the configuration required by components to the facility configuration in the simplest possible form, yet still use parameters for configuring components.

    public class RedirectingEmailSenderRegistration : IRegistration
    {
        public const string RedirectingEmailSenderKey = "redirecting.emailsender";
        public const string RedirectConfigurationChildKey = "redirectEmails";
        public const string RedirectConfigurationToAddressKey = "to";
        public const string RedirectConfigurationSkipSendingKey = "skipSending";

        private readonly IConfiguration _configuration;

        public RedirectingEmailSenderRegistration( IConfiguration facilityConfiguration )
        {
            _configuration = facilityConfiguration.Children[RedirectConfigurationChildKey];
        }

        public void Register(IKernel kernel)
        {
            kernel.ConfigurationStore.AddComponentConfiguration(
                RedirectingEmailSenderKey,
                BuildRedirectingEmailSenderConfiguration() );
            kernel.AddComponent(
                RedirectingEmailSenderKey,
                typeof( IEmailSender ),
                typeof( RedirectingEmailSender ),
                LifestyleType.Singleton );
        }

        private IConfiguration BuildRedirectingEmailSenderConfiguration()
        {
            if( _configuration == null )
            {
                throw new ConfigurationErrorsException(
                    "Missing configuration for the redirecting email sender.  Please ensure the following element is present and correct: <redirectEmails to=\"redirect address here\" />" );
            }
            var redirectAddress = _configuration.Attributes[ RedirectConfigurationToAddressKey ];
            if( String.IsNullOrEmpty( redirectAddress ) )
            {
                throw new ConfigurationErrorsException(
                    "Missing configuration for the redirecting email address sender.  Please ensure the to attribute is populated with a valid email address" );
            }
            var skipSending = _configuration.Attributes[ RedirectConfigurationSkipSendingKey ];
            if( String.IsNullOrEmpty( skipSending ))
            {
                skipSending = Boolean.FalseString;
            }
            var configuration = new MutableConfiguration( "component" );
            configuration.Attribute( "id", RedirectingEmailSenderKey )
                .CreateChild( "parameters" )
                .AddChild( "redirectTo", redirectAddress )
                .AddChild( "skipSending", skipSending );

            return configuration;
        }
    }

An additional benefit of this is that you can inspect the result of the registration to ensure it works the way you expect it to.

    [Specification]
    public class When_registering_the_redirecting_email_sender
    {
        private RedirectingEmailSenderRegistration _registration;
        private IKernel _kernel;
        private IConfigurationStore _configurationStore;

        public void Given(DevelopmentContainerConfigurationContext context)
        {
            _registration = new RedirectingEmailSenderRegistration( context.BuildFacilityConfiguration() );

            _kernel = MockRepository.GenerateStub<IKernel>();
            _configurationStore = MockRepository.GenerateStub<IConfigurationStore>();

            _kernel.ConfigurationStore = _configurationStore;
        }

        public void When()
        {
            _registration.Register(_kernel);
        }

        [Then]
        public void the_redirecting_email_sender_is_configured()
        {
            _configurationStore.AssertWasCalled(
                cs => cs.AddComponentConfiguration( null, null ),
                c => c.IgnoreArguments()
                         .Constraints(
                         Is.Equal( RedirectingEmailSenderRegistration.RedirectingEmailSenderKey ),
                         Is.Anything() ) );
        }

        [Then]
        public void the_redirecting_email_sender_is_registered()
        {
            _kernel.AssertWasCalled(
                k => k.AddComponent(
                         RedirectingEmailSenderRegistration.RedirectingEmailSenderKey,
                         typeof( IEmailSender ),
                         typeof( RedirectingEmailSender ),
                         LifestyleType.Singleton) );
        }
    }

Simplify Management of Component Registrations

Generally when I am developing a web application, I have two sets of components that I need to manage, one set for production – the components that make up the actual application, and a second set for development that perform tasks like redirecting the email from the application into a specific email address.

Rather than having to remember which components belong to what set, I create two facilities to register the components, the first is <ApplicationName>ConfigurationFacility and the second is DevelopmentConfigurationFacility. Because all the registrations can be accessed via static members of the ComponentRegistrations class I can create a simple facility as shown below.  This means it is easy to see what components are being registered in the container and in what order ( you can also register facilities in the same way ):

    public class DevelopmentConfigurationFacility : AbstractFacility
    {
        protected override void Init()
        {
            Kernel.Register( DevelopmentComponentRegistrations.DatabaseController );
            Kernel.Register( DevelopmentComponentRegistrations.RedirectingEmailSender( FacilityConfig ) );
            Kernel.Register( DevelopmentComponentRegistrations.NHibernateProfilerInitialisingConfigurationBuilder );
            Kernel.Register( DevelopmentComponentRegistrations.EnableStatisticsPersistenceConfigurer );
            Kernel.Register( DevelopmentComponentRegistrations.ShowSqlPersistenceConfigurer );
        }
    }

By using facilities to group component registrations, I can effectively “bootstrap” the container into one of two modes ( development or production ) by adding or removing one facility registration ( instead of 5 component registrations + the associated component configuration ).

Careful thought about the strategies you use to manage and test your component registrations may cost you some time up front, but it is time well invested as once it is up and running, you should end up with a zero-friction environment wrt components.

If it just works and you don’t notice when it does – you’ve done it right

Testing Windsor component registrations

July 16, 2009 Leave a comment

Having previously used Windsor on other projects and experienced the pain of debugging incomplete or invalid component registration via YSOD, I decided to be a little more proactive in my approach to container configuration on my current project.  This time round I have a suite of tests that (hopefully) cover all of the components that should be registered, and already these tests have exposed one problem that has arisen due to my ignorance around the NHibernate Facility.

In general, testing component registrations is as simple as resolving all of the types for a given service and ensuring the count matches some value you have determined via other means, like so:

        [Then]
        public void all_of_the_controllers_in_the_assembly_should_be_registered()
        {
            var controllerAssembly = typeof( RegistrationController ).Assembly;
            var controllerCount =
                controllerAssembly.GetExportedTypes()
                    .Where( t => t.IsSubclassOf( typeof( Controller ) ) && !t.IsAbstract )
                    .Count();
            var registeredControllerCount = _container.ResolveAll<Controller>().Length;
            registeredControllerCount.ShouldEqual( controllerCount );
        }

(_container is an IWindsorContainer instance and the [Then] attribute is from my customised xUnit BDD implementation)

The problem occurs when you try to use the same approach with open generic types such as IValidator<> – ResolveAll returns and array and you can’t create an array of open generic types. To get around this you need to retrieve the collection of handlers for the components rather than the components themselves (this is based on the assumption that a handler is generated for every registration – which I cannot disprove so I will go with it for now).

Using this approach, I can ensure the registration of all my IValidator<> instances with the following:

        [Then]
        public void all_of_the_validators_in_the_assembly_should_be_registered()
        {
            var validatorAssembly = typeof( RegistrationCommandValidator ).Assembly;
            var validatorCount =
                validatorAssembly.GetExportedTypes()
                    .Where( t => t.IsSubclassOf( typeof( IValidator<> ) ) && !t.IsAbstract && !t.IsInterface )
                    .Count();
            // Can't use ResolveAll as there is no way to create an array of an open type
            var registeredValidatorCount = _container.Kernel.GetHandlers( typeof( IValidator<> ) ).Length;
            registeredValidatorCount.ShouldEqual( validatorCount );
        }

The only difference to the first test is the call to _container.Kernel.GetHandlers( ... ) instead of _container.ResolveAll<...>().

Windsor and NLog – Getting the Exception StackTrace

February 15, 2008 Leave a comment

Someone queried the NZ.NET mailing list yesterday about how to get the stack trace out of an exception logged via the NLog logging facility.

Having a quick look at the docs for layout renderers seemed to indicate that the ${exception} layout renderer, however by all accounts that wasn’t working so I’ve thrown together a couple of quick tests and a MonoRail site with Windsor integration enabled demonstrate how to achieve it and make sure it works. You can get the demo from the link below – it is a rar file but as WordPress won’t let me upload rar files, so I have changed the extension to .png. You will need to download it to your machine and change the file extension back to .rar to access the content.

Logging with NLog via Windsor

For those of you who just want to know what the configuration looks like:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <targets>
            <target name="debugconsole" xsi:type="Console" layout="${message}"/>
            <target name="errorconsole" xsi:type="Console" layout="${message} [br] Details:${exception:format=type,message,stacktrace:separator=[br]}"/>
        </targets>
        <rules>
            <logger name="*" level="Debug" writeTo="debugconsole"/>
            <logger name="*" level="Error" writeTo="errorconsole"/>
        </rules>
    </nlog>
</configuration>

The targets are both console targets because I temporarily redirect Console.Out to a StringWriter so that I can capture and display the logged data.

Be aware that this demo is built against a copy of the Castle trunk from mid January (all referenced assemblies are included in the download), if you are not seeing the same behaviours in your code, it may be due to differences (or an issue) in the version you are using.

Categories: Castle Windsor, MonoRail, NLog
Follow

Get every new post delivered to your Inbox.