【问题标题】:NServiceBus handler set named dependency with Castle WindsorNServiceBus 处理程序使用 Castle Windsor 设置命名依赖项
【发布时间】:2015-08-31 15:04:03
【问题描述】:

对于 NServiceBus 处理程序,我想指定一个命名依赖项。我正在使用城堡温莎作为我的 IOC 容器。默认情况下,NServiceBus 将所有处理程序注册到容器中,因此当我尝试设置注册时,它会在启动时引发错误.....

“无法注册组件 EventMessageHandler。已经有一个具有该名称的组件。您是否要修改现有组件?如果不是,请确保指定一个唯一名称。”。

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

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 实现,因此希望能够为特定的处理程序指定特定的实现。

【问题讨论】:

    标签: dependency-injection castle-windsor nservicebus


    【解决方案1】:

    可以通过创建一个容器、预先注册所有内容然后将其交给 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")));
    

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

    【讨论】:

    • 如何将容器和 busConfiguration 连接在一起?
    • 感谢您的回复。我错的是处理程序的注册。 container.Register(Component.For().DependsOn(Dependency.OnComponent(typeof(IMyService), "s1")));正确,而 container.Register(Component.For>().ImplementedBy().DependsOn(Dependency.OnComponent(typeof(IMyService), "s2")));正在爆炸。不知道你的意思是“为什么注入实际的类而不是接口来实现同样的事情是不好的?”.....给出的例子是我实际代码的简化版本。
    • @JohnG 很高兴它已解决。我的意思是,如果您有两个不同的服务/接口实现,并且一个处理程序特别需要一个实现来操作,为什么不注入该具体类(而不是接口)并使依赖关系更“明显”而不是隐藏该依赖关系在使用命名依赖项的 IoC 容器配置中?
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多