使用Ninject与乌迪大汉的域事件 [英] Using Ninject with Udi Dahan's Domain Events

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

问题描述

我在MVC项目中使用Ninject,我试图实现以下乌迪大汉的模式的 http://www.udidahan.com/2009/06/14/domain-events-salvation/

在下面的提取物,所述容器用来解决所有事件处理程序,已提出了事件的特定类型的

我的问题(安培;道歉,如果我失去了一些基本的东西)是如何与Ninject做到这一点?换句话说:


  1. 如何容器在这个静态类被置?


  2. 有一次我一个容器(内核?)这将是Ninject语法来解决所有的事件处理程序(这我假设我必须先注册手以服务模块)?


我一直在读的帖子,只有构造器注入应使用一切递归从那个解决,那访问Ninject内核是一个没有没有。因此,对如何做到这一点的任何意见将大大AP preciated。

从文章中​​提取

 公共静态类DomainEvents
{
  [ThreadStatic] //让每个线程都有自己的回调
  私人静态列表<&代表GT;行动;  公共静态集装箱的IContainer {搞定;组; } //像之前一样  //注册为给定域事件的回调
  公共静态无效的注册< T>(动作< T>回调)其中T:IDomainEvent
  {
     如果(行动== NULL)
        行动=新的List<&代表GT;();     actions.Add(回调);
 } //清除传递给注册在当前线程上回调
 公共静态无效ClearCallbacks()
 {
     行动=无效;
 } //引发定域事件
 公共静态无效加薪< T>(T参数),其中T:IDomainEvent
 {
    如果(集装箱!= NULL)
       的foreach(在Container.ResolveAll&LT VAR处理程序;把手,LT; T>>())
          handler.Handle(参数);    如果(行动!= NULL)
        的foreach(在行动VAR动作)
            如果(动作动作< T>)
                ((动作< T>)动作)(参数);
 }
}


解决方案

  

如何容器获得这个静态类设置?


您将在应用程序启动时设置:

  DomainEvents.Container =内核;


  

这将是Ninject语法来解决所有的事件处理程序:


您可以像这样做,例如:

  Container.Get<&IEnumerable的LT;把手< T>>>())

乌迪的静态 DomainEvents 类是的周围语境的模式的实现。的周围语境的是这是只有在情景的数量限制可用的模式。在这种情况下,我宁愿使用依赖注入注入,而不是让code的 IDomainEvents 抽象到code需要它,依赖于静态实例。

问题不过是你的域对象需要在 IDomainEvents 和构造器注入的依赖是(可能)是不可能的。诀窍就是用注射的方法在这种情况下。

在换句话说,使用构造函数注入注入 IDomainEvents 进入命令处理程序或服务(或什么都你调用使用你的域对象的方法你的业务逻辑)而依赖传递到域对象调用需要它(方法注入)的方法时。

I'm using Ninject in an MVC project and am trying to implement Domain Events following Udi Dahan's pattern http://www.udidahan.com/2009/06/14/domain-events-salvation/

In the extract below, the "Container" is used to resolve all the event-handlers for the particular type of event that has been raised.

My question (& apologies if I am missing something basic) is how to do this with Ninject? In other words:

  1. How does the "Container" get set in this static class?

  2. Once I have a Container (Kernel?) what would be the Ninject syntax to resolve all the event handlers (which I'm assuming I would have to register before-hand in a Service Module)?

I keep reading in posts that only constructor injection should be used and everything recursively get resolved from that, and that accessing the Ninject Kernel is a no-no. So any advice on how to do this will be much appreciated.

Extract from the article

public static class DomainEvents
{ 
  [ThreadStatic] //so that each thread has its own callbacks
  private static List<Delegate> actions; 

  public static IContainer Container { get; set; } //as before

  //Registers a callback for the given domain event
  public static void Register<T>(Action<T> callback) where T : IDomainEvent
  {
     if (actions == null)
        actions = new List<Delegate>();

     actions.Add(callback);
 }

 //Clears callbacks passed to Register on the current thread
 public static void ClearCallbacks ()
 {
     actions = null;
 }

 //Raises the given domain event
 public static void Raise<T>(T args) where T : IDomainEvent
 {
    if (Container != null)
       foreach(var handler in Container.ResolveAll<Handles<T>>())
          handler.Handle(args);

    if (actions != null)
        foreach (var action in actions)
            if (action is Action<T>)
                ((Action<T>)action)(args);
 }
}

解决方案

How does the "Container" get set in this static class?

You will have to set it during application startup:

DomainEvents.Container = kernel;

what would be the Ninject syntax to resolve all the event handlers:

You can do it like this, for instance:

Container.Get<IEnumerable<Handles<T>>>())

Udi's static DomainEvents class is an implementation of the Ambient Context pattern. Ambient Context is a pattern which is only useable in a limit number of scenarios. In this case I would rather use dependency injection to inject an IDomainEvents abstraction into code that needs it, instead of letting code depend on a static instance.

The problem however is that your domain objects will need a dependency on the IDomainEvents and constructor injection is (probably) not possible. The trick is to use method injection in that case.

In other words, use constructor injection to inject the IDomainEvents into command handlers or services (or what ever you call your business logic that uses the methods on your domain objects) and pass that dependency into the domain object when calling a method that needs it (method injection).

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

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