Designing applications that can easily be reconfigured for the different stages in the development lifecycle is important when it comes to shorten the time between development and production. To achieve this we need ways to easily change our applications behavior as it moves through the various stages of software development. Having frameworks that help in this is of course a great start but it’s ultimately up to you as a developer to design and code your application to be lifecycle aware. Udi Dahan has a nice post on the subject that also describes how NServiceBus tries to help in this matter.

Enough talk let’s see an example on how we can combine NServiceBus and StructureMap to create easily reconfigurable applications.

Lifecycle awareness NServiceBus style

In my last post I explained how we could send emails in a “transactional” way using NServiceBus. The solution boiled down to a simple message handler that sends emails through it’s IEmailGateway dependency. Let’s see how we hook up to the built-in profiles of NServiceBus and configure our own dependencies accordingly.

The message handler was implemented as follows:

public class SendEmailMessageHandler : IMessageHandler< SendEmailRequest >{    private readonly IEmailGateway emailGateway;

    public SendEmailMessageHandler(IEmailGateway emailGateway)    {        this.emailGateway = emailGateway;    }

    public void Handle(SendEmailRequest message)    {        emailGateway.SendEmail(message.ToAdress,                               message.Subject,                               message.Body);    }}

To ease our integration testing we decide to swap out the implementation of IEmailGateway to something that just logs the request to a folder on disk so that we can verify the results either automatically or using our testers.  To do this we configure our endpoint as follows:

public class EndpointConfigWithAwareness : IConfigureThisEndpoint,                                    As.aServer,                                    IDontWant.Sagas,                                    ISpecify.ToRun< DemoEndpoint >,                                    IWantCustomInitialization,                                    IHandleProfile< Integration >{    private static bool IsInProductionMode = true;

    public void Init(Configure configure)    {        if (IsInProductionMode)            configure.Configurer.ConfigureComponent< SmtpGateway >(ComponentCallModelEnum.Singlecall);        else            configure.Configurer.ConfigureComponent< FileLoggingOnlyEmailGateway >(ComponentCallModelEnum.Singlecall);    }

    public void Init(IConfigureThisEndpoint specifier)    {        IsInProductionMode = false;    }}

As you can see we implement IHandleProfile<Integration> and uses the call to Init(…) to adjust the mode variable. With this in place we can easily configure the IEmailGateway dependency accordingly. So now when we start the NServiceBus in integration mode , NServiceBus.Host.exe /integration, our emails will be logged to disk instead of being sent to the real SMTP-server.

Lifecycle awareness vNext

As you can imagine this solution gets kind of ugly when you have more dependencies and more profiles.  As a nice “coincidence” my container of choice, StructureMap, also has the concept of profiles. Please read Chad Myers post for an in-depth explanation. Let’s modify our configuration to combine the both:

public class EndpointConfigUsingStructuremap : IConfigureThisEndpoint,                                   As.aServer,                                   ISpecify.ContainerTypeToUse< StructureMapObjectBuilder >,                                   IDontWant.Sagas,                                   ISpecify.ToRun< DemoEndpoint >,                                   IHandleProfile< Integration >{    private static readonly string IntegrationProfile = typeof (Integration).Name;

    public  EndpointConfigUsingStructuremap()    {        ObjectFactory.Configure(x =>                                    {                                        x.ForRequestedType< IEmailGateway>()                                            .TheDefaultIsConcreteType< SmtpGateway >();

                                        //setup the alterations for the integration profile                                        x.CreateProfile(IntegrationProfile)                                            .For< IEmailgateway >()                                                .UseConcreteType< FileLoggingEmailGateway >();                                    });    }

    public void Init(IConfigureThisEndpoint specifier)    {        //switch profile to "integration"        ObjectFactory.Profile = IntegrationProfile;        }}

The code above starts with configuring NServiceBus to use StructureMap as the container. Then we move on to configure all our components using the StructureMap API. Using “CreateProfile” we creates a “Integration” profile where we configure the special version of IEmailGateway to use when running in that profile. With all this setup it’s straight forward to use the NServiceBus profile to activate the correct StructureMap profile.

Conclusion

Building software that is easily configurable for different purposes is becoming increasingly important to enable rapid development and tight release cycles. To succeed make sure to pick frameworks that enables you to be lifecycle aware but in the end it’s up to you to “connect the dots”.

The source code an a fully working sample of all this can be found here.