Dotnet核心方法注入控制器方法

Gil*_*ian 5 c# dependency-injection .net-core asp.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在上面的代码中看到的,我通过构造函数使用依赖注入.但是,我在考虑如何减少代码量.所以,我正在考虑使用方法注入,这应该将代码减少到这样:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Nko*_*osi 6

使用FromServices引用操作注入

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

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


als*_*ami 5

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

通过阅读您提供的代码,我了解到您使用了某种 CQRS。对于这种情况,我可以建议MediatR。然后,您只需将一个接口注入控制器并使用IMediator发送您的请求。这样,您将保持控制器小而干净,并且不需要注入所有其他处理程序。

Microsoft 的 IoC-Container有一个很好且方便的扩展,可以注册所有处理程序和所有其他必要的类以使用 MediatR。

services.AddMediatR(typeof(Startup).Assembly);
Run Code Online (Sandbox Code Playgroud)