策略模式和依赖注入使用Unity [英] Strategy Pattern and Dependency Injection using Unity
问题描述
我终于得到我的脚湿依赖注入(姗姗来迟);我开始使用Unity玩,运行与策略模式的问题。我可以用容器还给我具体的实现基于名称的策略,但我不明白是怎么了应该得到的背景下,正确的策略。结果
让我们说明在一个简单的例子:上下文是一个汽车,它有一个IEngine(策略),用2实施方式中,FastEngine和SlowEngine。在code将沿着这些路线看:
I am finally getting my feet wet with Dependency Injection (long overdue); I got started playing with Unity and run into an issue with the strategy pattern. I can use the container to return to me specific implementations of a strategy based on a name, but what I don't see is how I am supposed to get the right strategy in the context.
Let's illustrate on a simple example: the context is a car, which has an IEngine (the strategy), with 2 implementations, FastEngine and SlowEngine. The code would look along these lines:
public interface IEngine
{
double MaxSpeed
{
get;
}
}
internal class FastEngine:IEngine
{
public double MaxSpeed
{
get
{
return 100d;
}
}
}
internal class SlowEngine:IEngine
{
public double MaxSpeed
{
get
{
return 10d;
}
}
}
public class Car
{
private IEngine engine;
public double MaximumSpeed
{
get
{
return this.engine.MaxSpeed;
}
}
public Car(IEngine engine)
{
this.engine = engine;
}
}
我的问题是:我应该如何去实例化一个汽车快速或慢速车?我可以用容器为我提供每个实现,我可以设置一个默认的实现使用:
My problem is the following: how should I go about instantiating a fast car or a slow car? I can use the container to provide me with each implementation, and I can set a "default" implementation to use:
IUnityContainer container = new UnityContainer();
container.RegisterType<IEngine, FastEngine>();
container.RegisterType<IEngine, FastEngine>("Fast");
container.RegisterType<IEngine, SlowEngine>( "Slow" );
var car = container.Resolve<Car>();
Assert.AreEqual(100, car.MaximumSpeed);
但我想是能够请求车与特定战略的实施 - 像
but what I would like is to be able to request a car with a specific implementation of the strategy - something like
var car = container.Resolve<Car>(??? use "Fast" or "Slow ???);
我可以用容器来做到这一点?或者我应该写它使用容器厂?任何指导,将AP preciated - !我不知道我想说得对,这个
Can I use the container to do that? Or should I write a Factory which uses the container? Any guidance would be appreciated - I am not sure I am thinking right about this!
推荐答案
在DI一种常见的模式是在运行时的目前唯一的将是一个单一的实现给定的抽象。这只是让生活轻松许多,因为你不需要处理的模糊性,如你描述的那个。
A common pattern in DI is that at run-time there's only going to be a single implementation of a given abstraction. That just makes life a whole lot easier, as you don't need to deal with the ambiguity such as the one you describe.
但是,有时候,你需要改变基于上下文的实现,比如你给的例子。很多DI容器提供的方式,你可以提供一个合格的参数,但是这意味着你将紧紧结束的code耦合到一个特定的DI容器。
However, sometimes, you need to vary an implementation based on context, such as the example you give. Many DI Containers provide ways where you can provide a qualifying parameter, but that means that you will end up tightly coupling your code to a specific DI Container.
有一个更好的解决方案将是1.产品抽象工厂,可以提供你所需要的。类似
A much better solution would be to introduct an Abstract Factory that can provide what you need. Something like
public interface ICarFactory
{
Car Create(IEngine engine);
}
如果你需要注入更多的战略,也许是构建器设计模式可能适合,甚至更好。
If you need to inject more Strategies, perhaps the Builder design pattern might fit even better.
在任何情况下,该点是,代替在容器中注册了很多不同的汽车的,你就不是注册单个ICarFactory实施
In any case, the point is that instead of registering a lot of different Cars in the container, you would instead register a single ICarFactory implementation.
在您的客户端code,你可以使用注射ICarFactory基于特定IEngine创建汽车实例。
In your client code, you would use the injected ICarFactory to create a Car instance based on a particular IEngine.
var car = factory.Create(engine);
这篇关于策略模式和依赖注入使用Unity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!