使用简单注入器在Azure函数中进行DI。

问题描述 投票:0回答:1

我想在Azure Fuctions中使用Simple Injector来注入命令处理程序、ILogger和TelemetryClient。

这是我的Azure函数。

[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;
}

这是我的Bootstrapper类

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

现在我的问题是,我如何在Azure Function中用这个bootstrapper方法解决DI?

我需要在FunctionsStartup中注册bootstrap方法吗?

c# dependency-injection azure-functions simple-injector
1个回答
1
投票

使用Simple Injector,你不会将服务注入到Azure Function中。不支持这样做。取而代之的是 整合指南 解释了这一点。

与其将服务注入Azure函数中,不如将所有业务逻辑从Azure函数中移出,移入一个应用程序组件。函数的依赖关系可以成为组件的构造函数的参数。这个组件可以从Azure函数内部进行解析和调用。

对于您的特定案例,这意味着执行以下步骤。

1. 将所有业务逻辑从Azure函数中移出,移到一个应用组件中。函数的依赖关系可以成为组件的构造函数的参数。

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 这个组件可以从Azure函数内部进行解析和调用。

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

    // Invoke the service
    service.Run(req);
}

3. 最后的步骤

要完成配置,您必须确保(新)静态的 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.
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.