依赖注入的Azure触发的Webjobs范围 [英] Azure Triggered Webjobs Scope for Dependency Injection

查看:59
本文介绍了依赖注入的Azure触发的Webjobs范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

我仍然尝试找出如何在触发的webjobs中正确集成DI,@ Steven向我提出了一个好问题:

I still try to figure out how to integrate gracefully DI in triggered webjobs and @Steven asked me a good question :

在某种范围内没有办法包装服务的执行吗?例如,MVC和Web API为此具有 IDependencyScope 抽象.这会通知请求的开始和结束.为了能够进行范围界定,您要么需要具有这样的拦截点,要么就需要将对呼叫的包装到JobActivator中.

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中是否有任何可扩展的点可以进行作用域确定?

I know that I can start a scope inside my triggered function but I would like to know if there are any point of extensibility in the sdk that allow us to do scoping ?

谢谢.

推荐答案

我已经打开了一个请求向Izure Webjob团队添加IDependencyScope来处理作用域.

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

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

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

  • Nuget download
  • GitHub project

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

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

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,例如

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:

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

    您可以像这样在JobHostConfiguration中使用自定义IQueueProcessorFactory:

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

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

  • 这篇关于依赖注入的Azure触发的Webjobs范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆