Azure 触发的 Webjobs 依赖项注入(inject)范围

标签 azure dependency-injection azure-webjobs azure-webjobssdk

我已阅读并询问了一些有关如何通过 WebJob 特别是触发式 Webjobs 使用 DI 的问题。

我仍在尝试弄清楚如何在触发的 webjobs 中优雅地集成 DI,@Steven 问了我一个很好的问题:

Isn't there a way to wrap the execution of your service in some scope? For instance, MVC and Web API have an IDependencyScope abstraction for this. This notifies the starting and ending of a request. To be able to do scoping, you either need to have such interception point or you need to be able to wrap the call to JobActivator.

我知道我可以在触发函数内启 Action 用域,但我想知道 sdk 中是否有任何可扩展点允许我们进行作用域界定?

谢谢。

最佳答案

我已打开一个请求 Add IDependencyScope to handle scoping致 Azure Webjob 团队。

我创建了一个小型库来收集有关 Azure Webjobs 和 SimpleInjector 的类:

对于 QueueTrigger 和 ServiceBustrigger,我遇到过以下解决方案:

  • ServiceBusTrigger(来自此答案:https://stackoverflow.com/a/33759649/4167200):

    public sealed class ScopedMessagingProvider : MessagingProvider
    {
        private readonly ServiceBusConfiguration _config;
        private readonly Container _container;
    
        public ScopedMessagingProvider(ServiceBusConfiguration config, Container container)
            : base(config)
        {
            _config = config;
            _container = container;
        }
    
        public override MessageProcessor CreateMessageProcessor(string entityPath)
        {
            return new ScopedMessageProcessor(_config.MessageOptions, _container);
        }
    
        private class ScopedMessageProcessor : MessageProcessor
        {
            private readonly Container _container;
    
            public ScopedMessageProcessor(OnMessageOptions messageOptions, Container container)
                : base(messageOptions)
            {
                _container = container;
            }
    
            public override Task<bool> BeginProcessingMessageAsync(BrokeredMessage message, CancellationToken cancellationToken)
            {
                _container.BeginExecutionContextScope();
                return base.BeginProcessingMessageAsync(message, cancellationToken);
            }
    
            public override Task CompleteProcessingMessageAsync(BrokeredMessage message, FunctionResult result, CancellationToken cancellationToken)
            {
                _container.GetCurrentExecutionContextScope()?.Dispose();
                return base.CompleteProcessingMessageAsync(message, result, cancellationToken);
            }
        }
    }
    

    您可以在 JobHostConfiguration 中使用自定义 MessagingProvider,例如

    var serviceBusConfig = new ServiceBusConfiguration
    { 
        ConnectionString = config.ServiceBusConnectionString
    };
    serviceBusConfig.MessagingProvider = new ScopedMessagingProvider(serviceBusConfig, container);
    jobHostConfig.UseServiceBus(serviceBusConfig);
    
  • 队列触发器:

    public sealed class ScopedQueueProcessorFactory : IQueueProcessorFactory
    {
        private readonly Container _container;
    
        public ScopedQueueProcessorFactory(Container container)
        {
            _container = container;
        }
    
        public QueueProcessor Create(QueueProcessorFactoryContext context)
        {
            return new ScopedQueueProcessor(context, _container);
        }
    
        private class ScopedQueueProcessor : QueueProcessor
        {
            private readonly Container _container;
    
            public ScopedQueueProcessor(QueueProcessorFactoryContext context, Container container)
                : base(context)
            {
                _container = container;
            }
    
            public override Task<bool> BeginProcessingMessageAsync(CloudQueueMessage message, CancellationToken cancellationToken)
            {
                _container.BeginExecutionContextScope();
                return base.BeginProcessingMessageAsync(message, cancellationToken);
            }
    
            public override Task CompleteProcessingMessageAsync(CloudQueueMessage message, FunctionResult result,
                CancellationToken cancellationToken)
            {
                _container.GetCurrentExecutionContextScope()?.Dispose();
                return base.CompleteProcessingMessageAsync(message, result, cancellationToken);
            }
        }
    }
    

    您可以在 JobHostConfiguration 中使用自定义 IQueueProcessorFactory,如下所示:

     var config = new JobHostConfiguration();
     config.Queues.QueueProcessorFactory = new ScopedQueueProcessorFactory(container);
    

关于Azure 触发的 Webjobs 依赖项注入(inject)范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35186456/

相关文章:

azure - 如何获取 azure devops 项目项目管理员组的成员

java - Java ServiceLoader 在开发期间如何工作? (构建 JAR 之前的单元测试?)

azure - 使用 AzureWebJobsSDK ErrorTrigger 扩展进行错误监视不起作用

dependency-injection - 在 Kotlin 的 Injekt 库中,如何注入(inject)函数而不仅仅是值?

java - 如何重新初始化我的 bean

powershell - 获取 AzureWebsiteJob : No default subscription has been designated

asp.net - 无法将调试器从 VS 2017 连接到 ASP.NET CORE 2.2.1 应用程序的 Azure 应用程序服务

git - 在触发器上从 GitLab 存储库发布到 Azure Web Apps

azure - 从 msal 登录获取资源管理器访问 token