我在应用程序中使用.net统一依赖注入框架。
该项目使用了一些“第三方图书馆”(由同一公司的其他团队编写的图书馆)
我以这种方式注册了我的第三方图书馆的一些“汽车”课程:
unityContainer.RegisterType<ICar,Car>();
现在,开发'Car'类的人决定如果构造函数在构造函数中使用布尔值会更好。
当我获得他们库的新版本时,我的代码在运行时断开(我无法检测构建管道中的错误):
解析构造函数Car的参数\“hasRadio \” 解析System.Boolean,(none)\ r \ n“,”exceptionType“:”Microsoft.Practices.Unity.ResolutionFailedException“...
所以我的问题是,你将如何避免这些问题?
引入诸如“永远不会在构造函数中使用原语”这样的规则是最佳实践问题吗?
我的测试覆盖范围不够好吗?例如,当类构造函数包含一些原语时,是否应该检查我的单元依赖关系图的所有类是否都使用InjectionConstructor进行实例化? (我甚至不确定是否可以使用UnityContainer,其Registrations字段不会返回InjectionConstructors)
我是否应该总是从第三方库中明确地实例化类(使用InjectionFactory),以确保在其他团队更改构造函数而不更改我的代码时构建管道失败? (我对这个选项并不满意,因为它违反了依赖注入原则:/)
答案 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。