Dot-Net

我可以使用強命名的 Ninject ConstructorArguments 嗎?

  • February 20, 2013

好吧,我不知道“強命名”是否正確,但我想做的如下。

目前我使用 ConstructorArgument 像這樣:

public class Ninja
{
   private readonly IWeapon _weapon;
   private readonly string _name;

   public Ninja(string name, IWeapon weapon)
   {
       _weapon = weapon;
       _name = name;
   }
   // ..more code..
}

public void SomeFunction()
{
   var kernel = new StandardKernel();
   kernel.Bind<IWeapon>().To<Sword>();
   var ninja = kernel.Get<Ninja>(new ConstructorArgument("name", "Lee"));
}

現在,如果我重命名參數“name”(例如使用 ReSharper),ConstructorArgument 將不會更新,並且在創建 Ninja 時會出現執行時錯誤。要解決此問題,我需要手動查找通過 ConstructorArgument 指定此參數的所有位置並更新它。不好,即使我有很好的測試覆蓋率,我也注定會在某些時候失敗。重命名應該是一種廉價的操作。

有什麼方法可以改為引用參數 - 以便在重命名參數時更新它?

如果您可以分享更多您真正想要實現的目標,您將獲得更好的答案。一般來說,如果有幫助的話,你根本不想依賴傳遞 ConstructorArgument - 它應該是最後的手段,將參數值硬塞到創建你不擁有的組件中,因此可以依賴不被改名

$$ as $$在重構活動期間無所事事。因此,對於普通程式碼,如果您可以嘗試將其保留在介面中以使事情明確而不依賴於更好的名稱。 現在無法舉出一個例子,但是有一個很常見的成語叫做靜態反射。提供的 ConstructorArgument 可以在任何建構子中匹配該名稱的任何參數,因此靜態反射在這種情況下不是最合適的。

因此,靜態反射可能允許您實現的最佳效果是:

var ninja = ninject.Get<Ninja>( ParamNamesOf(()=>new Ninja( "dummy", "dummy" )).First() );

您將看到的典型範例是要提取實例上正在訪問的屬性的名稱。這有點不同,因為它需要在建構子呼叫表達式上工作。

至於找到一個已經擁有的合適的庫,請為搜尋者練習:D(但我建議找到一種更好的方法來表達你想要做的事情,ConstructorArgument無論如何不要使用這種方法。)

引用自:https://stackoverflow.com/questions/2636864