[英]How to inject different implementations to same interface without conditional/context DI?
I have the following problem and I currently have a solution using conditional dependency injection. 我有以下问题,目前有使用条件依赖注入的解决方案。 I have read that this is a bad idea, such as here in the SimpleInjector docs.
我已阅读,这是一个糟糕的主意,比如这里的SimpleInjector文档。 I have read a large number of posts now and have seen various things suggesting using Strategy, Factory patterns, etc. What I am really looking for is some specifics - ie an example of some code - about how to solve without conditional injection.
我现在已经阅读了大量文章,并且看到了各种建议使用策略,工厂模式等的内容。我真正要寻找的是一些有关如何进行无条件注入的解决方案的细节(即一些代码示例)。 I need more that "use a factory".
我需要更多“使用工厂”。 Here's a simplified version of my code.
这是我的代码的简化版本。 This is in an MVC web app, thus the controllers.
这在MVC Web应用程序中,因此在控制器中。
public abstract class QAControllerBase : Controller
{
protected readonly QABusinessLayer _blQA;
public QAControllerBase(QABusinessLayer bl)
{
_blQA = bl;
}
[HttpGet]
public ActionResult PPR(string accession, string site)
{
var m = _blQA.popPPRViewModel(accession);
return View(m);
}
}
public class QASouthController : QAControllerBase
{
public QASouthController([QASouthBinding] QABusinessLayer bl) : base(bl)
{
}
// some actions that are specific to South
}
public class QANorthController : QAControllerBase
{
public QANorthController([QANorthBinding] QABusinessLayer bl) : base(bl)
{
}
// some actions that are specific to North
}
public abstract class QABusinessLayer
{
protected readonly IFullBaseRepo _repo;
public QABusinessLayer(IFullBaseRepo repo)
{
_repo = repo;
}
public abstract PPRViewModel popPPRViewModel(string accession);
protected PPRViewModel DoSomeCommonStuff(PPRViewModel model)
{
...
return model;
}
}
public class SouthBusinessLayer: QABusinessLayer
{
public SouthBusinessLayer([QASouthBinding] IFullBaseRepo repo) : base(repo)
{
}
public override PPRViewModel popPPRViewModel(string accession)
{
var m = new PPRViewModel();
// do some stuff that is specific to South
DoSomeCommonStuff(m);
return m;
}
}
public class NorthBusinessLayer : QABusinessLayer
{
public NorthBusinessLayer([QANorthBinding] IFullBaseRepo repo) : base(repo)
{
}
public override PPRViewModel popPPRViewModel(string accession)
{
var m = new PPRViewModel();
// do some stuff that is specific to North
DoSomeCommonStuff(m);
return m;
}
}
and here is the Ninject binding code that is pertinent: 这是相关的Ninject绑定代码:
kernel.Bind<QABusinessLayer>()
.To<SouthBusinessLayer>()
.WhenTargetHas<QASouthBinding>()
.InRequestScope();
kernel.Bind<QABusinessLayer>()
.To<NorthBusinessLayer>()
.WhenTargetHas<QANorthBinding>()
.InRequestScope();
The QASouthBinding and QANorthBinding are just simple attributes. QASouthBinding和QANorthBinding只是简单的属性。 I am not asking for Ninject specific example.
我不是在问Ninject的具体例子。 Any code sample as to how this might be handled without using conditional or context based injection as I am now.
无需像现在这样使用条件注入或基于上下文注入的任何有关如何处理的代码示例。
Make your QABusinessLayer class abstract. 使您的QABusinessLayer类抽象。
Change your startup configuration to: 将启动配置更改为:
kernel
.Bind<SouthBusinessLayer>()
.To<SouthBusinessLayer>()
.InRequestScope();
kernel
.Bind<NorthBusinessLayer>()
.To<NorthBusinessLayer>()
.InRequestScope();
Change your controller constructors to accept a concrete business layer type: 更改控制器构造函数以接受具体的业务层类型:
public class QANorthController : QAControllerBase
{
public QANorthController(NorthBusinessLayer businessLayer) : base(businessLayer)
{
}
}
public class QASouthController : QAControllerBase
{
public QASouthController(SouthBusinessLayer businessLayer) : base(businessLayer)
{
}
}
Few things: 一些事情:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.