14

プロジェクトにドメイン イベントを導入しようとしています。この概念は、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>>();

IHandleDomainEvents<>では、このように見えるすべてのアセンブリをスキャンするにはどうすればよいですか

public class SendWebQuestionToCSO : IHandleDomainEvents<JobNoteCreated>
4

2 に答える 2

2

アセンブリ スキャン コードの問題は、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(); 
于 2011-04-13T00:16:45.337 に答える