Problem ¶
Neither .NET generic host’s HostBuilder
nor IHost
exposes IServiceCollection
. You can resolve services via the IHost.Services
property but there is no obvious way of accessing dependency registration metadata.
Solution ¶
It can be done using a custom service provider factory:
public class ExposeServiceCollectionFactory : IServiceProviderFactory<IServiceCollection>
{
private DefaultServiceProviderFactory _defaultFactory =
new DefaultServiceProviderFactory();
public IServiceCollection? ServiceCollection { get; private set; }
public IServiceCollection CreateBuilder(IServiceCollection services)
{
ServiceCollection = services;
return _defaultFactory.CreateBuilder(services);
}
public IServiceProvider CreateServiceProvider(IServiceCollection containerBuilder)
{
return _defaultFactory.CreateServiceProvider(containerBuilder);
}
}
Then the factory can be used as follows:
var builder = new HostBuilder();
var factory = new ExposeServiceCollectionFactory();
builder.UseServiceProviderFactory(factory);
// your configuration here
builder.Build();
var services = factory.ServiceCollection;
Console.WriteLine($"Got {services.Count} services here");
Why would you need that ¶
Usually you wouldn’t. It may come handy when you have a library consuming an IServiceCollection
but you
have lots of extensions methods for IHostBuilder
rather than IServiceCollection
. This way you can
reuse your extension methods and pass the resulting IServiceCollection
to the library.