[英]dependency injection life cycle for IDisposable classes in .NET core
[英]Dependency injection and life time of IDisposable objects
我正在嘗試使用依賴注入方法(使用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();
}
}
所需的child
對象數量不盡相同。 例如,根據c1.DoSomething
返回值,我可能需要或可能不需要其他子對象。 所以我不想通過構造函數注入它們,只需在需要時創建它們。 但這種做法導致違反好萊塢原則。
如何在不通過構造函數注入子對象的情況下防止這種違規?
我希望child
對象與parent
對象使用相同的common
對象實例。 因此, common
對象的生命時間應與其父對象相同。
如果沒有為ICommon定義生命時間,則所有child
對象都將擁有自己的common
對象實例。
如果在Thread或Request范圍中定義了ICommon的生命周期,那么我不能在同一個Thread或Request范圍中使用parent
對象的不同實例。 因為每個parent
對象都應該使用自己的全新common
對象並進行處理。
所以我無法使用我所知道的終身范圍選項解決它。 我為第二個問題制作了另一個解決方案,但它使代碼變得更糟。
首先,不是將ICommon
注入parent
對象,而是通過ObjectFactory
自己創建parent
對象
class Parent : IParent {
private readonly ICommon _common;
public Parent() {
_common = ObjectFactory.GetInstance<ICommon>();
}
.....
然后, parent
對象不是將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();
}
}
但是這個解決方案再次違反了好萊塢原則,我必須設置每個child
對象的Common屬性。
parent
對象如何使用依賴注入將其common
對象分發給child
對象? (最好是Ninject)
這對我的問題更為籠統:Dependency Injection如何正確應用於此模型?
注意: ObjectFactory.GetInstance
調用Ninject的Kernel.Get
您需要使用任一CallScope
或NamedScope
。 這些是Ninject.Extensions.NamedScope
包的一部分。 這允許您將公共對象的范圍限定為父對象,以便所有子請求都接收相同的公共對象。
關於子對象創建。 如果您必須根據某些算法請求子對象,則需要使用工廠對其進行實例化。 使用Ninject.Extensions.Factory
包來實現此目的。 這樣做了一個上下文保留get並將父上下文傳遞給子請求,因此允許在工廠創建的子節點中重用您的公共對象。
所以最終不需要使用自己的對象工廠。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.