将Autofac与域事件一起使用

CRG*_*CRG 14 autofac domain-events

我正在尝试将域事件引入项目中.这个概念在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

最重要的部分是IEventDispatcher实现,它将域事件与引发事件时发生的任何事件分离开来.诀窍是通过容器连接这个耦合.这是我的尝试

注册所有域事件处理程序的代码....

        var asm = Assembly.GetExecutingAssembly();
        var handlerType = typeof(IHandleDomainEvents<>);

        builder.RegisterAssemblyTypes(asm)
            .Where(t => handlerType.IsAssignableFrom(t)
                        && t.IsClass
                        && !t.IsAbstract)
            .AsClosedTypesOf(handlerType)
            .InstancePerLifetimeScope(); 
Run Code Online (Sandbox Code Playgroud)

并解析调度程序中的所有事件处理程序.问题是没有解决处理程序.

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我没有正确注册事件处理程序或者没有解决它们.如何检查注册是否有效?

处理程序的示例代码

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新 经过一些试验和错误后,EventDispatcher正常工作!如果我手动注册一个处理程序,然后触发域事件它可以工作.装配扫描/注册是我的问题.手动注册码......

builder.RegisterType<SendWebQuestionToCSO >().As<IHandleDomainEvents<JobNoteCreated>>();
Run Code Online (Sandbox Code Playgroud)

因此,如果IHandleDomainEvents<>看起来像这样,我如何扫描所有组件

public class SendWebQuestionToCSO : IHandleDomainEvents<JobNoteCreated>
Run Code Online (Sandbox Code Playgroud)

Nic*_*rdt 8

正如彼得指出的那样,注册问题与你的Where()条款有关.

扫描程序集时,Autofac会根据您指定的服务自动过滤组件,因此仅使用以下内容同样正确:

builder.RegisterAssemblyTypes(asm)
    .AsClosedTypesOf(handlerType)
    .InstancePerLifetimeScope();
Run Code Online (Sandbox Code Playgroud)