2011-03-14 70 views
2

我試圖找到一個將構造函數參數傳遞給子類構造函數的方法。 這些對象是不可變的,所以我寧願使用構造函數參數。在Ninject中繼承構造函數參數

我所遇到的問題是,ConstructorArgument不會繼承到子實例和下面的語句是不能互換:

_parsingProcessor = _kernel.Get<IParsingProcessor>(new ConstructorArgument("dataFilePath", dataFilePath); 

_parsingProcessor = _kernel.Get<IParsingProcessor>(new Parameter("dataFilePath", dataFilePath, true); 

那麼,怎樣才能得到繼承ConstructorArgument和什麼時候纔有意義,如果有的話,新的參數類?

+1

你能提供更多關於你想要做什麼的信息嗎?可以將參數傳遞給孩子。但在大多數情況下,這不是最好的解決方案。 – 2011-03-14 17:01:44

回答

3

是的,你可以做到這一點,但它可能不是你真正想要的。如果容器實際上不負責實例化它自己的依賴項,那麼它的依賴項可能是不應該共享它的構造函數參數 - 它只是沒有意義。

我很確定我知道你在做什麼,推薦的方法是專門爲你的容器創建一個唯一的綁定,並使用WhenInjectedInto條件綁定語法,如下例所示:

public class Hello : IHello 
{ 
    private readonly string name; 

    public Hello(string name) 
    { 
     this.name = name; 
    } 

    public void SayHello() 
    { 
     Console.WriteLine("Hello, {0}!", name); 
    } 
} 

這是接受我們要修改的構造函數參數的類,具體取決於誰在請求IHello。比方說,它的這種無聊的容器類:

public class MyApp : IApp 
{ 
    private readonly IHello hello; 

    public MyApp(IHello hello) 
    { 
     this.hello = hello; 
    } 

    public virtual void Run() 
    { 
     hello.SayHello(); 
     Console.ReadLine(); 
    } 
} 

現在,這裏是你怎麼做了綁定:

public class MainModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IApp>().To<MyApp>(); 
     Bind<IHello>().To<Hello>() 
      .WithConstructorArgument("name", "Jim"); 
     Bind<IHello>().To<Hello>() 
      .WhenInjectedInto<MyApp>() 
      .WithConstructorArgument("name", "Bob"); 
    } 
} 

基本上所有這些結合正在做的是說的name應該是「吉姆」 除非它正在被Hello請求,在這種情況下,它會得到名稱「Bob」。


如果你是絕對一定你真正想要級聯行爲,並明白這是非常危險和脆弱,你可以使用欺騙的方法結合。假設我們現在已經增加了一個name參數傳遞給MyApp類某個不確定的目的,結合將是:

Bind<IHello>().ToMethod(ctx => 
    ctx.Kernel.Get<Hello>(ctx.Request.ParentContext.Parameters 
     .OfType<ConstructorArgument>() 
     .Where(c => c.Name == "name") 
     .First())); 

請,請,請確保您積極這是你在做之前要什麼它。它看起來很簡單,但它也很可能在一次簡單的重構期間中斷,而我所看到的95%的「自定義依賴」場景可以使用WhenInjectedInto綁定來解決。