如何处理依赖注入中的构造函数更改

时间:2016-10-25 17:01:57

标签: c# dependency-injection inversion-of-control unity-container

我在应用程序中使用.net统一依赖注入框架。

该项目使用了一些“第三方图书馆”(由同一公司的其他团队编写的图书馆)

我以这种方式注册了我的第三方图书馆的一些“汽车”课程:

 unityContainer.RegisterType<ICar,Car>();

现在,开发'Car'类的人决定如果构造函数在构造函数中使用布尔值会更好。

当我获得他们库的新版本时,我的代码在运行时断开(我无法检测构建管道中的错误):

解析构造函数Car的参数\“hasRadio \” 解析System.Boolean,(none)\ r \ n“,”exceptionType“:”Microsoft.Practices.Unity.ResolutionFailedException“...

所以我的问题是,你将如何避免这些问题?

引入诸如“永远不会在构造函数中使用原语”这样的规则是最佳实践问题吗?

我的测试覆盖范围不够好吗?例如,当类构造函数包含一些原语时,是否应该检查我的单元依赖关系图的所有类是否都使用InjectionConstructor进行实例化? (我甚至不确定是否可以使用UnityContainer,其Registrations字段不会返回InjectionConstructors)

我是否应该总是从第三方库中明确地实例化类(使用InjectionFactory),以确保在其他团队更改构造函数而不更改我的代码时构建管道失败? (我对这个选项并不满意,因为它违反了依赖注入原则:/)

1 个答案:

答案 0 :(得分:3)

  

引入规则是最佳实践的问题,例如“永远不要在构造函数中使用原语”。 ?

没有。 Primitive dependencies可以像任何其他依赖项一样使用。许多类需要这样的依赖项才能工作。例如,与SMTP服务器通信的类需要服务器的地址和端口。

  

我的测试覆盖范围还不够好吗?

您可以添加更多测试来验证对象图是否可以实际创建,我不确定它有多容易。但是,如果使用Pure DI,则可以在编译时检测到此类问题。

  

我是否应该总是从第三方库中明确地实例化类(使用InjectionFactory),以确保在其他团队更改构造函数而不更改我的代码时构建管道失败?

我认为这里没有规则。如果你愿意,你可以这样做。但是,如果您使用上面提到的Pure DI,您的问题已经解决了。

  

我对此选项并不满意,因为它违反了依赖注入原则

我不认为这违反了依赖性倒置原则。但是,我认为你以不同的方式违反了DIP:

如果正确应用依赖性反转原则,则不应直接使用应用程序类中的ICar抽象,因为它属于第三方组件,而不是您的应用程序。

您应该在应用程序内部定义抽象(在应用程序域的条款中),然后创建适配器以实现使用第三方API的抽象。例如:

namespace MyApplication
{
    public interface IMyCar
    {
        void DoSomething();
    }
}

namespace Adaptors
{
    public class CarAdaptor : MyApplication.IMyCar
    {
        private readonly ThirdParty.ICar car;

        public CarAdaptor(ThirdParty.ICar car) {this.car = car;}

        public void DoSomething() { car.Do3rdPartyThing();}
    }
}

这里要注意的另一件事是,从类Car的名称,这可能是一个新的,而不是注射。您只想注射注射剂。有关详细信息,请参阅this article