我正在尝试使用依赖注入方法(使用Ninject)开发一个库,但由于我的设计不正确,我感到有些困惑。简而言之,我的设计方法是:
然后,父对象不再将
- 一个父对象拥有一个公共对象。
- 一个父对象使用任意数量的子对象。
- 所有子对象都应该使用与其父对象相同的公共对象实例。
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
的返回值,我可能需要其他的子对象,也可能不需要。因此,我不想通过构造函数注入它们,而是在需要时创建它们。但这种方法会违反 Hollywood 原则。
如何避免这种违规行为,而不是通过构造函数注入 child 对象?
问题 2
我希望 child
对象能够使用与其 parent
对象相同的 common
对象实例。因此,common
对象的生命周期应该与其父对象相同。
如果没有为 ICommon 定义生命周期,则所有
child
对象都将拥有自己的common
对象实例。如果 ICommon 的生命周期定义在 Thread 或 Request 作用域中,则我不能在同一线程或请求作用域中使用不同实例的
parent
对象。因为每个parent
对象应该使用自己的全新的common
对象并将其处理掉。
因此,我不能使用我所知道的生命周期范围选项来解决它。我对这个问题产生了另一个解决方案,但它会使代码变得更糟。
首先,不是将 ICommon
注入到 parent
对象中,而是通过 ObjectFactory
创建它自己的实例。
class Parent : IParent {
private readonly ICommon _common;
public Parent() {
_common = ObjectFactory.GetInstance<ICommon>();
}
.....
然后,父对象不再将
ICommon
注入到child
对象中,而是设置子对象的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();
}
}
问题1
但是这个解决方案再次违反了好莱坞原则,我必须为每个child
对象设置Common
属性。
问题2
如何使用依赖注入(最好使用Ninject)让parent
对象将其common
对象分配给child
对象?
问题3
这更一般地涉及到我的问题:如何正确地应用依赖注入到这个模型中?
注意:ObjectFactory.GetInstance
调用 Ninject 的Kernel.Get
。