【发布时间】:2015-09-08 11:50:15
【问题描述】:
我有以下安装程序,但由于某些奇怪的原因,它无法正确解析。我有一个接口,其中有 2 个实现,但想基于 naming conventions 注入正确的实例。
我期望在这种情况下,ICommand 的正确实例将根据它们的命名方式被注入。但是,由于某些奇怪的原因,两个控制器都选择了第一个实例,即FooCommand,因为它是在安装程序中首先定义的。
不确定我做错了什么?也许,有没有其他方法可以做到这一点?
public interface ICommand { }
public class FooCommand : ICommand { }
public class BarCommand : ICommand { }
public class SomeController : ApiController
{
public SomeController(ICommand fooCommand) { }
}
public class HelloController : ApiController
{
public HelloController(ICommand barCommand) { }
}
container.Register(
Component.For<ICommand>()
.Named("fooCommand")
.ImplementedBy<FooCommand>()
.LifestyleSingleton(),
Component.For<ICommand>()
.Named("barCommand")
.ImplementedBy<BarCommand>()
.LifestyleSingleton());
【问题讨论】:
-
所以你想在
SomeController和BarCommand中注入FooCommand在HelloController中?但是如果你交换依赖关系,那些控制器会发生什么,即将BarCommand注入SomeController?这会破坏SomeController还是会继续正常运行? -
这会破坏它,因为它们最终都会与不同的基础表进行对话。
-
在这种情况下,您违反了Liskov Substitution Principle,这就是您问题的根源。要解决此问题,请为这两个命令提供自己独特的界面。
-
您可能还想看看使用更多消息驱动的设计,例如this one。
-
现实世界中,它只是对某个表执行 SQL 命令。 @Steven 我不太同意您的方法,因为这意味着我将拥有两个相同的接口。这只是一个不同的实现。您的方法意味着每个具体实现都有一个接口。
标签: c# dependency-injection castle-windsor