For an NServiceBus handler I want to specify a named dependency. I am using castle windsor as my IOC container. By default NServiceBus registers all handlers with the container so when I try to also set registrations it throws an error on startup.....
"Component EventMessageHandler could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.".
Is there a way to override this to specify the named dependency. So have a registration like this...
container.Register(
Component.For<IService>()
.ImplementedBy<Service>()
.Named("default")
.DependsOn(Dependency.OnValue<Config>(config1)));
container.Register(
Component.For<IHandleMessages<EventMessage>>().ImplementedBy<EventMessageHandler>()
.DependsOn(Dependency.OnComponent(typeof(IService), "default")));
For a handler that looks like this....
public class EventMessageHandler : IHandleMessages<EventMessage>
{
private IService service;
public EventMessageHandler(IService service)
{
this.service = service;
}
public void Handle(EventMessage message)
{
service.DoStuff();
}
}
This is because I have multiple implementations of the IService so want to be able to specify specific ones for specific handlers.
It is possible to do it by creating a container, preregister everything and then hand it over to the BusConfiguration (assuming you're on NSB v5.0 or greater).
Here's the code:
BusConfiguration busConfiguration = new BusConfiguration();
WindsorContainer container = new WindsorContainer();
container.Register(Component.For<IMyService>().ImplementedBy<MyServiceImpl1>().Named("s1"));
container.Register(Component.For<IMyService>().ImplementedBy<MyServiceImpl2>().Named("s2"));
container.Register(Component.For<MyMessageHandler>().DependsOn(Dependency.OnComponent(typeof(IMyService), "s1")));
busConfiguration.UseContainer<WindsorBuilder>(c => c.ExistingContainer(container));
Now on your handler, if you have a dependency to your service, it will be the one you've specified:
public class MyMessageHandler : IHandleMessages<MyMessage>
{
public MyMessageHandler(IMyService service)
{
//service is of the type you specified in your config
}
public void Handle(MyMessage message)
{
Console.WriteLine("Message arrived");
}
}
One thing to note, you'd have to do your registration exactly as shown above. If you try to do it this way it will blow up:
//Wouldn't work
container.Register(Component.For<IHandleMessages<MyMessage>>().ImplementedBy<MyMessageHandler>().DependsOn(Dependency.OnComponent(typeof(IMyService), "s2")));
Having said all that, why is it bad to inject the actual class and not the interface to achieve the same thing?