将Autofac与域事件一起使用

我正在尝试将域事件引入项目中。这个概念在Udi Dahan的帖子中描述 - http://www.udidahan.com/2009/06/14/domain-events-salvation/ 这是域事件代码
public interface IDomainEvent { }

public interface IHandleDomainEvents<T> where T : IDomainEvent
{
     void Handle(T args); 
}

public interface IEventDispatcher
{
    void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent;
}

public static class DomainEvents
{
    public static IEventDispatcher Dispatcher { get; set; }

    public static void Raise<TEvent>(TEvent eventToRaise) where TEvent : IDomainEvent
    {
        Dispatcher.Dispatch(eventToRaise);
    }
}
最重要的部分是IEventDispatcher实现,它将域事件与引发事件时发生的任何事件分离开来。诀窍是通过容器连接这个耦合。这是我的尝试 注册所有域事件处理程序的代码....
        var asm = Assembly.GetExecutingAssembly();
        var handlerType = typeof(IHandleDomainEvents<>);

        builder.RegisterAssemblyTypes(asm)
            .Where(t => handlerType.IsAssignableFrom(t)
                        && t.IsClass
                        && !t.IsAbstract)
            .AsClosedTypesOf(handlerType)
            .InstancePerLifetimeScope(); 
并解析调度程序中的所有事件处理程序。问题是没有解决处理程序。
public class EventDispatcher : IEventDispatcher
{
    private readonly IContainer _container;

    public EventDispatcher(IContainer container)
    {
        _container = container;
    }

    public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : IDomainEvent
    {
        var handlers = _container.Resolve<IEnumerable<IHandleDomainEvents<TEvent>>>().ToList();
        handlers.ForEach(handler => handler.Handle(eventToDispatch));
    }
}
所以我没有正确注册事件处理程序或者没有解决它们。 如何检查注册是否有效? 处理程序的示例代码
public class SendWebQuestionToCSO : IHandleDomainEvents<JobNoteCreated>
{
    private readonly IConfig _config;

    public SendWebQuestionToCSO(IConfig config)
    {
        _config = config;
    } 

    public void Handle(JobNoteCreated args)
    {
        var jobNote = args.JobNote;
        using(var message = new MailMessage())
        {
            var client = new SmtpClient {Host = _config.SmtpHostIp};
            message.From = new MailAddress(_config.WhenSendingEmailFromWebProcessUseThisAddress);
            ...... etc
        }
    }
}
UPDATE 经过一些试验和错误后,EventDispatcher正常工作!如果我手动注册一个处理程序,然后触发域事件它可以工作。装配扫描/注册是我的问题。 手动注册码......
builder.RegisterType<SendWebQuestionToCSO >().As<IHandleDomainEvents<JobNoteCreated>>();
因此,如果它们看起来像这样,我如何扫描所有assemblies5ѭ的所有组件
public class SendWebQuestionToCSO : IHandleDomainEvents<JobNoteCreated>
    
已邀请:
正如彼得指出的那样,注册问题与你的
Where()
条款有关。 扫描程序集时,Autofac会根据您指定的服务自动过滤组件,因此仅使用以下内容同样正确:
builder.RegisterAssemblyTypes(asm)
    .AsClosedTypesOf(handlerType)
    .InstancePerLifetimeScope();
    
装配扫描代码中的问题是使用
IsAssignableFrom
时。过滤器将询问:“是否可以将
SendWebQuestionToCSO
的实例分配给
IHandleDomainEvents<>
的变量?” 答案显然是“不”,因为你永远不会有一个开放泛型类型的变量。 诀窍是检查每种类型实现的接口,并检查它们是否正在关闭开放的通用接口类型。这是一个修改过的扫描仪:
    var asm = Assembly.GetExecutingAssembly();
    var handlerType = typeof(IHandleDomainEvents<>);

    builder.RegisterAssemblyTypes(asm)
        .Where(t => t.GetInterfaces().Any(t => t.IsClosedTypeOf(handlerType)))
        .AsImplementedInterfaces()
        .InstancePerLifetimeScope(); 
    
我不熟悉Autofac,但我相信我遇到了类似的问题,不是使用autofac而是使用架构动态通用接口转换。 这可能是协方差和逆变问题。     

要回复问题请先登录注册