For Asp.Net Core Dependence Injection, I know we register the dependence into IServiceCollection
, and use IServiceProvider
to get the instance.
I am wondering the code which register and initialize the IServiceCollection
.
For Interface Injection, why did it know get the instance from the ServiceCollection? Which code implement this feature?
I want to know the global controller who and how control this?
When you create ASP.NET Core project, the following code is generated for Program.Main()
:
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
The instance of IServiceCollection
is created inside WebHost.CreateDefaultBuilder(args)
and then is passed to Startup.ConfigureServices(IServiceCollection services)
call.
If you want to track the calls chain in ASP.NET Core source code, here it is (links to source code on github included):
WebHost.CreateDefaultBuilder() calls WebHostBuilderExtensions.UseDefaultServiceProvider()
extension method:
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseIISIntegration()
// ...
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
// ...
return builder;
}
WebHostBuilderExtensions.UseDefaultServiceProvider() calls WebHostBuilder.ConfigureServices()
method:
public static IWebHostBuilder UseDefaultServiceProvider(this IWebHostBuilder hostBuilder, Action<WebHostBuilderContext, ServiceProviderOptions> configure)
{
return hostBuilder.ConfigureServices((context, services) =>
{
var options = new ServiceProviderOptions();
configure(context, options);
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(new DefaultServiceProviderFactory(options)));
});
}
WebHostBuilder eventually creates the instance of ServiceCollection
and calls Startup.ConfigureServices()
method (through stored action):
private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
{
// ...
// Creation of `ServiceCollection` instance
var services = new ServiceCollection();
// ...
foreach (var configureServices in _configureServicesDelegates)
{
configureServices(_context, services);
}
// ...
}