Reputation: 29976
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?
Upvotes: 2
Views: 5240
Reputation: 9221
This is how I do it on .net core 2.2:
using System;
using System.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
namespace ConsoleAppDependencyInjection
{
class Program
{
static void Main(string[] args)
{
var serviceProvider = ConfigureContainer();
var service1 = serviceProvider.GetService<Service1>();
var service2 = serviceProvider.GetService<Service2>();
Debug.Assert(service1 != null);
Debug.Assert(service2 != null);
}
static IServiceProvider ConfigureContainer()
{
var services = new ServiceCollection();
ConfigureServices(services);
return services.BuildServiceProvider();
}
static void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<Service1>();
services.AddSingleton<Service2>();
}
}
public class Service1
{
public Service1()
{
}
}
public class Service2
{
Service1 service1;
public Service2(Service1 service1)
{
this.service1 = service1;
}
}
}
Upvotes: 0
Reputation: 247088
To supplement already provided answer, outside of asp.net-core, the DI framework can be used on its own, separately, as it is a completely decoupled module.
Essential .NET - Dependency Injection with .NET Core
public static void Main() {
IServiceCollection serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
var application = new MyApplication(serviceCollection);
// Run
// ...
}
static private void ConfigureServices(IServiceCollection services) {
ILoggerFactory loggerFactory = new Logging.LoggerFactory();
services.AddInstance<ILoggerFactory>(loggerFactory);
//...
}
The only difference is that now you have to create the collection on your own instead of the framework doing it for you as part of its pipeline.
From comments,
It bears mentioning that an ASP.NET Core app is nothing but a console app, which therefore explains why you can use
IServiceColleciton
in a basic console app as well, or anywhere else you like, for that matter.
Upvotes: 1
Reputation: 31282
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);
}
// ...
}
Upvotes: 4