2011-05-19 92 views
13

使用Ninject,你如何配置內核,以便我可以定義什麼構造函數值傳遞到對象的實例化?Ninject傳遞構造函數值

我有以下的一個模塊中配置:

Bind<IService1>() 
    .To<Service1Impl>() 
    .InSingletonScope() 
    .Named("LIVE"); 
Bind<IService2>() 
    .To<Service2Impl>() 
    .InSingletonScope() 
    .Named("LIVE") 
    .WithConstructorArgument(
     "service1", 
     Kernel.Get<IService1>("LIVE")); 

Service2Impl需要IService1的構造函數的參數,但我想這來自於容器。我也想命名綁定,因爲我的代碼將在運行時定位到不同的版本。

這似乎工作,但它是實現我想要做的正確方法? 我是否應該在不使用命名綁定的情況下實現並將不同的配置模塊連接到內核中?

EDIT

我已經使用了ToMethod()方法現在來指定一個代表到上的特定類型的請求調用。這看起來好多了,因爲如果構造函數配置錯誤,我會得到編譯時警告,而不必知道我首先傳遞的參數的名稱。

謝謝

回答

12

我最後使用了ToMethod,它允許我用構造函數構造所需的實例以維護編譯時錯誤。

例如:

.ToMethod(Func<IContext, T> method) 

Bind<IWeapon>().ToMethod(context => new Sword()); 
+1

對於.WithConstructorArgument更喜歡這種語法,編譯器會捕獲重構錯誤。 +1 – gb2d 2013-03-28 11:59:46

+1

您是否真的有一個應用程序需要一個武器界面和劍對象? – starmandeluxe 2016-09-15 08:39:59

0

也許提供者可以幫助你。將IService2綁定到提供者。並在Provider的Create方法中,使用Kernel.Get(「LIVE」)創建Service2Impl實例。

請訪問以下鏈接瞭解如何使用提供 https://github.com/ninject/ninject/wiki/Providers%2C-Factory-Methods-and-the-Activation-Context

+0

謝謝,我看到了。認爲這是一個太多的代碼,正如它在你分享的鏈接中所說的那樣,ToMethod是一個精簡版的提供者。 – 2011-05-20 01:21:42

16

我會建議WithConstructorParameter重載需要拉姆達像這樣:

Bind<IService2>() 
    .To<Service2Impl>() 
    .InSingletonScope() 
    .Named("LIVE") 
    .WithConstructorArgument(
     "service1", 
     ctx => ctx.Kernel.Get<IService1>("LIVE")); 

這將確保的IServive1分辨率情況在激活Service2Impl時,而不是在創建容器時啓動。雖然在你的情況下,它並不真正重要的是Service1Impl單,有可能是對的方式做它,你最初寫它的副作用:

  • 的用於由WithConstructorArgument注入依賴綁定有已存在。這意味着所有綁定必須按特定順序完成。當涉及多個模塊時,這會造成棘手的問題。

  • 使用自定義範圍時可能會出現範圍問題。 Ninject 2.0引入了緩存並收集範圍管理,綁定到一個常量很可能會導致混亂。

5

看來你正在看着這個錯誤的方式。如果Ninject將它作爲構造函數參數,它將自動將服務1注入到服務2中。在這種情況下,不需要WithConstructorArgument。

如果有多個IService1,你應該爲條件。例如。 WhenParentNamed(...)

0

我覺得ToConstant()是清潔的InSingletonScope是隱式的:

Bind<IService2>().ToConstant(new Service2Impl(argument))) 
       .Named("LIVE");