用于依赖注入的 Azure 触发 Web 作业范围

Azure Triggered Webjobs Scope for Dependency Injection

我已经阅读并询问了一些有关如何使用 WebJob 尤其是触发 Webjobs 使用 DI 的问题。

我仍在尝试弄清楚如何在触发的网络作业中优雅地集成 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.

我知道我可以在我的触发函数中启动一个范围,但我想知道 sdk 中是否有任何可扩展点允许我们进行范围界定?

谢谢。

我已向 Azure Webjob 团队提出请求 Add IDependencyScope to handle scoping

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

对于 QueueTrigger 和 ServiceBustrigger,我遇到了这些解决方案:

  • ServiceBusTrigger(来自这个答案:):

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