更新:有没有办法实现我在温莎以外的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
需要MyClassOne
和OtherController
的实例需要MyClassTwo
的实例1}}?
如何将两个不同的具体类绑定到IoC中的同一接口?我不想创建2个不同的界面,因为它打破了DRY规则,无论如何都没有意义。
在温莎城堡,我会有两行:
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>());
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>());
这不起作用,因为我只会获得MyClassTwo
的副本,因为它是最后注册的接口。
就像我说的那样,如果没有为每个具体的界面创建特定的界面,我就无法做到这一点,这样做不仅打破了DRY规则,也打破了基本的OOP。我如何实现这一目标?
根据Mark Polsen的回答进行更新
这是我目前的IoC,.Resolve
语句会在哪里出现?我在温莎文档中看不到任何内容
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();
}
}
答案 0 :(得分:7)
我希望你能使用service overrides。
实施例
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)
{
}
}
答案 1 :(得分:5)
您应该可以使用命名组件注册来完成它。
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");
答案 2 :(得分:2)
DI容器通常遵循注册,解析和发布模式。在注册阶段,有两个步骤。第一种是指定您正在进行的映射。第二步是指定管理哪个注入位置的规则。
当我们尝试使用装饰器解决横切问题时,这个问题很常见。在这些情况下,您有多个类(装饰器)实现单个接口。
简而言之,我们需要实现IModelInterceptorsSelector,它允许您编写命令式代码,以决定将哪个Interceptor应用于哪些类型或成员。
Mark Seemann在.Net书中的Dependency Injection一书中详细描述了这一点。查找第9章拦截或搜索上述界面。
我不是这方面的专家,但是正在寻找完全相同的问题,并在上面的书中找到了ans。
希望这有帮助。
此致 DEV1