【问题标题】:Membus and Simple Injector - Wiring Command Handlers automatically by interfaceMembus 和 Simple Injector - 通过接口自动连接命令处理程序
【发布时间】:2013-04-13 23:16:17
【问题描述】:

我在 Membus 中看到了 IoC 功能,我尝试将其连接到 Simple Injector

IEnumerable<object> IocAdapter.GetAllInstances(Type desiredType)
{
var found = SimpleInjectorContainer.GetAllInstances(desiredType);
return found;
}

我的想法是,我将使用RegisterManyForOpenGeneric(typeof&lt;CommandHandler&lt;&gt;),typeof&lt;CommandHandler&lt;&gt;).Assembly) 自动注册我的所有类型。

毫无疑问,SimpleInjector 通常不允许多次注册 - 但是,我想这样做是为了让不同的处理程序实现命令处理的不同方面/问题。

public void MembusBootstrap()
{
    this.Bus = BusSetup.StartWith<Conservative>()
    .Apply <IoCSupport>(c =>
    {
        c.SetAdapter(SimpleInjectorWiring.Instance)
           .SetHandlerInterface(typeof(HandleCommand<>));
    })
    .Construct();
}

public void SimpleInjectorBootstrap()
{
    this.Container.Register<HandleCommand<AccountCreatedCommand>,
        SetupNewAccountCommandHandler();

    // next line will throw
    this.Container.Register<HandleCommand<AccountCreatedCommand>,
        LogNewAccountRequestToFile>();
}

当然,来自 membus 的 IEnumerable&lt;object&gt; IocAdapter.GetAllInstances(Type desiredType) 接口需要一个集合,因此可以调用多个处理程序。

将 Membus 与 SimpleInjector IoC 结合的最佳方式是什么?

脚注

我见过其他按惯例连接menbus的方法:

public interface YetAnotherHandler<in T> {
  void Handle(T msg);
}

public class CustomerHandling : YetAnotherHandler<CustomerCreated>
...

var b = BusSetup  
  .StartWith<Conservative>()  
  .Apply<FlexibleSubscribeAdapter>(c => c.ByInterface(typeof(YetAnotherHandler<>))  
  .Construct();

var d = bus.Subscribe(new CustomerHandling());  

但我真的很想坚持使用 IoC 容器来处理生命周期范围,并避免实例化命令处理程序并在需要它们之前手动连接它们。

【问题讨论】:

  • 作为附加信息,this blog post here(免责声明 - 我的网站)概述了这些天您如何将 MemBus 连接到 DI 容器。
  • 感谢您创建 membus 标签,我没有足够的法力来创建 :) 这让我想到了第二个有关 SetHandlerInterface 的相关问题stackoverflow.com/questions/16125285/…

标签: c# simple-injector message-bus membus


【解决方案1】:

您可以有多个注册。这是一个例子(抱歉,我的电脑今天死了,我正在记事本上写这个):

SimpleInjectorContainer.RegisterManyForOpenGeneric(typeof(CommandHandler<>),
    AccessibilityOption.PublicTypesOnly,
    (serviceType, implTypes) => container.RegisterAll(serviceType, implTypes),
    AppDomain.CurrentDomain.GetAssemblies()
);

它们可以通过以下方式检索:

public IEnumerable<CommandHandler<T>> GetHandlers<T>()
    where T : class
{
    return SimpleInjectorContainer.GetAllInstances<CommandHandler<T>>();
}

您会发现here 中描述的RegisterManyForOpenGenericGetAllInstances 方法的这些版本

我使用这种技术来支持发布/订阅框架。您可以拥有 n独立 CommandHandler's

【讨论】:

  • 请注意,这些实现在注册集合中的顺序是不确定的。如果顺序很重要,请将排序列表传递给 RegisterAll 方法。例如:implTypes.OrderBy(t =&gt; t.Name).
猜你喜欢
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 2018-11-10
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多