如何处理依赖注入中的构造函数变化
How to deal with constructor changes in dependency injection
我在应用程序中使用 .net 统一依赖注入框架。
这个项目使用了一些'third party libraries'(同一公司其他团队编码的库)
我通过这种方式注册了一些 'Car' class 第三方库:
unityContainer.RegisterType<ICar,Car>();
现在,开发 'Car' class 的人决定,如果构造函数在构造函数中采用布尔值会更好。
当我获得他们库的新版本时,我的代码在运行时中断(我无法检测到构建管道中的错误):
解析构造函数Car的参数\"hasRadio\"
解析 System.Boolean,(none)\r\n","exceptionType":"Microsoft.Practices.Unity.ResolutionFailedException"...
所以我的问题是,您将如何设法避免此类问题?
引入诸如 'never use primitives in constructors' 之类的规则是否是最佳实践问题?
是我的测试覆盖率不够好吗?例如,当 class 构造函数包含一些原语时,我是否应该检查我的统一依赖关系图的所有 class 是否都用 InjectionConstructor 实例化? (我什至不确定可以用 UnityContainer 做到这一点,它的 Registrations 字段不返回 InjectionConstructors)
我是否应该始终明确地从第三方库(使用 InjectionFactory)实例化 classes,以确保当其他团队更改构造函数而不更改我的代码时构建管道失败? (我对这个选项不是很满意,因为它有点违反依赖注入原则:/)
Is it a matter of best practices to introduce rules such as 'never use primitives in constructors' ?
没有。 Primitive dependencies 可以像任何其他依赖项一样使用。许多 classes 需要这样的依赖才能工作。例如,与 SMTP 服务器通信的 class 需要服务器的地址和端口。
Is it my test coverage that is not good enough?
您可以添加更多测试来验证是否可以实际创建对象图,我不确定那会有多容易。但是,如果使用Pure DI,则可以在编译时检测到此类问题。
Should I always instantiate classes from third party libraries explicitely (with InjectionFactory), to make sure that build pipeline fails when other team changes constructors without changing my code ?
我认为这里没有规则。如果你愿意,你可以这样做。但是如果你像我上面提到的那样使用Pure DI,你的问题就已经解决了。
I am not really happy with this option as it kind'of violates dependency injection principle
我不认为这违反了依赖倒置原则。但是,我认为您以不同的方式违反了 DIP:
如果您正确应用依赖倒置原则,那么您不应直接使用应用程序 classes 中的 ICar
抽象,因为它属于第 3 方组件,而不是您的应用程序。
您应该在您的应用程序内部定义抽象(根据您的应用程序域),然后创建适配器来实现使用第 3 方的此类抽象 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();}
}
}
这里要注意的另一件事是,从 class Car
的名称来看,这可能是一种新药,而不是注射剂。您只想注射注射剂。有关详细信息,请参阅 this article。
我在应用程序中使用 .net 统一依赖注入框架。
这个项目使用了一些'third party libraries'(同一公司其他团队编码的库)
我通过这种方式注册了一些 'Car' class 第三方库:
unityContainer.RegisterType<ICar,Car>();
现在,开发 'Car' class 的人决定,如果构造函数在构造函数中采用布尔值会更好。
当我获得他们库的新版本时,我的代码在运行时中断(我无法检测到构建管道中的错误):
解析构造函数Car的参数\"hasRadio\" 解析 System.Boolean,(none)\r\n","exceptionType":"Microsoft.Practices.Unity.ResolutionFailedException"...
所以我的问题是,您将如何设法避免此类问题?
引入诸如 'never use primitives in constructors' 之类的规则是否是最佳实践问题?
是我的测试覆盖率不够好吗?例如,当 class 构造函数包含一些原语时,我是否应该检查我的统一依赖关系图的所有 class 是否都用 InjectionConstructor 实例化? (我什至不确定可以用 UnityContainer 做到这一点,它的 Registrations 字段不返回 InjectionConstructors)
我是否应该始终明确地从第三方库(使用 InjectionFactory)实例化 classes,以确保当其他团队更改构造函数而不更改我的代码时构建管道失败? (我对这个选项不是很满意,因为它有点违反依赖注入原则:/)
Is it a matter of best practices to introduce rules such as 'never use primitives in constructors' ?
没有。 Primitive dependencies 可以像任何其他依赖项一样使用。许多 classes 需要这样的依赖才能工作。例如,与 SMTP 服务器通信的 class 需要服务器的地址和端口。
Is it my test coverage that is not good enough?
您可以添加更多测试来验证是否可以实际创建对象图,我不确定那会有多容易。但是,如果使用Pure DI,则可以在编译时检测到此类问题。
Should I always instantiate classes from third party libraries explicitely (with InjectionFactory), to make sure that build pipeline fails when other team changes constructors without changing my code ?
我认为这里没有规则。如果你愿意,你可以这样做。但是如果你像我上面提到的那样使用Pure DI,你的问题就已经解决了。
I am not really happy with this option as it kind'of violates dependency injection principle
我不认为这违反了依赖倒置原则。但是,我认为您以不同的方式违反了 DIP:
如果您正确应用依赖倒置原则,那么您不应直接使用应用程序 classes 中的 ICar
抽象,因为它属于第 3 方组件,而不是您的应用程序。
您应该在您的应用程序内部定义抽象(根据您的应用程序域),然后创建适配器来实现使用第 3 方的此类抽象 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();}
}
}
这里要注意的另一件事是,从 class Car
的名称来看,这可能是一种新药,而不是注射剂。您只想注射注射剂。有关详细信息,请参阅 this article。