结构图ObjectFactory.GetAllInstances >()

|| 我在最近的项目中很难实施事件。 我已经验证了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之前。像ѭ1这样的东西 该事件将被触发。我必须更改现在要收集的事件的设计
_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个计数) ...我认为这与引发类型为ѭ6as而不是实际类型的事件有关,这使Structuremap很难解决它。 我该如何解决这个问题? 问候, 马尔 - 编辑1: 我已经确认struturemap容器包含从程序集扫描的所有事件处理程序。 编辑2 我不知道如何使这个问题引起更多关注。我要提供赏金以寻求实现所需结果的解决方案。如果问题不清楚,请询问。 基本上,我希望
ObjectFactory.GetAllInstances<IHandle<TEvent>>()
返回
TEvent
的处理程序,其中
TEvent
IDomainEvent
类型。将要引发的事件存储在“ 6”的集合中,并在域被保存之后(从服务层)被引发。 我想应该有一些方法可以使结构图知道as6ѭ引发的事件实际上是
DomainEvent
类型的事件 var eventsToRaise = Dealer.EventsToRaise(); 从调试窗口添加信息: 在调度程序窗口中引发事件之后 编辑3: 即使eventToRaise显示为\“ DealerName Changed \”和\“ DealerCommunicationChanged \” typeof(TEvent)给出Type作为Domain.IDomainEvent 我猜想是否有可能将类型转换为正确的类型(无论从VS监视窗口获取信息的地方),问题都可以得到解决 -----结果--- 两种方法都有效。我将这两种方法都联系了我团队中的其他两名成员,我们认为没有反思的解决方案将被选为正确的答案。 今天,我们将对更改后的实现进行测试,以查看解决方案中此解决方案是否存在任何问题。 我赞成基于反射的解决方案,因为它也是正确的答案。     
已邀请:
我建议您使用一条记录来保留类型信息,而不是基于反射的方法。像这样:
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);
    }
}
如果您发现实例化事件记录很麻烦,则助手可以像这样推断类型参数:
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);
}
    
正如您所说,问题在于您要向结构图查询所有
IHandle<IDomainEvent>
实例,但没有一个实例,结构图具有用于具体事件的处理程序。您需要使用事件的实际类型来构造类型,然后要求该事件的所有处理程序:
        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);
        }
    

要回复问题请先登录注册