Unable to resolve service for type 'ServiceStack.Jobs.IBackgroundJobs

After I ran" x mix jobs" on my working ServiceStack 8.4.1 Blazor Wasm project, I get a runtime error:

System.AggregateException
  HResult=0x80131500
  Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: Server.ConfigurationNs.JobsHostedService': Unable to resolve service for type 'ServiceStack.Jobs.IBackgroundJobs' while attempting to activate 'Server.ConfigurationNs.JobsHostedService'.)
  Source=Microsoft.Extensions.DependencyInjection
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(ICollection`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.Hosting.HostApplicationBuilder.Build()
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
   at Program.<Main>$(String[] args) in Program.cs:line 18

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: Server.ConfigurationNs.JobsHostedService': Unable to resolve service for type 'ServiceStack.Jobs.IBackgroundJobs' while attempting to activate 'Server.ConfigurationNs.JobsHostedService'.

Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'ServiceStack.Jobs.IBackgroundJobs' while attempting to activate 'Server.ConfigurationNs.JobsHostedService'.

Am I missing something?

It’s not clear why it’s not working in your project but you can checkout the blazor-wasm template for a working Blazor WASM + Background Jobs configuration.

It uses a different Configure.BackgroundJobs.cs which is integrated with sending Identity Auth emails with Background Jobs.

You can also try deleting NuGet.config so that you’re only referencing the official v8.4 packages published on NuGet. Also make sure all page references are referencing 8.* so that they’re all referencing the same (latest) version.

<PackageReference Include="ServiceStack" Version="8.*" />

All ServiceStack packages are at 8.4.1 (using Feedz as the nuget source). The blazor-wasm template project works without any errors (as expected).

I have compared the code between the working blazor-wasm project and my project after running “x mix jobs”, but I do not see any background job related differences.

There is only one code change in my project after running the mixin

  • Configure.BackgroundJobs.cs is added

There are no changes to my Program.cs file.

In the blazor-wasm project, the Program.cs contains:

services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo("App_Data"));

and the jobs.db file is under App_Data\jobs

So, in my project, how does the jobs service know where the Sqlite jobs.db is located (e.g. App_Data in the blazor_wasm project)?

No idea why your project is having different behavior, maybe your packages are dirty. You can try reverting back to official NuGet packages by deleting NuGet.config and doing a full nuget restore, although we’ve got several projects using pre-release packages with Background Jobs.

This is built-into the BackgroundsJobFeature where it automatically saves the jobs.db in App_Data/jobs by default:

I have cleaned nuget and restored clean. If I find the time, I will try using nuget.org instead of feedz

Unfortunately, I will now have to abandon my hope of using the jobs feature, and by extension the SQLite logging feature. Pity, because they are great additions to ServiceStack.

Anyway, thank you for the quick response.

I noticed on nuget.org, only 8.4.0 packages are available. Are there any significant changes with the 8.4.1 package on Feedz?

No since we just released v8.4.0 last week, v8.4.1 is automatically bumped for the next pre-release version until the next release.

I cleared nuget, fetched ServiceStack 8.4.0 packages from nuget.org. Same runtime error as before.

The packages shouldn’t have different behavior since they’re both close to the same version, reverting to 8.4.0 would at least reference the immutable packages on NuGet to rule out any dirty packages.

I’m assuming your project differs from the working project templates on github.com/NetCoreTemplates, but without a repro I wont be able to tell form here.

It is quite different than the current templates, because it started with a much earlier ServiceStack version and has been updated along the way with newer ServiceStack releases.

I will try to create a minimal repo, but not sure when I will have the time yet.

Thank you for your support.

1 Like

Success!

I compared the blazor-wasm template with my project, and managed to get my project working with the jobs feature by adding the following to Program.cs

//Program.cs

// ADDED Register all services 
builder.Services.AddServiceStack(typeof(ReferenceService).Assembly);

var app = builder.Build();

I was not doing this, because I have registered my services in Configure.AppHost.cs and that has worked without any issues.

//Configure.AppHost.cs

public AppHost() : base(ApplicationName,
    typeof(Framework.ServiceInterface.SecurityNs.SecurityService).Assembly,
    typeof(ReferenceService).Assembly) // Alchemy
{
//...
}

Is there a reason that the previous Configure.AppHost.cs stopped the jobs feature working?

Unfortunately, the change to avoid the runtime error with jobs, causes null reference error in my first executed service that uses AutoQuery

//Program.cs
services.AddServiceStack(
    [
        typeof(Framework.ServiceInterface.SecurityNs.SecurityService).Assembly,
        typeof(ReferenceService).Assembly
    ]);

Removing the jobs feature and reverting back to my original code avoids the null reference error:

    public AppHost() : base(ApplicationName,
         typeof(Framework.ServiceInterface.SecurityNs.SecurityService).Assembly,
         typeof(ReferenceService).Assembly
        ) 

So, one step forward, two steps back.

When using Endpoint Routing and ASP .NET Core IOC you’ll need to switch to constructor injection, e.g:

public class SecurityService(IAutoQueryDb autoQuery) : Service
{
    public object Get(QueryUserPermission request) => ...;
}

Optional dependencies can use [Service] attribute property injection, but required dependencies should switch to constructor injection.

You’ll also need to register all plugins with services.AddPlugin so that their dependencies are also registered in ASP .NET IOC.

Either in Program.cs

builder.Services.AddPlugin(new AdminDatabaseFeature());

Or in ConfigureServices() in your Modular Startup config classes:

public class ConfigureDb : IHostingStartup
{
    public void Configure(IWebHostBuilder builder) => builder
        .ConfigureServices((context, services) => {
            services.AddPlugin(new AutoQueryFeature {
                 MaxLimit = 1000,
            });
        });
}

Yes, I now suspect that my neglect of not following the release notes is hitting me when adding new features. I will take the time to update my modular startup configs to the new way for ServiceStack 8.

I will update the ticket as soon as I have news. Thank you again.