Azure Triggered Webjobs Scope for Dependency Injection

后端 未结 1 713
攒了一身酷
攒了一身酷 2020-12-10 09:04

I\'ve read and asked some questions on how to use DI using WebJob and especially Triggered Webjobs.

  • SimpleInjector - Azure WebJob with TimerTrigger - Register
相关标签:
1条回答
  • 2020-12-10 09:41

    I've opened an request Add IDependencyScope to handle scoping to the Azure Webjob team.

    I've create a small library to gather classes around Azure Webjobs and SimpleInjector :

    • Nuget download
    • GitHub project

    For QueueTrigger and ServiceBustrigger, I've come accross these solutions :

    • ServiceBusTrigger (from this answer: 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);
              }
          }
      }
      

      You can use your custom MessagingProvider in your JobHostConfiguration like

      var serviceBusConfig = new ServiceBusConfiguration
      { 
          ConnectionString = config.ServiceBusConnectionString
      };
      serviceBusConfig.MessagingProvider = new ScopedMessagingProvider(serviceBusConfig, container);
      jobHostConfig.UseServiceBus(serviceBusConfig);
      
    • QueueTrigger:

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

      You can use your custom IQueueProcessorFactory in your JobHostConfiguration like this:

       var config = new JobHostConfiguration();
       config.Queues.QueueProcessorFactory = new ScopedQueueProcessorFactory(container);
      
    0 讨论(0)
提交回复
热议问题