点网核心方法注入与控制器方法

时间:2018-08-03 11:25:03

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

假设我在dotnet核心中具有以下控制器:

[Route("api/v1/[controller]")]
public class ValuesController : Controller
{
    private readonly IHandler<ValuesRequest, ValuesResponse> _valueHandler;
    private readonly IHandler<ValuesIdRequest, ValuesIdResponse> _valueIdHandler;

    public ValuesController(IHandler<ValuesRequest, ValuesResponse> valueHandler, 
                            IHandler<ValuesIdRequest, ValuesIdResponse> valueIdHandler)
    {
        _valueHandler = valueHandler;
        _valueIdHandler = valueIdHandler;
    }

    [HttpGet]
    public ValuesResponse Get(ValuesRequest request)
    {
        return _valueHandler.Handle(request);
    }

    [HttpGet("{id}")]
    public ValuesIdResponse Get(ValuesIdRequest request)
    {
        return _valueIdHandler.Handle(request);
    }
}

您可以在上面的代码中看到,我正在通过构造函数使用依赖项注入。但是,我在考虑如何减少代码量。因此,我正在考虑使用方法注入,这应该将代码减少为以下形式:

[Route("api/v1/[controller]")]
public class ValuesController : Controller
{
    [HttpGet]
    public ValuesResponse Get(ValuesRequest request, IHandler<ValuesRequest, ValuesResponse> handler)
    {
        return handler.Handle(request);
    }

    [HttpGet("{id}")]
    public ValuesIdResponse Get(ValuesIdRequest request, IHandler<ValuesIdRequest, ValuesIdResponse> handler)
    {
        return handler.Handle(request);
    }
}

我想知道是否可以结合控制器参数来做类似的事情。我尝试在网上找到答案,但是找不到类似的问题/解决方案。

2 个答案:

答案 0 :(得分:5)

引用Action Injection with FromServices

  

有时候,您不需要为控制器内的多个动作提供服务。在这种情况下,将服务作为操作方法的参数注入可能是有意义的。通过使用属性[FromServices]标记参数来完成此操作,如下所示:

public ValuesResponse Get(ValuesRequest request, [FromServices]IHandler<ValuesRequest, ValuesResponse> handler)
{
    return handler.Handle(request);
}

答案 1 :(得分:3)

虽然在您的操作中使用[FromService]可以解决问题,但我还有另一个建议。

据我所阅读的代码了解,您正在使用某种CQRS。对于这种情况,我可以建议MediatR。然后,您只需要将一个接口注入到控制器中,然后使用IMediator发送请求即可。这样,您将使控制器保持小巧,整洁,并且无需注入其他所有处理程序。

Microsoft IoC容器有一个很好用的extension,可以注册您的所有处理程序以及使用MediatR的所有其他必要的类。

services.AddMediatR(typeof(Startup).Assembly);