Asp.net-Mvc-3

具有由多個類實現的介面的依賴注入

  • June 23, 2013

**更新:**有沒有辦法在 Windsor 以外的 IoC 框架中實現我想要做的事情?Windsor 會很好地處理控制器,但不會解決其他任何問題。我確定這是我的錯,但我正在逐字遵循教程,並且對像沒有通過 ctor 注入解析,儘管進行了註冊和解析,它們仍然為空。我已經廢棄了我的 DI 程式碼並暫時進行手動注入,因為該項目對時間很敏感。希望在截止日期前完成 DI。


我有一個解決方案,它有多個類都實現了相同的介面

舉個簡單的例子,Interface

public interface IMyInterface {
   string GetString();
   int GetInt();
  ...
}

具體類

public class MyClassOne : IMyInterface {
   public string GetString() {
       ....
   }
   public int GetInt() {
       ....
   }
}

public class MyClassTwo : IMyInterface {
   public string GetString() {
       ....
   }
   public int GetInt() {
       ....
   }
}

現在這些類將在需要的地方注入到它們上面的層中,例如:

public class HomeController {

   private readonly IMyInterface myInterface;

   public HomeController() {}

   public HomeController(IMyInterface _myInterface) {
       myInterface = _myInterface
   }
   ...
}

public class OtherController {

   private readonly IMyInterface myInterface;

   public OtherController() {}

   public OtherController(IMyInterface _myInterface) {
       myInterface = _myInterface
   }
   ...
}

兩個控制器都注入了相同的介面。

在我的 IoC 中使用適當的具體類解決這些介面時,我如何區分HomeController需要一個實例MyClassOneOtherController需要一個實例MyClassTwo

如何將兩個不同的具體類綁定到 IoC 中的同一個介面?我不想創建 2 個不同的介面,因為這違反了 DRY 規則並且無論如何都沒有意義。

在溫莎城堡中,我會有 2 行這樣的:

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());

這行不通,因為我只會得到一個副本,MyClassTwo因為它是為介面註冊的最後一個。

就像我說的,如果不為每個具體實例創建特定的介面,我不知道如何做到這一點,這樣做不僅違反了 DRY 規則,而且也違反了基本的 OOP。我如何實現這一目標?


根據 Mark Polsen 的回答進行更新


這是我目前的 IoC,.Resolve聲明會去哪裡?我在 Windsor 文件中看不到任何內容

public class Dependency : IDependency {

   private readonly WindsorContainer container = new WindsorContainer();

   private IDependency() {
   }

   public IDependency AddWeb() {
       ...

       container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList"));
       container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList"));

       return this;
   }

   public static IDependency Start() {
       return new IDependency();
   }
}

您應該能夠通過命名組件註冊來完成它。

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>().Named("One"));
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>().Named("Two"));

然後解決它們

kernel.Resolve<IMyInterface>("One");

或者

kernel.Resolve<IMyInterface>("Two");

請參閱:指定組件的名稱

我希望您可以使用服務覆蓋

前任。

container.Register(
   Component.For<IMyService>()
       .ImplementedBy<MyServiceImpl>()
       .Named("myservice.default"),
   Component.For<IMyService>()
       .ImplementedBy<OtherServiceImpl>()
       .Named("myservice.alternative"),

   Component.For<ProductController>()
       .ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.alternative"))
);

public class ProductController
{
   // Will get a OtherServiceImpl for myService.
   // MyServiceImpl would be given without the service override.
   public ProductController(IMyService myService)
   {
   }
}

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