2010-01-28 39 views
7

我有這樣的事情:進樣值到注入依賴

class Root 
{ 
    public Root(IDependency dep) 
    {} 
} 
class Dependency:IDependency 
{ 
    public Dependency(int val) 
    {} 
} 

而我試圖獲得使用ninject到根的引用。 所以我配置它這樣

var module = new InlineModule(mod => mod.Bind<IDependency>().To<Dependency>()); 

var kernel = new StandardKernel(module); 

我想注入依賴的是僅在獲得來自ninject根引用的那一刻知道一些「VAL的價值。

我希望做的是這樣的:

Kernel.Instance.Get<Root>(With.Parameters.ConstructorArgument("val", 12)); 

是使用ninject 1.0這樣的事情可能嗎?

回答

8

上下文中的Parameters.ConstructorArgument默認只有一個深度。

將參數向下傳遞給多個層次的一種方法是使用ContextParameter,但是有些東西需要抓住並說出 - 現在我們將在這種情況下使用它作爲 ConstructorArgument。一個這樣的構造是提供者。見this dojo page for details of Providers

所以,你可以這樣做:

class DependencyProvider : SimpleProvider<Dependency> 
    { 
     protected override Dependency CreateInstance(IContext context) 
     { 
      return new Dependency((int)context.ParentContext.Parameters.GetOne<ContextVariableParameter>("masterVal").Value); 
     } 
    } 

    public static void Main() 
    { 
     var module = new InlineModule(
      mod => mod.Bind<IDependency>().ToProvider(new DependencyProvider()) 
     ); 

     var kernel = new StandardKernel(new[ ] {module}); 

     Root root = kernel.Get<Root>(With.Parameters.ContextVariable("masterVal", 12)); 
    } 

或者你可以按照如下進行管理:

class RootProvider : SimpleProvider<Root> 
    { 
     protected override Root CreateInstance(IContext context) 
     { 
      return new Root(context.Kernel.Get<Dependency>(With.Parameters.ConstructorArgument("val", (int)context.Parameters.GetOne<ContextVariableParameter>("masterVal").Value))); 
     } 
    } 

    public static void Main() 
    { 
     var module = new InlineModule(
      mod => mod.Bind<IDependency>().To<Dependency>(), // Optional if ImplictSelfBinding is on 
      mod => mod.Bind<Root>().ToProvider(new RootProvider()) 
     ); 

     var kernel = new StandardKernel(new[] {module}); 

     Root root = kernel.Get<Root>(With.Parameters.ContextVariable("masterVal", 12)); 
    } 

當你正在考慮這一點,考慮the points I make in this point re separating the concerns if configuration from object binding in this response

+0

我想我能做到這一點更多的只是想: 綁定()。爲了().WithConstructorArgument( 「VAL」(IContext續)=> \t \t cont.ParentContext.Parameters。獲得( 「VAL」)); 但我不喜歡使用ParentContext。 :(它 – Silviu 2010-02-01 07:15:36

+0

@Silviu:試試吧 - 越短越好,這對我來說似乎是有道理的,就像你直接問你的問題一樣,但是我不能在我嘗試它的情況下爲它工作 – 2010-02-01 08:50:20

+0

@ Silviu:你是否把它作爲「綁定」的一部分來完成呢?如果你想挑選一些可以用於評論的東西,我會把它放到例子中。 – 2010-02-11 08:40:45

1

隨着Ninject 3 IParameter S(ConstructorArgument是其中之一),現在簡單地「繼承」來的孩子的要求時,他們有ShouldInherit == true(見here)。

對於這個問題的解決方案,現在可以簡單:

IResolutionRoot.Get<Root>(new ConstructorArgument("val", 12, true)); 

,其中作爲ConstructorArgument的構造函數的true設置ShouldInherittrue。另請參閱here