【发布时间】:2016-01-12 22:39:09
【问题描述】:
我们有一种情况,我们使用 Castle Windsor 依赖注入将 IService 注入到 wep api 控制器中,如下所示:
public FooController : ApiController
{
private IService _service;
public FooController(IService service)
{
_service = service;
}
}
并像这样注册服务:
container.Register(Component.For<IService>().ImplementedBy<Service>().LifestyleTransient());
服务类似于:
public Service : IService
{
public virtual string Logic()
{
return "Service Logic";
}
}
问题是,一些客户的业务逻辑与基础业务逻辑半不同,因此我们需要使用 Service 的另一个实现来满足客户的需求。
因此,如果有 2 个客户(客户 1 和客户 2),客户 1 应使用默认的 Service,但客户 2 应使用名为 Customer2Service 的自定义实现,它将继承自 Service 并根据需要覆盖,如下所示:
public Customer2Service : Service
{
public override string Logic()
{
var response = base.Logic();
return "Customer 2 Logic " + response;
}
}
问题
- 首先,这似乎是解决客户特定代码这一特殊问题的正确架构吗?
- 有没有办法使用依赖注入来解决这个问题? (我们不想要一个巨大的 switch 语句,它只是根据每个操作中的客户名称来选择要使用的服务)
我们的尝试
我们尝试将依赖注入更改为基于属性,如下所示:
public FooController : ApiController
{
private IService _service;
public FooController()
{
}
public HttpResponseMessage FooAction(string customer)
{
_service = container.Resolve<IService>(customer);
...
}
}
container.Register(Component.For<IService>().ImplementedBy<Service>().LifestyleTransient());
container.Register(Component.For<IService>().ImplementedBy<Customer2Service>().LifestyleTransient().Named("Customer2"));
这样做的问题是,我们必须为每个客户提供定制服务,即使他们不需要,这会变得笨拙。否则解析会抛出一个异常,指出命名依赖项不存在。
【问题讨论】:
-
@NightOwl888 我喜欢这个答案,我认为这与 Kenneth 的答案一致,即使用注入的工厂而不是服务。谢谢!
标签: c# dependency-injection castle-windsor