使用 Unity 的策略模式和依赖注入

Posted

技术标签:

【中文标题】使用 Unity 的策略模式和依赖注入【英文标题】:Strategy Pattern and Dependency Injection using Unity 【发布时间】:2010-12-14 22:21:33 【问题描述】:

我终于开始使用依赖注入(姗姗来迟);我开始使用 Unity 并遇到了策略模式的问题。我可以使用容器根据名称返回给我特定的策略实现,但我没有看到我应该如何在上下文中获得正确的策略。 让我们用一个简单的例子来说明:上下文是一辆汽车,它有一个 IEngine(策略),有 2 个实现,FastEngine 和 SlowEngine。代码如下所示:

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;
    

我的问题如下:我应该如何实例化快车或慢车?我可以使用容器为我提供每个实现,我可以设置一个“默认”实现来使用:

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);

但我想要的是能够请求一辆具有特定战略实施的汽车——比如

var car = container.Resolve<Car>(??? use "Fast" or "Slow ???);

我可以使用容器来做到这一点吗?或者我应该写一个使用容器的工厂?任何指导将不胜感激 - 我不确定我的想法是否正确!

【问题讨论】:

【参考方案1】:

DI 中的一个常见模式是在运行时只有一个给定抽象的实现。这只会让生活变得更轻松,因为您不需要处理您所描述的那种模棱两可的情况。

但是,有时,您需要根据上下文(例如您给出的示例)来改变实现。许多 DI 容器提供了可以提供限定参数的方法,但这意味着您最终会将代码紧密耦合到特定的 DI 容器。

一个更好的解决方案是引入一个Abstract Factory,它可以提供你需要的东西。类似的东西

public interface ICarFactory

    Car Create(IEngine engine);

如果您需要注入更多策略,也许Builder 设计模式可能更适合。

无论如何,重点是不要在容器中注册很多不同的 Car,而是注册一个 ICarFactory 实现。

在您的客户端代码中,您将使用注入的 ICarFactory 创建基于特定 IEngine 的 Car 实例。

var car = factory.Create(engine);

【讨论】:

谢谢,有见地的回答。我使用策略模式,在运行时交换多个策略,很多;默认情况下,我会按照您的描述进行操作(工厂或生成器),但我看到策略模式和 DI 有很多关联,尽管这可能会有所帮助。从你所说的来看,容器似乎只是有一点帮助。 我仍然认为容器非常有用。在这些情况下,他们只会注入工厂而不是策略,但我想你仍然可以选择使用容器来实现工厂...... 哦,我想我明白你的意思了;与其归还正确的车,不如根据发动机归还正确的工厂。无论如何,您的评论:用于为抽象提供单一实现的容器非常有帮助;它与我看到的面向配置的示例一致。在那个框架中,你可以有一个策略模式,但一个特定的部署只会配置一个实现。

以上是关于使用 Unity 的策略模式和依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

java23中设计模式之策略模式

策略模式

Unity 2.0 和 .config 中的策略注入

Java学习笔记——对比简单工厂模式和策略模式

Unity HTFramework框架(四十二)进阶篇使用依赖注入(控制反转模式)

Unity HTFramework框架(四十二)进阶篇使用依赖注入(控制反转模式)