我在最近的项目中很难实现事件。

我已经验证了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);

            }

        }

    }

在我以前从Domain触发Event之前。像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类型而不是实际类型引发的事件有关,这使Structuremap很难解决它。

我该如何解决这个问题?

问候,

马尔

--

编辑1:

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

编辑2

我不知道如何使这个问题引起更多关注。我为寻求实现所需结果的解决方案添加了赏金。如果问题不清楚,请询问。

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

我想应该有一些方法可以使Structuremap知道IDomainEvent引发的事件实际上是类型DomainEvent

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

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

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

我猜想是否有可能将类型转换为正确的类型(无论从VS监视窗口获取信息的地方),问题都可以得到解决

- - - 结果 - -

两种方法都有效。我将这两种方法都联系了我团队中的其他两名成员,我们认为没有反射(reflection)的解决方案将被选为正确的答案。

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

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

最佳答案

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

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

如果发现实例化一个事件记录很麻烦,则助手可以像这样推断出type参数:
public static EventRecord<TEvent> CreateEventRecord<TEvent>(TEvent theEvent) where TEvent : IDomainEvent
{
    return new EventRecord<TEvent>(theEvent);
}

这样可以实例化事件记录,如下所示:
var record = CreateEventRecord(myDomainEvent);

然后,不保留IDomainEvent的集合,而保留IEventRecords的集合,该集合包含必要的类型数据以提高自身:
foreach (var eventRecord in Records)
{
    eventRecord.Dispatch(myDispatcher);
}

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

10-11 20:21