0

IJobActivator를 사용하여 .Net Core 2.0을 설치 한 webjob을 작성합니다. IServiceScopeFactory.CreateScope는 IjobActivator에서 작동하지 않는 것처럼 보입니다. 함수가 범위가 지정되어 있거나 Singleton 인 경우 함수 내에서 작동하지 않습니다.. 범위가 정의 된 종속성이있는 Net Core 2.0 Webjob

e.e. 예외는 활성에 발생합니다 : : 함수가 범위의 경우

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를'범위 확인할 수 없습니다.

함수가 singleton 인 경우 System.InvalidOperationException : 루트 공급자에서 'ValidationResultProcessorWebJob.TelemetryScopeProvider'범위의 서비스를 확인할 수 없습니다.

_scopeFactory.CreateScope()가 적용되지 않습니까? 왜 안돼?

감사합니다,

웨인

+0

'ProcessorActivator'는'IServiceScopeFactory '를 인스턴스화해야합니다. 컴파일 중입니까? – Thomas

+0

컴파일되어 실행됩니다. serviceCollection.BuildServiceProvider (false)를 사용하면 일반적으로 잠시 동안 실행되지만 dbcontext를 다시 사용하면 결국 오류가 발생합니다. 나는 Null이 아닌 객체를 얻음으로써 IServiceScopeFactory가 컨테이너에 자동으로 설정되어 있다고 믿었다. 내 코드는 미리보기 모음이므로 복사하여 붙여 넣기 문제가있을 수 있습니다. – wayju

답변

0

내가 잘못 IServiceScopeFactory 그것보다 더 마법을 제공하는 것을 생각했다. 현재 IServiceScopeFactory.CreateScope를 사용하여 하위 범위를 만들어야한다고 이해하고 있습니다. IServiceScope에는 종속성의 새로운 그래프를 인스턴스화하는 데 사용할 수있는 ServiceProvider가 포함되어 있습니다.

로직에서 함수를 새 프로세서 클래스로 옮기고 Scoped로 구성했습니다.

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

는 I는 WebJobs 클래스 (함수)에 IServiceScopeFactory 주입하고에서 새로운 객체를 인스턴스화 그래프.

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); 
     } 
    } 
} 
관련 문제