structuremap ObjectFactory.GetAllInstances <IHandle <TEvent >>()

The*_*Mar 5 c# structuremap domain-events

我正忙着在最近的一个项目中实现事件.

我已经验证了structuremap正在扫描正确的汇编和添加EventHandler

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

            }

        }

    }
Run Code Online (Sandbox Code Playgroud)

之前我曾经从域中触发事件.有点像Dispatcher.RaiseEvent(new [domainEvent class](x,y,z));

而事件将被激起.我不得不改变设计,我现在收集集合中的collectiong事件

_domainEvents = new Collection<IDomainEvent>();
Run Code Online (Sandbox Code Playgroud)

我将域保存到存储库后再将其提升

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

        }
Run Code Online (Sandbox Code Playgroud)

但现在

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

如果我注意的话

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

...我假设这与事件被提出类型IDomainEvent 而不是实际类型有关,这使得结构图很难解决它.

我该如何解决这个问题?

问候,

三月

-

编辑1:

我已经确定struturemap容器包含从程序集扫描的所有事件处理程序.

编辑2

我不知道如何让这个问题引起更多关注.我正在为获得所需结果的解决方案添加赏金.如果问题不明确,请询问.

基本上我想ObjectFactory.GetAllInstances<IHandle<TEvent>>()返回处理程序TEvent,其中TEvent的类型的IDomainEvent.要保存的事件(存储在IDomainEvent服务层之后)存储在Collection of 和raise中.

我认为应该有一些方法可以让结构图知道事件被提升为IDomainEvent实际上是TypeDomainEvent

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

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

在此输入图像描述

编辑3:尽管eventToRaise显示为"DealerName Changed"和"DealerCommunicationChanged"
typeof(TEvent)将Type设为Domain.IDomainEvent

我猜是否有可能转换为正确的类型(从VS观察窗口获取信息)问题可以得到解决

-----结果---

两种方法都有效.我把两个接近我的团队中的其他两个成员,我们觉得没有反思的解决方案被选为正确的答案.

今天我们将通过改变实施进行测试,看看解决方案中是否存在此解决方案的任何问题.

我推荐了基于反射的解决方案,因为它也是正确的答案.


def*_*mer 1

我建议您使用记录来保存类型信息,而不是基于反射的方法。像这样的东西:

interface IEventRecord
{
    void Dispatch(IEventDispatcher dispatcher);
}

public class EventRecord<TEvent> : IEventRecord where TEvent : IDomainEvent
{
    TEvent theEvent;

    public EventRecord(TEvent theEvent)
    {
        this.theEvent = theEvent;
    }

    public void Dispatch(IEventDispatcher dispatcher)
    {
        dispatcher.Dispatch(theEvent);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您发现实例化事件记录很麻烦,则帮助程序可以像这样推断类型参数:

public static EventRecord<TEvent> CreateEventRecord<TEvent>(TEvent theEvent) where TEvent : IDomainEvent
{
    return new EventRecord<TEvent>(theEvent);
}
Run Code Online (Sandbox Code Playgroud)

这将允许您实例化事件记录,如下所示:

var record = CreateEventRecord(myDomainEvent);
Run Code Online (Sandbox Code Playgroud)

然后,不要持有IDomainEvents 的集合,而是持有IEventRecords包含必要类型数据的集合来提升自身:

foreach (var eventRecord in Records)
{
    eventRecord.Dispatch(myDispatcher);
}
Run Code Online (Sandbox Code Playgroud)