Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# asp.net核心依赖项传递依赖项_C#_Asp.net Core - Fatal编程技术网

C# asp.net核心依赖项传递依赖项

C# asp.net核心依赖项传递依赖项,c#,asp.net-core,C#,Asp.net Core,我试图将依赖注入控制器内部使用的类中 我有 //Startup.cs public void ConfigureServices(IServiceCollection services){ services.AddMvc();//IDocumentService is a WCF service from our legacy stack services.AddScoped(typeof(IDocumentService),typeof(DocumentServiceClien

我试图将依赖注入控制器内部使用的类中

我有

//Startup.cs
public void ConfigureServices(IServiceCollection services){
    services.AddMvc();//IDocumentService is a WCF service from our legacy stack
    services.AddScoped(typeof(IDocumentService),typeof(DocumentServiceClient));
}
//Controller.cs
[Route("api/eci/test/[action]")]
public class Controller{
    private IDocumentService injectedDocService;
    public Controller(IDocumentService client){
        injectedDocService=client;
    }
    [HttpPost({"id"})]
    public void ingestedDocs(string id){
        new Logic(injectedDocService).ingest(id);
    }
}
//Logic.cs
public class Logic{
    private IDocumentService injectedDocServiceActualTarget;
    public Logic(IDocumentService injected2){
        injectedDocServiceActualTarget=injected2;
    }
    public void injest(string id){
        injectedDocServiceActualTarget.doWork(id);
    }
}

将其注入目标类的父类似乎有点多余。这是正确的方法吗?

您需要注册
逻辑,然后将其注入控制器<代码>文档服务
将被注入
逻辑


依赖注入背后的思想是实现IoC(控制反转)原则。在您的示例中,它只是部分的,因为您在控制器中显式地实例化了
逻辑。如果您想正确地执行依赖项反转,那么所有依赖项都需要作为构造函数参数传递。

您应该在接口后面抽象
逻辑,只公开依赖项使用的成员

public interface ILogic {
    void injest(string id);
}
让逻辑类派生自抽象

//Logic.cs
public class Logic : ILogic {
    private readonly IDocumentService injectedDocServiceActualTarget;

    public Logic(IDocumentService injected2) {
        this.injectedDocServiceActualTarget=injected2;
    }

    public void injest(string id) {
        injectedDocServiceActualTarget.doWork(id);
    }
}
控制器现在应该只显式地依赖于
ILogic
接口

//Controller.cs
[Route("api/eci/test/[action]")]
public class Controller {
    private readonly ILogic service;

    public Controller(ILogic service) {
        this.service = service;
    }

    [HttpPost({"id"})]
    public void ingestedDocs(string id) {
        service.ingest(id);
    }
}
因此,最后要做的事情是向服务集合注册所有依赖项

//Startup.cs
public void ConfigureServices(IServiceCollection services){
    services.AddMvc();
    services.AddScoped<IDocumentService, DocumentServiceClient>();
    services.AddScoped<ILogic, Logic>();
}
//Startup.cs
public void配置服务(IServiceCollection服务){
services.AddMvc();
services.addScope();
services.addScope();
}

因此,现在当调用控制器时,所有依赖项都将被解析并注入各自的依赖项。

通过在控制器中实例化
逻辑
,您正在破坏DI模型。让容器来为你做吧。注入类不是一个好主意(如果你正在进行单元测试的话)。我将创建接口ILogic,让逻辑实现ILogic,并将ILogic注入控制器。@OndrejSvejdar在实际代码中,逻辑是少数几个具有其他逻辑类不共享的特定方法的业务逻辑类之一,是否建议我创建一个一次性接口,用于复制每个特定类的所有方法签名?@Austin_Anderson-depends;是否要对控制器进行单元测试?如果是这样,您可能需要模拟逻辑类;模拟类是一个非常重要的问题(它们必须使每个可模拟的方法都是虚拟的),您还需要调用构造函数。模拟接口非常简单。如果您不进行单元测试,那么做您想做的:)@OndrejSvejdar此体系结构中的逻辑类的要点是,没有任何可测试逻辑直接进入控制器,相反,我们有一个包含所有代码的业务逻辑层,以及一个只调用业务逻辑层的控制层。也许这是一个不必要的抽象,因为我们有依赖注入,但这是团队决定的。tl;博士,我们可能不会测试控制器,只是测试逻辑classes@OndrejSvejdar在不了解上下文的情况下进行判断从来都不是一个好主意。虽然我大体上同意你的看法,但这超出了这个问题的范围。有时,您有一个无状态的单例(因此名为
Logic
,这就意味着),它没有模拟/伪造的意义,您可以完美地注入它。
public interface ILogic {
    void injest(string id);
}