简体   繁体   English

Azure Function 中的 DI 使用简单注射器

[英]DI in Azure Function using Simple Injector

I want to use Simple Injector to inject command handlers, ILogger and TelemetryClient in Azure Fuctions.我想使用 Simple Injector 在 Azure Fuctions 中注入命令处理程序、ILogger 和 TelemetryClient。

Here is my Azure Function:这是我的 Azure Function:

[FunctionName("ReceiveEvent")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
    ILogger log,
    ICommandMapper commandMapper,
    ICommandValidator commandValidator,
    ICommandHandlerService commandHandlerService)
{
    log.LogInformation("ReceiveEvent HTTP trigger function started processing request.");

    IActionResult actionResult = null;

    string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

    var command = await commandMapper.Map(requestBody);

    if (commandValidator.Validate(req, command, ref actionResult))
    {
        //TODO
        commandHandlerService.HandleCommand(command);
        return actionResult;
    }

    return actionResult;
}

Here is my Bootstrapper class:这是我的引导程序 class:

public class Bootstrapper
{
    public static void Bootstrap(IEnumerable<Assembly> assemblies = null, bool verifyContainer = true)
    {
        Container container = new Container();

        container.Register(typeof(ICosmosDBRepository<>), typeof(CosmosDBRepository<>).Assembly);
        container.Register(typeof(IAzureBlobStorage), typeof(AzureBlobStorage).Assembly);
        container.Register(typeof(ICommandMapper), typeof(CommandMapper).Assembly);
        container.Register(typeof(ICommandValidator), typeof(CommandValidator).Assembly);
        container.Register(typeof(ICommandHandlerService), typeof(CommandHandlerService).Assembly);

        List<Assembly> myContextAssemlies = new List<Assembly>
            {
                 Assembly.GetAssembly(typeof(CardBlockCommandHandler)),
            };

        container.Register(typeof(ICommandHandler), myContextAssemlies, Lifestyle.Scoped);

        assemblies = assemblies == null
            ? myContextAssemlies
            : assemblies.Union(myContextAssemlies);

        if (verifyContainer)
        {
            container.Verify();
        }
    }
}

Now my question is, how I'll resolve the DI with this bootstrapper method in Azure Function?现在我的问题是,我将如何在 Azure Function 中使用这种引导程序方法解决 DI?

Do I need to register bootstrap method in FunctionsStartup?我需要在 FunctionsStartup 中注册引导方法吗?

With Simple Injector, you don't inject services into the Azure Function.使用 Simple Injector,您不会将服务注入 Azure Function。 This is not supported.这是不支持的。 Instead, the integration guide explains that:相反,集成指南解释说:

Instead of injecting services into a Azure Function, move all the business logic out of the Azure Function, into an application component. Instead of injecting services into a Azure Function, move all the business logic out of the Azure Function, into an application component. The function's dependencies can become arguments of the component's constructor.函数的依赖可以变成组件构造函数的arguments。 This component can be resolved and called from within the Azure function.该组件可以在 Azure function 中解析和调用。

For your particular case, this means executing the following steps:对于您的特定情况,这意味着执行以下步骤:

1. move all the business logic out of the Azure Function, into an application component. 1.将所有业务逻辑移出Azure Function,到一个应用组件中。 The function's dependencies can become arguments of the component's constructor.函数的依赖可以变成组件构造函数的arguments。

public sealed class ReceiveEventFunction
{
    private readonly ILogger log;
    private readonly ICommandMapper commandMapper;
    private readonly ICommandValidator commandValidator;
    private readonly ICommandHandlerService commandHandlerService;

    public ReceiveEventFunction(ILogger log, ICommandMapper commandMapper,
        ICommandValidator commandValidator, ICommandHandlerService commandHandlerService)
    {
        this.log = log;
        this.commandMapper = commandMapper;
        this.commandValidator = commandValidator;
        this.commandHandlerService = commandHandlerService;
    }
    
    public async Task<IActionResult> Run(HttpRequest req)
    {
        IActionResult actionResult = null;

        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();

        var command = await commandMapper.Map(requestBody);

        if (commandValidator.Validate(req, command, ref actionResult))
        {
            commandHandlerService.HandleCommand(command);
            return actionResult;
        }

        return actionResult;    
    }
}

2 This component can be resolved and called from within the Azure function. 2 该组件可以在 Azure function 中解析和调用。

[FunctionName("ReceiveEvent")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req)
{
    // Resolve the service
    var service = Bootstrapper.Container.GetInstance<ReceiveEventFunction>();
    
    // Invoke the service
    service.Run(req);
}

3. Final steps 3. 最后步骤

To complete the configuration, you will have to ensure the (new) static Bootstrapper.Container field exists, and that ReceiveEventFunction is registered:要完成配置,您必须确保(新)static Bootstrapper.Container字段存在,并且ReceiveEventFunction已注册:

public class Bootstrapper
{
    public static readonly Container Container;

    static Bootstrapper()
    {
        Container = new Bootstrapper().Bootstrap();
    }

    public static void Bootstrap(
        IEnumerable<Assembly> assemblies = null, bool verifyContainer = true)
    {
        Container container = new Container();

        container.Register<ReceiveEventFunction>();

        ... // rest of your configuration here.
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM