代码之家  ›  专栏  ›  技术社区  ›  Mathias

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

  •  23
  • Mathias  · 技术社区  · 16 年前

    我终于被依赖注射(早该注射)弄湿了脚;我开始玩Unity,遇到了战略模式的问题。我可以使用容器返回基于名称的策略的特定实现,但我不知道如何在上下文中获得正确的策略。
    让我们用一个简单的例子来说明:上下文是一辆汽车,它有一个IEEngine(策略),有两个实现,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 回复  |  直到 16 年前
        1
  •  28
  •   Mark Seemann    16 年前

    DI中的一个常见模式是 一个给定抽象只有一个实现。这只会让生活变得更简单,因为你不需要处理你所描述的模糊性。

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

    一个更好的解决办法是引入 Abstract Factory 这可以提供你所需要的。差不多

    public interface ICarFactory
    {
        Car Create(IEngine engine);
    }
    

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

    在任何情况下,要点是,您不需要在容器中注册许多不同的汽车,而需要注册单个ICarFactory实现。

    var car = factory.Create(engine);
    
    推荐文章