将Autofac与域事件一起使用 [英] Using Autofac with Domain Events

查看:102
本文介绍了将Autofac与域事件一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将领域事件引入到项目中. Udi Dahan的帖子- http://www.udidahan .com/2009/06/14/domain-events-salvation/

I'm trying to introduce domain events into a project. The concept is described in Udi Dahan's post - 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实现,该实现将域事件与引发事件时所需发生的一切脱钩.诀窍是通过容器将这种耦合连接起来.这是我的尝试

The most important part is the IEventDispatcher implementation that decouples the domain event from whatever needs to happen when the event is raised. The trick is to wire up this coupling through a container. Here's my attempt

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

Code for Registering all Domain event handlers....

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

        builder.RegisterAssemblyTypes(asm)
            .Where(t => handlerType.IsAssignableFrom(t)
                        && t.IsClass
                        && !t.IsAbstract)
            .AsClosedTypesOf(handlerType)
            .InstancePerLifetimeScope(); 

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

And resolving all the event handlers in the dispatcher. The problem is no handlers are resolved.

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

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

So I'm not registering the event handlers correctly or not resolving them. How do I check that the registration is working?

处理程序的示例代码

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

更新 经过反复试验后,EventDispatcher正常运行!如果我手动注册一个处理程序,然后触发域事件,它将起作用.程序集扫描/注册是我的问题. 手动注册代码...

UPDATE After some trial and error the EventDispatcher is working ok! If I manually register a handler and then fire the domain event it works. The assembly scanning/registraion is my problem. The manual registration code...

builder.RegisterType<SendWebQuestionToCSO >().As<IHandleDomainEvents<JobNoteCreated>>();

那么,如果它们看起来像这样,我该如何扫描所有程序集的所有IHandleDomainEvents<>

So how do I scan all assemblies for all IHandleDomainEvents<> given they look like this

public class SendWebQuestionToCSO : IHandleDomainEvents<JobNoteCreated>

推荐答案

正如Peter指出的那样,注册问题出在您的Where()子句中.

As Peter pointed out, the registration problem was with your Where() clause.

在扫描装配体时,Autofac会根据您指定的服务自动过滤零部件,因此使用以下方法同样正确:

When scanning assemblies Autofac filters components automatically based on the services you specify, so it would be equally correct to just use:

builder.RegisterAssemblyTypes(asm)
    .AsClosedTypesOf(handlerType)
    .InstancePerLifetimeScope();

这篇关于将Autofac与域事件一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆