IOC(Ninject)和工厂 [英] IoC (Ninject) and Factories
问题描述
如果我有下面的代码:
public class RobotNavigationService : IRobotNavigationService {
public RobotNavigationService(IRobotFactory robotFactory) {
//...
}
}
public class RobotFactory : IRobotFactory {
public IRobot Create(string nameOfRobot) {
if (name == "Maximilian") {
return new KillerRobot();
} else {
return new StandardRobot();
}
}
}
我的问题是什么正确的方式做控制反转吗?我不想给KillerRobot和StandardRobot混凝土添加到工厂类是吧?而且我不希望把他们通过IoC.Get<>对不对? BC这将是服务定位不正确的IoC吧?有没有更好的方式来处理的切换具体在运行时
推荐答案
这个问题为您样,你有一个完美的罚款工厂实现,我不会改变任何事情。
For your sample, you have a perfectly fine factory implementation and I wouldn't change anything.
不过,我怀疑你的KillerRobot和StandardRobot类实际上有自己的依赖关系。我同意你不想暴露你的IoC容器的RobotFactory
However, I suspect that your KillerRobot and StandardRobot classes actually have dependencies of their own. I agree that you don't want to expose your IoC container to the RobotFactory.
一种选择是使用ninject工厂扩展:
One option is to use the ninject factory extension:
https://github.com/ninject/ninject.extensions.factory/wiki一>
它为您提供了两种方式注入工厂 - 按接口,并通过注射Func键返回一个iRobot公司(或其他)
It gives you two ways to inject factories - by interface, and by injecting a Func which returns an IRobot (or whatever).
样品基于接口工厂创建/ninject/ninject.extensions.factory/wiki/Factory-interface
Sample for interface based factory creation: https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface
根据样本FUNC:的https://github.com/ninject/ninject.extensions.factory/wiki/Func
Sample for func based: https://github.com/ninject/ninject.extensions.factory/wiki/Func
如果你愿意,你也可以在你的IoC初始化代码绑定FUNC做到这一点。是这样的:
If you wanted, you could also do it by binding a func in your IoC Initialization code. Something like:
var factoryMethod = new Func<string, IRobot>(nameOfRobot =>
{
if (nameOfRobot == "Maximilian")
{
return _ninjectKernel.Get<KillerRobot>();
}
else
{
return _ninjectKernel.Get<StandardRobot>();
}
});
_ninjectKernel.Bind<Func<string, IRobot>>().ToConstant(factoryMethod);
您导航服务,则可能看起来像:
Your navigation service could then look like:
public class RobotNavigationService
{
public RobotNavigationService(Func<string, IRobot> robotFactory)
{
var killer = robotFactory("Maximilian");
var standard = robotFactory("");
}
}
当然,这种方法的问题是,你'重新编写的工厂方法正确你的IoC初始化内 - 也许不是最好的折衷...
Of course, the problem with this approach is that you're writing factory methods right inside your IoC Initialization - perhaps not the best tradeoff...
工厂扩展试图通过给你几个基于约定的办法来解决这个问题 - 从而让您保持与除上下文敏感的依赖性正常DI链接。
The factory extension attempts to solve this by giving you several convention-based approaches - thus allowing you to retain normal DI chaining with the addition of context-sensitive dependencies.
这篇关于IOC(Ninject)和工厂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!