具有范围依赖性的.Net Core 2.0 Webjob [英] .Net Core 2.0 Webjob with Scoped Dependencies

查看:123
本文介绍了具有范围依赖性的.Net Core 2.0 Webjob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用IJobActivator设置.Net Core 2.0来构建Webjob。如果作用域是作用域,则IServiceScopeFactory.CreateScope在IJobActivator中似乎不起作用,如果作用域是单例,则在IJobActivator中不起作用。

I am building a webjob with .Net Core 2.0 set up using an IJobActivator. IServiceScopeFactory.CreateScope does not seem to work in the IJobActivator if Functions is scoped, nor within Functions if it's a singleton.

Ie

public static void Main(string[] args)
{
    IServiceCollection serviceCollection = new ServiceCollection();

    serviceCollection.AddScoped<Functions>(); //Or serviceCollection.AddSingleton<Functions>();
    serviceCollection.AddScoped<TelemetryScopeProvider>();
    //... Other scoped dependecies e.g. EF context and repositories.

    var serviceProvider = serviceCollection.BuildServiceProvider(true);

    var jobHostConfiguration = new JobHostConfiguration();
    jobHostConfiguration.Queues.MaxPollingInterval = TimeSpan.FromSeconds(10);
    jobHostConfiguration.Queues.BatchSize = 1;
    jobHostConfiguration.JobActivator = new ProcessorActivator(serviceProvider);
    jobHostConfiguration.UseServiceBus();

    jobHostConfiguration.NameResolver = new QueueNameResolver()
    {
        ResultQueueName = ...
    };

    var config = new JobHostConfiguration();
    var host = new JobHost(jobHostConfiguration);
    host.RunAndBlock();
}

public class ProcessorActivator : IJobActivator
{
    private readonly IServiceProvider _service;
    private IServiceScopeFactory _scopeFactory;

    public ProcessorActivator(IServiceProvider service, IServiceScopeFactory scopeFactory)
    {
        _service = service;
        _scopeFactory = scopeFactory;
    }

    public T CreateInstance<T>()
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var service = _service.GetService(typeof(T));
            return (T)service;
        }
    }

public class Functions
{
    private IServiceScopeFactory _scopeFactory;
    private IServiceProvider _serviceProvider;

    public Functions(IServiceProvider serviceProvider, IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
        _serviceProvider = serviceProvider;
    }

    public async Task ProcessValidationResult([ServiceBusTrigger("%Response%")
 ] string r)
    {
        var start = DateTime.UtcNow;
        using (var scope = _scopeFactory.CreateScope())
        {
            try
            {
                //Deserialize the result.
                var result = JsonConvert.DeserializeObject...;

                var scopeProvider = _serviceProvider.GetService<TelemetryScopeProvider>(); //FAIL HERE

            //Some other Logic which we dont get to
            }
            catch (Exception e)
            {
                Console.Out.WriteLine($"Error processing: {e.Message}");
            }
        }
    }

如果函数的作用域为:异常将在激活器中抛出:无法从根提供者解析范围服务'ValidationResultProcessorWebJob.Functions'。

If Functions is scoped : The exception will be thrown in the activator: Cannot resolve scoped service 'ValidationResultProcessorWebJob.Functions' from root provider.

如果Function是单例:System.InvalidOperationException:无法解析范围服务

If Functions is a singleton: System.InvalidOperationException: Cannot resolve scoped service 'ValidationResultProcessorWebJob.TelemetryScopeProvider' from root provider.

是否不应用_scopeFactory.CreateScope()?是根提供者提供的 ValidationResultProcessorWebJob.TelemetryScopeProvider。为什么不呢?

Is _scopeFactory.CreateScope() not being applied? Why not?

谢谢

韦恩

推荐答案

我错误地认为IServiceScopeFactory提供的功能比它提供的更多。据我目前了解,应该使用IServiceScopeFactory.CreateScope创建子范围。 IServiceScope包含一个ServiceProvider,然后可以使用该ServiceProvider实例化新的依赖关系图。

I mistakenly thought that IServiceScopeFactory was providing more magic than it does. As I currently understand a child scope should be created with IServiceScopeFactory.CreateScope. IServiceScope contains a ServiceProvider which can then be used to instantiate a new graph of dependencies.

我将逻辑从函数移至新的处理器类,并将其配置为Scoped。

I moved the logic from the function to a new processor class and configured it as Scoped.

serviceCollection.AddScoped<Functions>();
serviceCollection.AddScoped<ResponseProcesor>();
//... Other scoped dependecies e.g. EF context and repositories. 

我将IServiceScopeFactory注入WebJobs类(函数)并从中实例化一个新的对象图。

I inject IServiceScopeFactory to the WebJobs class (Functions) and instantiate a new object graph from it.

public class Functions
{
    private IServiceScopeFactory _scopeFactory;

    public Functions(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }

    public async Task ProcessValidationResult([ServiceBusTrigger("%Response%")] string r)
    {
        using (var scope = _scopeFactory.CreateScope())
        {
            var processor = scope.ServiceProvider.GetService<ResponseProcesor>();
            await processor.Process(r);
        }
    }
}

这篇关于具有范围依赖性的.Net Core 2.0 Webjob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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