【问题标题】:How to instantiate an object with a reference to another object that depends on DI ASP.NET core 2.0?如何使用对依赖于 DI ASP.NET core 2.0 的另一个对象的引用来实例化一个对象?
【发布时间】:2019-02-16 10:22:18
【问题描述】:

我有一个控制器的构造函数,我想在其中实例化一个可以通过依赖注入访问存储库的对象。

像这样:

ContactController.cs:我收到一个错误,因为我没有传递 IContactRepository

private ContactOperationsFacade contactOperator;

ContactController(){
    contactOperator = new ContactOperationsFacade(//I want to use DI here);
}

ContactOperationsFacade.cs:

private readonly IContactRepository contactRepository;

public ContactOperationsFacade(IContactRepository contactRepositor){
    this.contactRepository = contactRepository;
}

如何在控制器的构造函数中实例化这个 ContactOperationsFacade 对象,仍然使用 DI 作为存储库?

【问题讨论】:

  • 只需将IContactRepository 注入控制器并在新建外观时使用它。
  • 然后在 IoC 容器中注册 ContactOperationsFacade 并注入它,或者使用服务定位器,但这是一种反模式:stackoverflow.com/questions/32459670/… 基本上是 @JSteward 在下面所说的
  • 你可以注入你正在使用的任何 DI 容器。但是为什么你不能注入 ContactOperationsFacade 而不是更新它呢?
  • 对不起。我实际上误读了评论。您不需要控制器依赖于IContactRespository,但它确实依赖于ContactOperationsFascade。因此,它应该被注入到你的构造函数中,而不是在构造函数中更新它。
  • 所有依赖项应该被注入。所以,是的,控制器的依赖关系也适用。

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


【解决方案1】:

在 asp.net core 中,只要范围允许,您就可以进行 DI 链接。因此,如果 A 依赖于 B 并且控制器想要 A,您只需将 A 和 B 添加到 di 容器(代码的 ConfigurationServices 部分),容器就会弄清楚。

在此处阅读更多信息https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1

【讨论】:

    【解决方案2】:

    ContactController 应该关注The Explicit Dependencies Principle

    方法和类应该明确要求(通常通过方法参数或构造函数参数)它们需要的任何协作对象才能正常运行。

    此外,类应该依赖于抽象,而不是耦合到具体。

    所以假设像

    public class ContactOperationsFacade: IContactOperationsFacade { //<-Note interface/contract
    
        private readonly IContactRepository contactRepository;
    
        public ContactOperationsFacade(IContactRepository contactRepositor){
            this.contactRepository = contactRepository;
        }
    
        //...
    }
    

    控制器应该依赖于外观派生的抽象

    public class ContactController: Controller {
    
        private readonly IContactOperationsFacade contactOperator;
    
        public ContactController(IContactOperationsFacade contactOperator){
            this.contactOperator = contactOperator;
        }
    
        //...
    
    }
    

    并假设所有接口和实现都注册到 DI 容器中。

    services.AddScoped<IContactOperationsFacade, ContactOperationsFacade>();
    

    一旦注册了所有依赖项,服务提供者应该在激活控制器时解决它们。

    【讨论】:

    • 我可以毫无问题地将 IContactRepository 注入我的控制器,所以。为什么我不能将 IContactRepository 注入到我的 IContactOperationsFacade 中?我有很多类似的类,比如 ContactOperationsFacade,我不想只注入所有这些类。我正在尝试编写易于单元测试的代码(通过使我的方法没有任何外部依赖项,只有原始类型)而不滥用 DI @Nkosi
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-13
    • 2017-01-16
    • 1970-01-01
    • 2020-01-25
    • 2017-03-13
    • 2017-02-25
    相关资源
    最近更新 更多