2012-12-26 45 views
13

假設我使用Ninject構建了以下類,其中箭頭顯示了依賴關係。Ninject作用域 - 在構建的整個圖中使用相同的實例

​​

我想配置Ninject使得A是短暫的範圍的,即你問Ninject用於A每一次,你會得到一個新的。我也希望B和C是暫時的,每當你要求一個答案時,你會得到一個新的答案。但是我希望B和C都可以重複使用。因此,每當我請求A時,I要Ninject構建每個對象的一個​​,而不是兩個Ds。但我不想讓Ds在不同的As上重用。

使用Ninject進行設置的最佳方法是什麼?

更新:
一些調查研究後,好像團結具有PerResolveLifetimeManager它做什麼我要找的。是否有Ninject等價物?

回答

13

Ninject支持四個內置object scopes out of the box:瞬態,單例,線程,請求。

所以沒有任何PerResolveLifetimeManager類似的範圍,但你可以很容易地實現它與註冊自定義範圍與InScope方法。

事實證明,有一個現有的Ninject擴展:ninject.extensions.namedscope它提供了InCallScope方法,這正是你正在尋找的。

但是,如果您想自己做,您可以使用自定義InScope代表。在這裏您可以使用主IRequest對象類型A使用它的範圍對象:

var kernel = new StandardKernel(); 
kernel.Bind<A>().ToSelf().InTransientScope(); 
kernel.Bind<B>().ToSelf().InTransientScope(); 
kernel.Bind<C>().ToSelf().InTransientScope(); 
kernel.Bind<D>().ToSelf().InScope(
    c => 
     { 
      //use the Request for A as the scope object       
      var requestForA = c.Request; 
      while (requestForA != null && requestForA.Service != typeof (A)) 
      { 
       requestForA = requestForA.ParentRequest; 
      } 
      return requestForA; 
     }); 

var a1 = kernel.Get<A>();  
Assert.AreSame(a1.b.d, a1.c.d); 

var a2 = kernel.Get<A>();  
Assert.AreSame(a2.b.d, a2.c.d); 

Assert.AreNotSame(a1.c.d, a2.c.d); 

當樣品類:

public class A 
{ 
    public readonly B b; 
    public readonly C c; 
    public A(B b, C c) { this.b = b; this.c = c; } 
} 

public class B 
{ 
    public readonly D d; 
    public B(D d) { this.d = d; } 
} 

public class C 
{ 
    public readonly D d; 
    public C(D d) { this.d = d; } 
} 

public class D { } 
+0

如果D也是一部分,如果依賴鏈不包含A? –

+0

@KevinBabcock。不,它不會中斷。然後,委託將返回'null',這相當於下面的註冊:'kernel.Bind ().ToSelf()。InTransientScope();' – nemesv

+0

感謝您的澄清。好答案! –

1

一種替代方法是自己構建的依賴關係。

var kernel = new StandardKernel(); 
kernel.Bind<A>().ToMethod(ctx => 
{ 
    var d = new D(); 
    var c = new C(d); 
    var b = new B(d); 
    var a = new A(b, c); 
    return a; 
}); 

這可能不是優選的方法,但使用的BC,和D一個新的實例(但重用的D相同的實例爲BC)它總是構建的A的新實例。您可以將呼叫添加到InTransientScope(),但這不是必需的,因爲它是默認範圍。

+0

這對我所需要的東西太具體了。實際上,在我的代碼中,A,B,C級有許多不同的類,它們都需要爲給定的分辨率共享一個D。 – RationalGeek

相關問題