2017-08-04 58 views
1

我试图注入的依赖到控制器内部使用的一类,asp.net核心依赖传球的依赖性沿

//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); 
    } 
} 

这似乎有点多余把它注入到目标班级的家长。这是做事的正确方式吗?

+1

您正在通过在控制器中实例化'Logic'来打破DI模型。让容器为你做。 – DavidG

回答

1

您需要注册Logic,然后将其注入控制器。然后DocumentService将被注入Logic

依赖注入背后的思想是实现IoC(控制反转)原理。在你的例子中,它只是部分的,因为你在你的控制器中明确实例化了Logic。如果你想正确执行依赖反转 - 所有的依赖需要作为构造参数传递。

+0

注入类不是一个好主意(如果你正在进行单元测试)。相反,我会创建接口ILogic,将逻辑实现ILogic并将ILogic注入控制器。 –

+0

@OndrejSvejdar在实际代码中,Logic是少数业务逻辑类之一,它具有不被其他逻辑类共享的特定方法,建议我制作一个一次性界面,以便为每个特定项重复所有方法签名类? –

+0

@Austin_Anderson - 取决于;你想单元测试你的控制器吗?如果是这样,你可能需要模拟逻辑类;嘲笑类是非平凡的问题(他们必须让每一个可模拟的方法都是虚拟的),你也需要调用构造函数。模拟接口非常简单。如果你没有进行单元测试,那就做你想做的事吧:) –

1

您应该在接口后面抽象出Logic,只显示依赖者使用的成员。

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>(); 
} 

所以现在当控制器被调用时,所有的依赖将被解析并注入到它们各自的依赖项中。