具有范围依赖性的 .Net Core 2.0 Webjob
.Net Core 2.0 Webjob with Scoped Dependencies
我正在使用 IJobActivator 设置 .Net Core 2.0 来构建网络作业。 IServiceScopeFactory.CreateScope 如果 Functions 是作用域的,则似乎在 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 是作用域的:异常将在激活器中抛出:无法解析来自根提供者的作用域服务 'ValidationResultProcessorWebJob.Functions'。
如果 Functions 是单例:System.InvalidOperationException: 无法从根提供程序解析作用域服务 'ValidationResultProcessorWebJob.TelemetryScopeProvider'。
是否未应用_scopeFactory.CreateScope()?为什么不呢?
谢谢,
韦恩
我错误地认为 IServiceScopeFactory 提供了比它更多的魔力。据我目前了解,应该使用 IServiceScopeFactory.CreateScope 创建子作用域。 IServiceScope 包含一个 ServiceProvider,然后可用于实例化新的依赖关系图。
我将逻辑从函数移至新处理器 class 并将其配置为 Scoped。
serviceCollection.AddScoped<Functions>();
serviceCollection.AddScoped<ResponseProcesor>();
//... Other scoped dependecies e.g. EF context and repositories.
我将 IServiceScopeFactory 注入 WebJobs class(函数)并从中实例化一个新的对象图。
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);
}
}
}
我正在使用 IJobActivator 设置 .Net Core 2.0 来构建网络作业。 IServiceScopeFactory.CreateScope 如果 Functions 是作用域的,则似乎在 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 是作用域的:异常将在激活器中抛出:无法解析来自根提供者的作用域服务 'ValidationResultProcessorWebJob.Functions'。
如果 Functions 是单例:System.InvalidOperationException: 无法从根提供程序解析作用域服务 'ValidationResultProcessorWebJob.TelemetryScopeProvider'。
是否未应用_scopeFactory.CreateScope()?为什么不呢?
谢谢,
韦恩
我错误地认为 IServiceScopeFactory 提供了比它更多的魔力。据我目前了解,应该使用 IServiceScopeFactory.CreateScope 创建子作用域。 IServiceScope 包含一个 ServiceProvider,然后可用于实例化新的依赖关系图。
我将逻辑从函数移至新处理器 class 并将其配置为 Scoped。
serviceCollection.AddScoped<Functions>();
serviceCollection.AddScoped<ResponseProcesor>();
//... Other scoped dependecies e.g. EF context and repositories.
我将 IServiceScopeFactory 注入 WebJobs class(函数)并从中实例化一个新的对象图。
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);
}
}
}