Home > front end >  Add service to IServiceCollection NOT in ConfigureServices
Add service to IServiceCollection NOT in ConfigureServices

Time:12-29

I have Startup and IHosterService in witch I want to add a service to IServiceCollection. Problem is, after I add my service to IServiceCollection I can't get it from IServiceProvider

I tried to add my service to IServiceColection in IHostedService, but after I added my service I can't get it from IServiceProvider. Have I any chance to add service in IHostedService and after in get new service from IServiceProvider?

Startup

public class Startup {
... 
public void ConfigureServices(IServiceCollection services) {
        services.AddHostedService<InitHostedService>();
        //without this line I can't resolve IServiceCollection in InitHostedService
        services.AddSingleton<IServiceCollection>(services);
}

InitHostedService

public class InitHostedService : IHostedService {
    private readonly IServiceCollection _services;
    private readonly IServiceProvider _serviceProvider;

    public InitHostedService(IServiceCollection services, IServiceProvider serviceProvider) {
        _services = services;
        _serviceProvider = serviceProvider;
    }
    
    public async Task StartAsync(CancellationToken cancellationToken) { 
        var serviceUri = // get actual uri for my service

        if (serviceUri != null) {
            // add service with uri to IServiceCollaction
            _services.AddServiceClient<IIdMapperServiceClient, IdMapperServiceClient>(serviceUri); 
            // can't get here my added service
            var a = _serviceProvider.GetRequiredService<IIdMapperServiceClient>(); 
    }
...
}

AddServiceClient extension

    public static void AddServiceClient<TServiceContract, TImplementation>(
        this IServiceCollection services,
        Uri serviceUri)
        where TServiceContract : class
        where TImplementation : class, TServiceContract {
        services.AddHttpClient<TServiceContract, TImplementation>((sp, client) => { client.BaseAddress = serviceUri; });
    }

CodePudding user response:

You can't do it this way. IServiceProvider is built from IServiceCollection during startup process. When this happens - IServiceProvider copies services from IServiceCollection. So when your hosted service starts - IServiceProvider has already been built with services that you added during startup. Adding more services to IServiceCollection after that will have no effect, because IServiceProvider is "detached" from this collection already.

CodePudding user response:

I think you trying to do something like that.

public static class ServiceCollectionExtension
{

    public static  IServiceCollection RegisterServices(this IServiceCollection servicesCollection, IConfiguration configuration)
    {
        servicesCollection.AddControllers();
        servicesCollection.AddEndpointsApiExplorer();
        servicesCollection.AppServices();
        servicesCollection.AddIdentity();
        servicesCollection.AddSwagger();
        servicesCollection.AddAutoMapper(typeof(Program));
        servicesCollection.AddDatabase(configuration);
        
        var appSettings = servicesCollection.GetApplicationSettings(configuration);
        servicesCollection.AddJwtTokenAtuhentication(appSettings);

        return servicesCollection;
    }

Hope it helps

  • Related