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

  • SimpleInjector - Azure WebJob with TimerTrigger - Register IDisposable
  • Dependency injection using Azure WebJobs SDK?

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



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

    谢谢。

    最佳答案

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

    我创建了一个小型库来围绕 Azure Webjobs 和 SimpleInjector 收集类:

  • Nuget download
  • GitHub project

  • 对于 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);
    
  • 关于用于依赖注入(inject)的 Azure 触发的 Webjobs 范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35186456/

    10-11 07:53