NServiceBus 处理程序设置与 Castle Windsor 的命名依赖关系

NServiceBus handler set named dependency with Castle Windsor

对于 NServiceBus 处理程序,我想指定一个命名依赖项。我正在使用 castle windsor 作为我的 IOC 容器。默认情况下,NServiceBus 会向容器注册所有处理程序,因此当我尝试同时设置注册时,它会在启动时抛出错误……

"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."。

有没有办法覆盖它以指定命名依赖项。所以有这样的注册...

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")));

对于看起来像这样的处理程序....

public class EventMessageHandler : IHandleMessages<EventMessage>
{
    private IService service;

public EventMessageHandler(IService service)
{
    this.service = service;
}

public void Handle(EventMessage message)
{
    service.DoStuff();
}
}

这是因为我有 IService 的多个实现,所以希望能够为特定的处理程序指定特定的实现。

可以通过创建容器、预先注册所有内容然后将其移交给 BusConfiguration 来实现(假设您使用的是 NSB v5.0 或更高版本)。

代码如下:

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));

现在在您的处理程序上,如果您依赖于您的服务,它将是您指定的那个:

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");
    }
}

需要注意的一点是,您必须完全按照上面所示进行注册。如果您尝试这样做,它会爆炸:

//Wouldn't work
container.Register(Component.For<IHandleMessages<MyMessage>>().ImplementedBy<MyMessageHandler>().DependsOn(Dependency.OnComponent(typeof(IMyService), "s2")));

说了这么多,为什么注入实际的 class 而不是接口来实现同样的事情是不好的?