代码之家  ›  专栏  ›  技术社区  ›  Adiel Yaacov

依赖注入模式下设计的基本原则是什么

  •  3
  • Adiel Yaacov  · 技术社区  · 14 年前

    我使用Unity应用程序块2.0作为我的DI框架。

    对于这些问题:

    1. 假设我有一个名为IDevice的硬件设备接口。 一些硬件侦听器接收到这样的IDevice。 现在假设您有几个实现IDevice的硬件设备和几个侦听器。 您需要为每个侦听器指定要注入的实际设备。

    一个可行的解决方案是为每个实际设备创建另一个抽象级别 喜欢

    public interface IActualDevice : IDevice
    {}
    
    public ActualDevice : IActualDevice
    {}
    
    public SimulatedActualDevice : IActualDevice
    {}
    
    public OtherAcualDevice: IOtherAcualDevice
    {}
    

    那么就有可能创建这样的映射:

    container.RegisterType<IActualDevice, ActualDevice>()
    

    container.RegisterType<IActualDevice, SimulatedActualDevice>()
    

    你觉得这个设计好吗?

    1. DI模式为我们提供了良好的对象创建机制。

    胶水呢,对象之间的事件订阅呢?

    你不认为它丢失了吗?或者我丢失了一些支持它的统一特性。

    2 回复  |  直到 14 年前
        1
  •  3
  •   Community CDub    7 年前

    没有必要引入标记接口来让您的DI容器工作——这将是一个很好的选择

    使用Unity,您可以用自己的IDevice实现配置每个侦听器,如下所示:

    container.RegisterType<IDevice, ActualDevice>("actual");
    container.RegisterType<IDevice, OtherActualDevice>("otherActual");
    
    container.RegisterType<IListener, Listener1>("listener1",
        new InjectionConstructor(
            new ResolvedParameter<IDevice>("actual")));
    container.RegisterType<IListener, Listener2>("listener2",
        new InjectionConstructor(
            new ResolvedParameter<IDevice>("otherActual")));
    

    var listener1 = container.Resolve<IListener>("listener1");
    var listener2 = container.Resolve<IListener>("listener2");
    

    一般来说,DI的核心模式是 抽象工厂 . 大多数其他事情都是从这两个方面来的。看到了吗 this answer

        2
  •  -2
  •   Yauheni Sivukha    14 年前

    1) 这完全是个坏主意,因为接口旨在隐藏实现的细节。随处使用IDevice类型并手动注入此依赖项

    IDevice d;
    
    if(a == 1)
    {
       d = container.Resolve<SimulatedActualDevice>()
    }
    else
    {
       d = container.Resolve<ActualDevice>()
    }
    
    User user = container.Resolve<IUser>();
    user.Device = d;
    

    如果不想在代码中使用实现类名,请使用命名注册:

    IDevice d;
    
    if(a == 1)
    {
       d = container.Resolve<IDevice>("Simulated")
    }
    else
    {
       d = container.Resolve<IDevice>("Actual")
    }
    
    User user = container.Resolve<IUser>();
    user.Device = d;
    

    2) 对象之间的事件订阅是对象初始化的一部分,而不是创建的一部分。Unity只是封装了“新”操作符。像使用DI容器之前一样,在构造函数或特殊工厂中进行订阅。