0

IJobActivatorを使用して.Net Core 2.0を設定してWebジョブを構築しています。 IServiceScopeFactory.CreateScopeは、関数がスコープされている場合はIJobActivatorで動作していないようで、シングルトンの場合は関数内で機能していないようです。。スコープの依存関係を持つ.Net Core 2.0 Webjob

I.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」をスコープ解決することはできません。

関数がシングルトンの場合:System.InvalidOperationException:スコープされたサービス 'ValidationResultProcessorWebJob.TelemetryScopeProvider'をルートプロバイダから解決できません。

_scopeFactory.CreateScope()は適用されていませんか?何故なの?

おかげで、

ウェイン

+0

あなたの 'ProcessorActivator'は' IServiceScopeFactory 'がインスタンス化されることを要求します。はコンパイルしていますか? – Thomas

+0

コンパイルして実行します。 serviceCollection.BuildServiceProvider(false)を使用すると、通常は少し時間がかかりますが、dbcontextを再利用すると最終的にエラーになります。私は、null以外のオブジェクトを取得すると、IServiceScopeFactoryがコンテナ内で自動的に設定されると考えました。 コードはスニペットの束ですが、コピー&ペーストの問題がある可能性があります。 – wayju

答えて

0

は、私が誤ってIServiceScopeFactoryはそれがないよりも多くの魔法を提供していたと思いました。私が現在理解しているように、子スコープはIServiceScopeFactory.CreateScopeで作成する必要があります。 IServiceScopeには、依存関係の新しいグラフをインスタンス化するために使用できるServiceProviderが含まれています。

ロジックを関数から新しいプロセッサクラスに移動し、スコープとして構成しました。

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); 
     } 
    } 
} 
関連する問題