我正在尝试使用依赖注入方法(使用 Ninject)开发一个库,但由于我的设计不正确,我可能会遇到某种混乱。总之,我的设计方法是
- 一个
parent
对象有一个common
对象。 - 一个
parent
对象使用一些可变数量的child
对象。 - 所有
child
对象都应使用common
与其parent
对象完全相同的对象实例
这是我的问题域的简单模型。
interface IParent : IDisposable {
void Operation();
}
interface ICommon : IDisposable {
void DoCommonThing();
}
interface IChild1 {
void DoSomething();
}
interface IChild2 {
void DoAnotherThing();
}
class Parent : IParent {
private readonly ICommon _common;
public Parent(ICommon common) {
_common = common;
}
public void Dispose() {
_common.Dispose();
}
public void Operation() {
var c1 = ObjectFactory.GetInstance<IChild1>();
c1.DoSomething();
var c2 = ObjectFactory.GetInstance<IChild2>();
c2.DoAnotherThing();
// number of childs vary, do things until cn
_common.DoCommonThing();
}
}
class Common : ICommon {
private bool _isDisposed;
public void Dispose() {
_isDisposed = true;
}
public void DoCommonThing() {
if (_isDisposed)
throw new Exception("Common Object is Disposed");
}
}
class Child1 : IChild1
{
private readonly ICommon _common;
public Child1(ICommon common) {
_common = common;
}
public void DoSomething() {
// Do Something...
_common.DoCommonThing();
}
}
class Child2 : IChild2 {
private readonly ICommon _common;
public Child2(ICommon common) {
_common = common;
}
public void DoAnotherThing() {
// Do Another Thing...
_common.DoCommonThing();
}
}
问题 1
所需child
对象的数量各不相同。例如,根据c1.DoSomething
I 的返回值可能需要也可能不需要其他子对象。所以我不想通过构造函数注入它们,只是在需要时创建它们。但这种做法违反了好莱坞原则。
问题 1
在不通过构造函数注入子对象的情况下,如何防止这种违规行为?
问题 2
我希望child
对象使用与其对象相同common
的对象实例parent
。所以common
对象的生命周期应该和它的父对象一样。
如果没有为 ICommon 定义生命周期,那么所有
child
对象都将拥有自己的common
对象实例。如果 ICommon 的生命周期是在 Thread 或 Request 范围内定义的,那么我不能
parent
在同一 Thread 或 Request 范围内使用不同的对象实例。因为每个parent
对象都应该使用自己的全新common
对象并处理它。
所以我无法使用我知道的生命周期范围选项来解决它。我为第二个问题提出了另一种解决方案,但它使代码变得更糟。
首先,它不是注入ICommon
到parent
对象中,parent
而是通过它自己创建的对象ObjectFactory
class Parent : IParent {
private readonly ICommon _common;
public Parent() {
_common = ObjectFactory.GetInstance<ICommon>();
}
.....
然后,对象不是注入ICommon
对象child
,而是parent
设置common
子对象的对象。
interface IChild {
ICommon Common { get; set; }
}
interface IChildN : IChild {
void DoNthThing();
}
abstract class ChildBase : IChild {
ICommon IChild.Common { get; set; }
}
class ChildN : IChildN {
public void DoNthThing() { }
}
class Parent : IParent {
private readonly ICommon _common;
public void Operation() {
var c1 = ObjectFactory.GetInstance<IChild1>();
c1.Common = _common;
c1.DoSomething();
var c2 = ObjectFactory.GetInstance<IChild2>();
c2.Common = _common;
c2.DoAnotherThing();
_common.DoCommonThing();
}
}
但是这个解决方案再次违反了好莱坞原则,我必须设置每个child
对象的 Common 属性。
问题2
对象如何使用依赖注入parent
将其common
对象分发给对象?child
(最好使用 Ninject)
问题 3
关于我的问题,这有点笼统:如何将依赖注入正确应用于此模型?
注意:Ninject 的ObjectFactory.GetInstance
调用Kernel.Get