Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I had developed the blazorWASM Hosted Application with IndexedDb.

This application has two projects, client and server projects.

Client project purely runs on browser and server project contains ASP.NET Core API and ASP.NET Core Server hosted the client application or client project.

I had developed background service for long running on background of application in server project or server. Blazor client makes a request to
background service using HTTP API request at the time, got the error like:
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();   
    }
  }


I had registered the service in starup.cs file:
C#
public void ConfigureServices(IServiceCollection services)
{
    // ...

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


Namespace where backgroundservice defined that is the same for where the register service using Dependency injection(DI) for AddHostedservice also but didn't find the service or NO service for Type UpdateDbBackgroundService has been registered when request controller from client.

Please help me to fix the issue. Thanks!

What I have tried:

I had developed background service for long running on background of application in server project or server. Blazor client makes a request to
background service using HTTP API request at the time got the error like:
Unable to resolve service for type 'WebAssembly.Server.Data.UpdateDbBackgroundService' while attempting to activate 'WebAssembly.Server.Controllers.BackgroundServiceController'.
Posted
Updated 25-Oct-23 8:56am
v3

1 solution

.Net (Core)Hosted Services run in a different container to normal Dependency Injection, therefore, to access, you need to access them differently. You can read about it here: Background tasks with hosted services in ASP.NET Core | Microsoft Learn[^].

Here is a sample of how you could do it: ASP.NET Core IHostedService manual start/stop/pause(?) - StackOverflow[^]

I'm not a fan of starting and stopping hosted services. The preferred method is as per the Microsoft example, Queued background tasks
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900