【问题标题】:How to deal with constructor changes in dependency injection如何处理依赖注入中的构造函数变化
【发布时间】:2017-03-07 20:09:56
【问题描述】:

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

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

我以这种方式注册了我的第三方库的一些“汽车”类:

 unityContainer.RegisterType<ICar,Car>();

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

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

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

所以我的问题是,您将如何避免此类问题?

引入诸如“不要在构造函数中使用原语”之类的规则是否是最佳实践?

是不是我的测试覆盖率不够好?例如,当类构造函数包含一些原语时,我是否应该检查我的统一依赖图的所有类是否都使用 InjectionConstructor 实例化? (我什至不确定是否可以使用 UnityContainer 来做到这一点,它的 Registrations 字段不会返回 InjectionConstructors)

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

【问题讨论】:

  • 是的,你的单元测试覆盖率不够好——你应该有单元测试来检查类型是否可以像生产代码那样实例化(在你的情况下是通过 Unity),因此正在改变新库的版本应该在构建时被拒绝...您将如何解决其他库不方便您选择的 DI 容器这一事实取决于您...(您显然看到 stackoverflow.com/questions/787001/… 传递构造函数参数。 ..)

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


【解决方案1】:

引入诸如“不要在构造函数中使用原语”之类的规则是否是最佳实践?

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

是不是我的测试覆盖率不够好?

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

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

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

我对这个选项不太满意,因为它有点违反依赖注入原则

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

如果您正确地应用了依赖倒置原则,那么您不应该直接从您的应用程序类中使用ICar 抽象,因为它属于第 3 方组件,而不是您的应用程序。

您应该在应用程序内部定义抽象(根据应用程序域),然后创建适配器来实现使用 3rd 方 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

【讨论】:

    猜你喜欢
    • 2013-01-30
    • 2011-02-02
    • 2018-06-17
    • 1970-01-01
    • 2011-07-05
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多