我在最近的项目中很难实现事件。
我已经验证了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/