Asp.net-Mvc-3
具有由多個類實現的介面的依賴注入
**更新:**有沒有辦法在 Windsor 以外的 IoC 框架中實現我想要做的事情?Windsor 會很好地處理控制器,但不會解決其他任何問題。我確定這是我的錯,但我正在逐字遵循教程,並且對像沒有通過 ctor 注入解析,儘管進行了註冊和解析,它們仍然為空。我已經廢棄了我的 DI 程式碼並暫時進行手動注入,因為該項目對時間很敏感。希望在截止日期前完成 DI。
我有一個解決方案,它有多個類都實現了相同的介面
舉個簡單的例子,
Interfacepublic 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需要一個實例MyClassOne和OtherController需要一個實例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) { } }