依赖注入 - 订阅组合根中的事件而不是构造函数

时间:2013-08-22 14:26:47

标签: c# events constructor dependency-injection compositionroot

在实施DI时,Mark Seemann和Misko Hevery都说构造函数应该简单,并且只应该接收依赖。他们不应该做任何其他事情。 (herehere

但是,我经常想订阅传入的依赖项的事件,但是如果我在构造函数中执行此操作,那么构造函数不仅仅接收它的依赖项,如果我不这样做,那么该对象不是完全初始化。

那么,实例化那些需要在组合根中订阅事件,挂钩事件,然后注入那些实例化对象的对象是否正确?

例如:

// Composition root
Panel panel = new Panel();
Button button = new Button();
panel.OnButtonClick += button.Click;

Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);

// Panel Class
private Button _button;

public Panel(Button button)
{
    _button = button;
}

void OnButtonClick()
{
    // handle button click
}

而不是:

//composition root
Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);

// Panel Class
private Button _button;

public Panel(Button button)
{
    _button = button;
    OnButtonClick += button.Click
}

void OnButtonClick()
{
    // handle button click
}

2 个答案:

答案 0 :(得分:0)

是的,在组合根中连接事件将是正确的方法。

答案 1 :(得分:0)

这个答案主要是基于意见的。

我通常不会将DI用于表示层,因为我假设DI的最佳用法是在域(业务)层中创建持久性无知类。但DI的使用是针对无状态service类。它处理请求而不管任何指定的状态,并且是无事件的,因此消除了service类中事件的需要。

您要创建的内容可能是control类,而不是service类,因此,分配事件是一个真正的问题。但是,我不认为连接事件违反了构造函数规则的事情,因为它只是在协助事件。

  1. 为什么它没有事件?

    接受请求并处理它。如果您需要执行以下操作:afterProcessbeforeProcess等,您可以在类中定义特定事件,并将接口作为依赖项传递。

  2. 如果我需要做基于事件的怎么办?

    有时你需要传递一个事件in some cases。您可以使用Func(或java中的适配器)进行参数注入,而不是在构造函数中挂钩。