【发布时间】:2013-01-28 01:10:34
【问题描述】:
我正在尝试使用依赖注入方法(使用 Ninject)开发一个库,但由于我的设计不正确,我可能会遇到某种混乱。总之,我的设计方法是
-
parent对象有一个common对象。 -
parent对象使用了可变数量的child对象。 - 所有
child对象都应使用与其parent对象完全相同的common对象实例
这是我的问题域的简单模型。
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的返回值,我可能需要也可能不需要其他子对象。所以我不想通过构造函数注入它们,只是在需要时创建它们。但这种做法违反了好莱坞原则。
问题 1
在不通过构造函数注入子对象的情况下,如何防止这种违规行为?
问题 2
我希望 child 对象使用相同的 common 对象实例及其 parent 对象。所以common对象的生命周期应该和它的父对象一样。
如果没有为 ICommon 定义生命周期,则所有
child对象都将拥有自己的common对象实例。如果 ICommon 的生命周期是在线程或请求范围内定义的,那么我不能在同一线程或请求范围内使用
parent对象的不同实例。因为每个parent对象都应该使用自己全新的common对象并处置它。
所以我无法使用我知道的生命周期范围选项来解决它。我为第二个问题提出了另一种解决方案,但它使代码变得更糟。
首先,不是将ICommon 注入parent 对象,而是通过ObjectFactory 自己创建parent 对象
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
这对我的问题有点笼统:如何将依赖注入正确应用于此模型?
注意:ObjectFactory.GetInstance 调用 Ninject 的 Kernel.Get
【问题讨论】:
-
+1 如果某个问题值得一票,这就是一个!
标签: c# dependency-injection ninject idisposable object-lifetime