0

There are many extensions for the IServiceCollection - in my case I use AddHttpClient.

My scenario is that I register general stuff in the ConfigureServices method in the Startup.cs where IServiceCollection is used to register services. Everything that is needed only in specific projects is registered in an extension method in the respective project, but there the DryIoc IContainer is used due to how the DryIoc container must be integrated in an ASP .NET Core project.

Now I have a HttpClient that I only need in a specific project. Therefore I would like to put the registration for it in the respective project. Problem is I want to use AddHttpClient for it which I normally can only use with IServiceCollection.

My question: Is there any way to use it in my other project. Maybe by getting it from the DryIoc container or something else.

This is the general structure of the described files:

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.RegisterSomeService();
        // register other stuff
    }
}

Program.cs

public class Startup
{
    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .UseServiceProviderFactory(new DryIocServiceProviderFactory())
            .ConfigureContainer<Container>(SomeProject.ContainerSetup.Initialize);
}

ContainerSetup.cs in SomeProject

public static class ContainerSetup
{
    public static void Initialize(HostBuilderContext hostContext, IContainer container)
    {
        container.Register<SomeService>();
        // register other stuff
        // here I want to use AddHttpClient
    }
}
Christoph Mett
  • 369
  • 3
  • 16

2 Answers2

2

I was able to solve the problem by using the IContainer extension Populate which is part of DryIoc.Microsoft.DependencyInjection.

With it I edited my ContainerSetup.cs as follows

public static class ContainerSetup
{
    public static void Initialize(HostBuilderContext hostContext, IContainer container)
    {        
        var services = new ServiceCollection();
        
        services.AddHttpClient<MyTypedClient>()
            .Configure[...];
        
        container.Populate(services); // with this call all services registered above will be registered in the container
        
        // register other stuff if necessary
        container.Register<SomeService>();
    }
}
Christoph Mett
  • 369
  • 3
  • 16
1

I suggest to look inside the AddHttpClient https://source.dot.net/#Microsoft.Extensions.Http/DependencyInjection/HttpClientFactoryServiceCollectionExtensions.cs,72bc67c4aadb77fc

and maybe make the same registrations with IContainer instead of the service collection.

Update:

Another idea is to register IServiceCollection into itself (or maybe it is already automatically registered?), then resolve it from IContainer and AddHttpClient..

dadhi
  • 4,807
  • 19
  • 25
  • 1
    Yeah, that were exactly my two ideas. First one is possible but pretty ugly because there are sooooo many registration within `AddHttpClient`. The Second approach I also checked. By default it is not registered, but it would be possible I think. Only thing I don't know if it would have any bad side effects. Will try this tomorrow. – Christoph Mett Aug 13 '20 at 20:44
  • 1
    Nope, does not seem to work. The registrations are only done in the instance of the `IServiceCollection` that is resolved. After this, they are not part of the DryIoC container. Or maybe I do it wrong. – Christoph Mett Aug 14 '20 at 07:46