【问题标题】:.Net Core 2.0 Webjob with Scoped Dependencies.Net Core 2.0 具有范围依赖关系的 Webjob
【发布时间】:2018-06-07 02:31:23
【问题描述】:

我正在构建一个使用 IJobActivator 设置的 .Net Core 2.0 网络作业。如果 Functions 是作用域的,IServiceScopeFactory.CreateScope 似乎在 IJobActivator 中不起作用,如果它是单例,在 Functions 中也不起作用。

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

如果 Functions 是作用域的:将在激活器中引发异常:Cannot resolve scoped service 'ValidationResultProcessorWebJob.Functions' from root provider。

如果 Functions 是单例:System.InvalidOperationException:无法从根提供程序解析范围服务“ValidationResultProcessorWebJob.TelemetryScopeProvider”。

_scopeFactory.CreateScope() 没有被应用吗?为什么不呢?

谢谢,

韦恩

【问题讨论】:

  • 您的ProcessorActivator 需要IServiceScopeFactory 才能被实例化。正在编译吗?
  • 它编译并运行。使用 serviceCollection.BuildServiceProvider(false) 它通常会运行一段时间,但是重用 dbcontext 最终会导致错误。我相信 IServiceScopeFactory 是在容器中自动配置的,因为我得到了一个非空对象。我的代码是一堆 sn-ps,所以可能存在复制和粘贴问题。

标签: asp.net dependency-injection .net-core azure-webjobs asp.net-core-2.0


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 2018-12-24
    • 2018-03-03
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多