Containers
NServiceBus is a container-agnostic framework.
While it comes with Spring merged into its core,
that is easily replaced by any other container.
With 4 other container technologies available out of the box
including Castle, StructureMap, Unity, and AutoFac
developers don't have to change to something new.
NServiceBus automatically registers all of its components
as well as user-implemented handlers and sagas so that
all instancing modes and wiring are done correctly
by default and without error.
Standard Container Usage
When hosting NServiceBus in your own process, you will see the following:
When using the generic host, the SpringBuilder is configured by default.
Other Containers Available
In the binary distribution of NServiceBus, you can find the other containers available under
/binaries/containers. You'll see a directory for each one - autofac, castle, structuremap, unity.
Each directory contains the binaries of the specific container as well as an additional assembly
which serves as the adapter which connects it to NServiceBus. This assembly is called
NServiceBus.ObjectBuilder.SpecificContainerName.dll. If you want to use one of these containers,
you'll need to add a reference to the relevant adapter assembly for the specific container.
Using a different container
In the PubSub sample you can see how a different container is used by looking at the Subscriber2 project.
In this project, the Castle container is used. Notice that references to all the Castle assemblies
have been added, as well as to the adapter assembly - NServiceBus.ObjectBuilder.CastleWindsor.dll.
One of the things illustrated by this sample is that different processes can use different containers.
While it is unlikely that a single team will want to use multiple containers within
a given solution, if multiple teams are working together each with its own preferred container,
NServiceBus does not require that all processes use the same container.
This is also useful when using NServiceBus to integrate with legacy code that may have been built
using an older or different container, or even when talking to an application that was designed without
a container.
After all the necessary references have been added, you'll see an additional extension method
become available on the NServiceBus.Configure class as shown below:
Using a different container with the host
When using the generic host that comes with NServiceBus, changing the container is very similar
to the process described above and is illustrated in the "Containers and Dependency Injection" section
of the generic host page here.
Plugging in your own container
In order to use a container other than the ones that come with NServiceBus you will need to implement
the IContainer interface in the NServiceBus.ObjectBuilder.Common namespace from the NServiceBus.Core dll.
public interface IContainer
{
object Build(Type typeToBuild);
IEnumerable<object> BuildAll(Type typeToBuild);
void Configure(Type component, ComponentCallModelEnum callModel);
void ConfigureProperty(Type component, string property, object value);
void RegisterSingleton(Type lookupType, object instance);
}
You may be wondering why this interface doesn't make use of generics. The reason is that for NServiceBus
to be used in a multi-threaded smart-client environment, the object that the bus uses to create
message handlers must inherit from System.ContextBoundObject and be decorated with the Synchronization
attribute found in System.Runtime.Remoting.Contexts. Classes which comply with these constraints
cannot make use of generics, and so cannot use these the generics-based API in the container.
In order to tell NServiceBus to use your container, you should create an extension method to the
NServiceBus.Configure class and pass an instance of your object as follows:
namespace NServiceBus
{
public static class YourExtensionMethodHolder
{
public static Configure NameOfYourContainer(this Configure config)
{
ConfigureCommon.With(config, new YourClassImplementingIContainer());
return config;
}
}
}
It is recommended to put this class in the NServiceBus namespace so that users of this container
won't need to add another 'using' directive in order for them to see the option of using your
container when intellisense shows them what's available after NServiceBus.Configure.With().
Next steps
You may be interested in seeing:
How NServiceBus facilitates unit-testing message handlers and sagas
or go back to the documentation table of contents