如何使用手动依赖注入实例化一个类?

时间:2018-02-27 10:52:16

标签: c# asp.net-core dependency-injection

我有一个可能需要服务的类,以前通过依赖注入注册,具体取决于用户需求。

他通过静态方法bool实现我的类,如果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(); } } 设置为true,那么我需要根据依赖注入调用构造函数。怎么做到这一点?

MyClass myClass = getInjector(getContext()).getInstance(MyClass.class)

例如在Java中,你在构造函数的顶部放置一个@Inject标记,然后你就像这样实现你的类:directives : [CeiboShare]

我在C#和ASP.NET Core 2中寻找相同的概念。

2 个答案:

答案 0 :(得分:2)

是的,我认为你在这里走错了路。这几乎是Service Locator (anti) pattern

你应该尝试使用DI框架上下整合DI构建底层类,然后其他一切只接受依赖。还有一个论据要说,&#34;如果你注入一个课程并且不使用它,为什么重要?&#34;。提供该类没有施工开销(它不应该)只是注入并使用它。

所以你的课应该看起来像:

public class MyClass {

  //inject all the dependencies
  private MyClass(MyService env) {
    // ...
  }


}

美好而简单。

服务定位器往往会导致组件过于紧密耦合。例如,在问题的代码中,您如何对GetInstance进行单元测试?这很棘手,你不能注射嘲笑等等。

DI的重点是将组件分离,以提高灵活性并简化单元测试。

  

我曾经有一个UnitTest项目,它引用了一个虚拟Web应用程序   注册所有必需的服务

看到这不是很好的测试,我说你的测试会很快变得臃肿,难以维护。上述内容很容易使用模拟引擎等进行测试。如果您更改x,则不希望它影响y的测试。

答案 1 :(得分:-2)

我会保持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 {

}