c# - 结构图 ObjectFactory.GetAllInstances<IHandle<TEvent>>()

标签 c# structuremap domain-events

我在最近的项目中实现事件处理时遇到了困难。

我已验证 structuremap 正在正确扫描、组装和添加 EventHandlers

Scan(cfg =>
            {
               cfg.TheCallingAssembly();
                cfg.IncludeNamespace("ABC.EventHandler");
                cfg.ConnectImplementationsToTypesClosing(typeof(IHandle<>));

           });

 public class StructureMapEventDispatcher : IEventDispatcher
    {

        public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
        {

            foreach (var handler in ObjectFactory.GetAllInstances<IHandle<TEvent>>())
            {

                handler.Handle(eventToDispatch);

            }

        }

    }

之前我曾经从域中触发事件。类似 Dispatcher.RaiseEvent(new [domainEvent class](x,y,z)); 的东西

事件将被触发。我不得不更改我现在在集合中收集事件的设计

_domainEvents = new Collection<IDomainEvent>();

然后在我将域保存到存储库后提升它

 public static void Raise(ICollection<IDomainEvent> domainEvents)
        {
            foreach (var domainEvent in domainEvents)
            {
                DomainEventDispatcher.Raise(domainEvent);
            }

        }

但是现在

ObjectFactory.GetAllInstances<IHandle<TEvent>>()返回 0 个处理程序

如果我看

ObjectFactory.GetAllInstances<IHandle<DomainEventClass>>()它正确返回处理程序集合(目前我有 2 个,它显示 2 个计数)

...我假设这与类型 IDomainEvent 引发的事件有关而不是实际类型,这使得结构图很难解析它。

我该如何解决这个问题?

问候,

三月

--

编辑 1:

我确认 structuremap 容器包含从程序集扫描的所有事件处理程序。

编辑 2

我不知道如何让这个问题吸引更多的关注。我正在为实现所需结果的解决方案增加赏金。如果问题不清楚,请提问。

基本上我想要 ObjectFactory.GetAllInstances<IHandle<TEvent>>() 返回 TEvent 的处理程序其中 TEvent类型为 IDomainEvent .要引发的事件存储在 IDomainEvent 的集合中并在域被保存(从服务层)之后引发。

我认为应该有一些方法可以让 structuremap 知道引发的事件为 IDomainEvent实际上是类型 DomainEvent

var eventsToRaise= dealer.EventsToRaise(); 从调试窗口添加信息:

在调度程序窗口中引发事件之后

enter image description here

编辑 3: 尽管 eventToRaise 显示为“DealerName Changed”和“DealerCommunicationChanged”
typeof(TEvent) 给出 Type 作为 Domain.IDomainEvent

我猜想如果能够转换为正确的类型(从 VS 监 window 口获取信息的任何地方),问题就可以得到解决

----- 结果---

这两种方法都奏效了。我将这两个方法都交给了我团队中的其他 2 名成员,我们认为没有经过深思熟虑的解决方案被选为正确答案。

今天我们将对更改后的实现进行测试,看看解决方案中是否存在此解决方案的问题。

我赞成基于反射的解决方案,因为它也是正确的答案。


最佳答案

如您所说,问题是您要为 IHandle<IDomainEvent> 的所有实例询问结构图它没有这些,structuremap 有具体事件的处理程序。您需要使用事件的实际类型构造类型,然后请求该事件的所有处理程序:

        Type genericHandler = typeof(IHandle<>);
        Type[] typeArgs = { eventToDispatch.GetType() };
        Type neededHandler = genericHandler.MakeGenericType(typeArgs);
        var handlers = ObjectFactory.GetAllInstances(neededHandler);

问题是你最终得到一个对象的 IList,你需要将它们转换为正确的处理程序类型,这有点棘手......一个可能的解决方案是使用反射来调用 Handle()方法:

        var methodInfo = neededHandler.GetMethod("Handle");
        object[] methodArgs = new object[] { eventToDispatch };
        foreach (var h in handlers)
        {
            methodInfo.Invoke(h, methodArgs);
        }

关于c# - 结构图 ObjectFactory.GetAllInstances<IHandle<TEvent>>(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6104058/

相关文章:

c# - 如何将 IList 复制到相同类型的 IList?

c# - ASP.Net 核心 : How do I update (change/add/remove) nested item objects (One-to-Many relationship)?

c# - 用工作单元装饰特定的命令处理程序

asp.net-mvc - StructureMap-MVC3 中 scan.TheCallingAssembly、scan.WithDefaultConventions 的用途

dependency-injection - 如何从域对象内分派(dispatch)域事件?

domain-driven-design - 领域驱动设计 : how to model nested product category hierarchy? 更糟糕的是,如果产品类别是聚合根怎么办?

domain-driven-design - 加载聚合对域事件的 react

c# - 在 C# wpf 中的 slider 上添加直方图

c# - StructureMap - 如何注册和解析开放泛型类型

StructureMap AlwaysUnique 似乎不适用于构造函数注入(inject)