【解決方法】「webassembly.server.controllers.backgroundservicecontroller」をアクティブ化しようとしているときに、タイプ「webassembly.server.data.updatedbbackgroundservice」のサービスを解決できません。

[ad_1]

私が開発したのは、 blazorWASM ホスト型アプリケーション IndexedDb

このアプリケーションには、クライアント プロジェクトとサーバー プロジェクトの 2 つのプロジェクトがあります。

クライアント プロジェクトは純粋にブラウザー上で実行され、サーバー プロジェクトには ASP.NET Core API が含まれており、ASP.NET Core サーバーはクライアント アプリケーションまたはクライアント プロジェクトをホストします。

サーバープロジェクトまたはサーバー内のアプリケーションのバックグラウンドで長時間実行するためのバックグラウンドサービスを開発しました。 Blazor クライアントがリクエストを行う
当時、HTTP API リクエストを使用したバックグラウンド サービスでは、次のようなエラーが発生しました。

Unable to resolve service for type 'WebAssembly.Server.Data.UpdateDbBackgroundService' while attempting to activate 'WebAssembly.Server.Controllers.BackgroundServiceController'.

Backgroundservice:

C#
public class UpdateDbBackgroundService : BackgroundService
{
    private CancellationTokenSource _stoppingCts;
    private Task _executeTask;
    private SyncWorkerService _worker;

    private readonly ILogger<UpdateDbBackgroundService> _logger;

    private readonly IBlazorDbFactory _dbFactory;

    private readonly IHttpClientFactory _httpClientFactory;

    private IndexedDbManager _manager;

    private readonly IServiceProvider _serviceProvider;
    public UpdateDbBackgroundService
    (IServiceProvider serviceProvider,
     IHttpClientFactory httpClientFactory,
     IBlazorDbFactory dbFactory,
     SyncWorkerService worker, IndexedDbManager manager,
     ILogger<UpdateDbBackgroundService> logger)
    {
        _serviceProvider = serviceProvider;
        _httpClientFactory = httpClientFactory;
        _dbFactory = dbFactory;
        _worker = worker;
        _manager = manager;
        _logger = logger;
    }
    protected override async Task ExecuteAsync
              (CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("background process started");

            // Check for new orders in IndexedDB and
            // update the SQL database
            await ProcessOrdersAsync();
        }
    }

    public async Task ProcessOrdersAsync()
    {
        _manager = await _dbFactory.GetDbManager("resdb");

        var order = (await _manager.ToArray<Orders>
        ("Orders")).OrderByDescending(s => s.Id).FirstOrDefault();

        var client = _httpClientFactory.CreateClient("WebAPI");

        var updaterequest = new HttpRequestMessage
            (HttpMethod.Post, "api/Orders/UpdateOrder");

        HttpResponseMessage response = await
        HttpClientJsonExtensions.PostAsJsonAsync
              (client, updaterequest.RequestUri, order);

        if (response.IsSuccessStatusCode)
        {
            var updatereponse =
                response.Content.ReadAsStringAsync().Result;
        }
    }
    /// <summary>
    /// Triggered when application host is ready to start the service.
    /// </summary>
    /// <param name="cancellationToken">Indicates that the start
    /// process has been aborted.</param>
    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Create linked token to allow cancelling executing task
        // from provided token
        _stoppingCts =
      CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);

        // Store the task we're executing
        _executeTask = ExecuteAsync(_stoppingCts.Token);

        // If the task is completed then return it,
        // this will bubble cancellation and failure to the caller
        if (_executeTask.IsCompleted)
        {
            return _executeTask;
        }

        // Otherwise it's running
        return Task.CompletedTask;
    }

    /// <summary>
    /// Triggered when the application host is performing
    /// a graceful shutdown.
    /// </summary>
    /// <param name="cancellationToken">
    /// Indicates that the shutdown process should no longer be graceful.
    /// </param>
    public async Task StopAsync(CancellationToken cancellationToken)
    {
        // Stop called without start
        if (_executeTask == null)
        {
            return;
        }

        try
        {
            // Signal cancellation to the executing method
            _stoppingCts.Cancel();
        }
        finally
        {
            // Wait until the task completes or the stop token triggers
            await Task.WhenAny(_executeTask, Task.Delay
            (Timeout.Infinite, cancellationToken)).ConfigureAwait(false);
        }
    }
}

BackgroundServiceController:

C#
[Route("api/background-service")]
[ApiController]
 public class BackgroundServiceController : ControllerBase
 {
    private readonly UpdateDbBackgroundService _backgroundService;

   public BackgroundServiceController
                (UpdateDbBackgroundService backgroundService)
   {
      _backgroundService = backgroundService;
   }

    [HttpPost("start")]
    public IActionResult StartBackgroundService()
    {
       _backgroundService.StartAsync(CancellationToken.None);
       return Ok();
    }

    [HttpPost("stop")]
    public IActionResult StopBackgroundService()
    {
      _backgroundService.StopAsync(CancellationToken.None);
      return Ok();   
    }
  }

にサービスを登録していました スターアップ.cs ファイル:

C#
public void ConfigureServices(IServiceCollection services)
{
    // ...

    // Register the background service
   services.AddHostedService<UpdateDbBackgroundService>();
   // services.AddHttpClient();
    services.AddScoped<IBlazorDbFactory, BlazorDbFactory>();
    services.AddScoped<SyncWorkerService>();
    // ...
}

Namespace どこ backgroundservice 依存関係注入 (DI) を使用してサービスを登録する場合と同じように定義されています。 AddHostedservice また、タイプのサービスが見つからないか、サービスが見つかりませんでした UpdateDbBackgroundService クライアントからコントローラをリクエストしたときに登録されています。

問題の解決を手伝ってください。 ありがとう!

私が試したこと:

サーバープロジェクトまたはサーバー内のアプリケーションのバックグラウンドで長時間実行するためのバックグラウンドサービスを開発しました。 Blazor クライアントがリクエストを行う
当時、HTTP API リクエストを使用したバックグラウンド サービスでは、次のようなエラーが発生しました。

Unable to resolve service for type 'WebAssembly.Server.Data.UpdateDbBackgroundService' while attempting to activate 'WebAssembly.Server.Controllers.BackgroundServiceController'.

解決策 1

.Net (Core)Hosted Services は通常のDependency Injectionとは異なるコンテナーで実行されるため、アクセスするには別の方法でアクセスする必要があります。 それについてはここで読むことができます: ASP.NET Core のホストされたサービスを使用したバックグラウンド タスク | Microsoft Learn[^]。

これを行う方法のサンプルを次に示します。 ASP.NET Core IHostedService手動開始/停止/一時停止(?) – コードログ[^]

私はホストされたサービスを開始したり停止したりするのが好きではありません。 推奨される方法は Microsoft の例によると、 キューに入れられたバックグラウンド タスク

[ad_2]

コメント

タイトルとURLをコピーしました