依赖注入和 Mediatr 与 Azure Functions 结合使用是否效率低下?

yes*_*man 5 c# azure mediatr azure-functions

我正处于 Azure 之旅的早期阶段。我理解函数的方式是,它们是一种无服务器解决方案,仅在实际需要时运行。在执行了他们的逻辑之后,他们再次“关闭”。与应用服务之类的东西相比,即使没有请求,它也始终在运行,这更便宜。

我目前的情况:我有一个采用 DDD 设计的解决方案,类似于 Microsoft 的 eshoponcontainers 解决方案。我有一个 webapi 项目,只有超薄控制器,只需将输入传递给 Mediatr,Mediatr 将其传递给不同的项目以进行验证和业务逻辑。我所有的控制器方法如下所示:

[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetById(string id)
{
    // Mediator instantiated via DI in the controller constructor
    var result = await Mediator.Send(new GetByIdQuery { Id = id });
    return Ok(result);
}
Run Code Online (Sandbox Code Playgroud)

对我来说,删除此 webapi 项目并将其替换为 Azure Functions 项目很简单,该项目也从 HTTP 触发器获取输入并将其传递给 Mediatr。我的依赖项注入内容是在另一个项目中设置的,独立于 webapi,因此也可以轻松插入到我的 Azure Functions 项目中。我所有的功能都是这样的:

public class GetId
{
    private readonly IMediator _mediator;

    public GetId(IMediator mediator)
    {
        _mediator = mediator;
    }

    [FunctionName("GetById")]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] string id,
        ILogger log)
    {
        var result = await _mediator.Send(new GetByIdQuery { AgreementId = id });
        return new OkObjectResult(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

但从成本角度来看,这不是很糟糕吗?根据我有限的理解,每次启动 Azure Function 时,它都会重新创建我的大量 DI 容器。这意味着我为进行 DI 设置的 CPU 时间(而不是我的实际业务逻辑)付出了很多代价。或者我错过了什么?

Ian*_*emp 3

撇开 Web API 与 Azure Functions 的讨论不谈,您所做的事情相当奇怪:接受消息,以便您可以使用 Mediatr 根据该消息的内容手动触发事件。

Azure 已经为此提供了内置功能:事件网格、事件中心或服务总线。创建这些资源之一,将事件/消息发布到它们而不是 Web API/Azure Functions,并将 Mediatr 事件侦听器替换为事件网格/事件中心/服务总线侦听器。那么您根本不需要 Web API 或 Azure Functions。

关于实际问题,Azure Functions 带来了很多担忧 - 无法使用 ASP.NET Core 中间件是一个大问题。您可能会节省资源使用量,但说实话,Azure 非常便宜,因此这样的节省可能不值得。(我建议您查看实际定价,而不是假设 Azure Functions 会为您节省金钱,因为它并不总是在线。)不,DI 容器构建根本不会花费太多 CPU - 如果需要,您有更大的架构问题。

总是有取舍的,没有什么是免费的。