Singleton BackgroundService not started by Autofac

818 Views Asked by At

I am running Autofac.Extensions.DependencyInjection 7.1.0 in an ASP.NET Core 3.1 REST API.

I have a BackgroundService class and configured to run as a SingleInstance.

My problem is that the StartAsync is never called. But configured without the SingleInstance statement, StartAsync is called.

Is this a bug, not configured correctly or maybe a misunderstanding?

Registration:

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
             .AsImplementedInterfaces()
             .Except<BackgroundSendMailService>(ct => ct.As<IBackgroundSendMailService>()
                .SingleInstance())
             .PublicOnly();

BackgroundService:

using Microsoft.Extensions.Hosting;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace TheNameSpace
{
    public interface IBackgroundSendMailService : IHostedService
    {
        Task SendMail(List<EmailModel> emails);
    }

    public class BackgroundSendMailService : BackgroundService, IBackgroundSendMailService
    {
        public BackgroundSendMailService()
        {

        }

        public Task SendMail(List<EmailModel> emails)
        {
            return Task.CompletedTask;
        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            return Task.CompletedTask;
        }

        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return Task.CompletedTask;
        }
    }


}
1

There are 1 best solutions below

0
On

Your service is not exposed to the DI container as an IHostedService, so it cannot be found when looking up all those services at startup. The DI container can only resolve it when looking specifically for an IBackgroundSendMailService.

Change this part

.Except<BackgroundSendMailService>(ct => ct.As<IBackgroundSendMailService>()
                                           .SingleInstance())

to either this

.Except<BackgroundSendMailService>(ct => ct.As<IBackgroundSendMailService>()
                                           .As<IHostedService>()
                                           .SingleInstance())

or something like this:

.Except<BackgroundSendMailService>(ct => ct.AsImplementedInterfaces()
                                           .SingleInstance())

Edit: I just noticed you used the AsImplementedInterfaces() on the assembly registration, but I guess the Except won't take this into account and just use your manual registration.