对于Asp.Net Core Dependence Injection,我知道我们将依赖注册到IServiceCollection
,并使用IServiceProvider
来获取实例。
我想知道注册和初始化IServiceCollection
的代码。
对于Interface Injection,为什么知道从ServiceCollection获取实例?哪个代码实现了这个功能?
我想知道全局控制器谁以及如何控制它?
答案 0 :(得分:1)
创建ASP.NET Core项目时,会为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();
}
IServiceCollection
的实例是在WebHost.CreateDefaultBuilder(args)
内创建的,然后传递给Startup.ConfigureServices(IServiceCollection services)
来电。
如果你想在ASP.NET Core源代码中跟踪调用链,这里是(包含github上的源代码的链接):
WebHost.CreateDefaultBuilder()调用WebHostBuilderExtensions.UseDefaultServiceProvider()
扩展方法:
public static IWebHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = new WebHostBuilder()
.UseIISIntegration()
// ...
.UseDefaultServiceProvider((context, options) =>
{
options.ValidateScopes = context.HostingEnvironment.IsDevelopment();
});
// ...
return builder;
}
WebHostBuilderExtensions.UseDefaultServiceProvider()调用WebHostBuilder.ConfigureServices()
方法:
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最终会创建ServiceCollection
的实例并调用Startup.ConfigureServices()
方法(通过存储操作):
private IServiceCollection BuildCommonServices(out AggregateException hostingStartupErrors)
{
// ...
// Creation of `ServiceCollection` instance
var services = new ServiceCollection();
// ...
foreach (var configureServices in _configureServicesDelegates)
{
configureServices(_context, services);
}
// ...
}
答案 1 :(得分:1)
为了补充已经提供的答案,在asp.net-core之外,DI框架可以单独使用,因为它是一个完全解耦的模块。
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);
//...
}
唯一的区别是,现在你必须自己创建集合,而不是作为管道的一部分为你做框架。
来自评论,
值得一提的是,ASP.NET核心应用程序只不过是一个控制台应用程序,因此可以解释为什么您可以在基本控制台应用程序中使用
IServiceColleciton
,或者在其他任何您喜欢的地方使用它。
答案 2 :(得分:0)
这是我在.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;
}
}
}