monty
monty

Reputation: 8745

AddHostedService for Types that are loaded from dynamically loaded assemblies

I have a .NET 5 background worker applications with a single background service (MyInternalBackgroundService).

Now I am working on a modular plug in architecture where plug ins are put in a plug in directory, from there assemblies are loaded. Each assembliy can contain multiple class definitons which inherit from BackgroundService. I load the list of types that are inheriting from BackgroundService.

I just can't figure out how to call the AddHostedService method for the loaded types. Every approach seems to cause a different compiler error.

public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)            
    .ConfigureServices((hostContext, services) =>
    {
      services.AddHostedService<MyInternalBackgroundServiceImplementation>();

      TypeInfo[] moduleTypes = // class scanning directories for dlls, load the assemblies and find the desired types
      foreach(var moduleType in moduleTypes)
      {
        // can't find the correct way
        // services.AddHostedService<moduleType>();
        //services.AddHostedService<moduleType.GetType()>();
      }
    });

Upvotes: 2

Views: 998

Answers (2)

rbohac
rbohac

Reputation: 319

The answer from @maxim helped me. I ended up creating this extension class to load all services derived from the base class ProcessorBase automatically. Sharing in case it helps

public static class ServiceCollectionExtensions
{        
    public static IServiceCollection AddJobProcessors(this IServiceCollection services, Assembly assembly = null)
    {
        assembly ??= Assembly.GetCallingAssembly();

        var processorTypes = assembly.GetTypes()
            .Where(t => t.IsClass
                && !t.IsAbstract
                && t.BaseType != null
                && t.BaseType.IsGenericType
                && t.BaseType.GetGenericTypeDefinition() == typeof(ProcessorBase<>));

        foreach (var processor in processorTypes)            
            services.AddTransient(typeof(IHostedService), processor);            

        return services;
    }
}    

Usage:

services.AddJobProcessors();

Upvotes: 1

Maxim Tkachenko
Maxim Tkachenko

Reputation: 5798

Internally AddHostedService looks like thisenter image description here

Further AddTransient looks like thisenter image description here

So you can try the following approach (of course as long as TypeInfoObjectHere implements IHostedService) services.AddTransient(typeof(IHostedService), TypeInfoObjectHere);

Upvotes: 5

Related Questions