如何使用手动依赖注入实例化一个类?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用手动依赖注入实例化一个类?相关的知识,希望对你有一定的参考价值。
我有一个可能需要服务的类,以前通过依赖注入注册,具体取决于用户需求。
他通过静态方法GetInstance(bool)
实现我的类,如果bool
设置为true,那么我需要根据依赖注入调用构造函数。怎么做到这一点?
public class MyClass {
private MyClass() {
// ...
}
private MyClass(MyService env) {
// ...
}
public static MyClass GetInstance(bool serviceIsNeeded) {
if (serviceIsNeeded) {
/* How to realize the following ?
* if (!ServiceRegistered<MyService>())
* throw new ServiceNotFoundException(...);
* return InstanciateWithDependencyInjection(typeof(MyClass));
*/
}
else
return new MyClass();
}
}
例如在Java中,你在构造函数的顶部放置一个@Inject标记,然后你就像这样实现你的类:MyClass myClass = getInjector(getContext()).getInstance(MyClass.class)
我在C#和ASP.NET Core 2中寻找相同的概念。
Tl; Dr我认为你的方向是错误的。这几乎是Service Locator (anti) pattern。
您应该尝试使用DI框架上下集成DI构建底层类,然后其他所有内容都接受依赖项。还有一个论点要说,“如果你注入一个类并且不使用它,为什么这很重要?”。提供该类没有构造开销(它不应该)只是注入并使用它。
所以你的课应该看起来像:
public class MyClass {
//inject all the dependencies
private MyClass(MyService env) {
// ...
}
}
很好,很简单。
服务定位器往往会导致组件过于紧密耦合。例如,在你的问题代码中,你如何对GetInstance
进行单元测试?这很棘手,你不能注射嘲笑等。
DI的重点是将组件分离,以提高灵活性并简化单元测试。
我曾经有一个UnitTest项目,该项目引用了一个虚拟Web应用程序,用于注册所有必需的服务
看到这不是很好的测试,我会说你的测试会很快变得臃肿,难以维护。上面的地方很容易使用模拟引擎等进行测试。如果你改变x
,你不希望它影响y
的测试。
我会保持MyClass清晰并将依赖放在构造函数中。如果构造函数无法解析此依赖项,则创建将手动创建对象的工厂类。像这样的东西:
public class MyClassFactory{
public MyClass Create(){
// insetead of manualy creating depenedecy service locator can be
// used
return new MyClass(new MyService());
}
}
public class MyClass{
public MyClass(MyService myService){}
}
public class MyService {
}
以上是关于如何使用手动依赖注入实例化一个类?的主要内容,如果未能解决你的问题,请参考以下文章