-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Kestrel
服务器源码解读和 IOC
容器依赖注入 DI
源码分析
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
CreateDefaultBuilder
方法
-
启动必须的配置:比如监听的端口,
url
地址等。 -
程序自定义配置,从
appsettings.json
、appsettings.[EnvironmentName].json
、环境变量、命令行参数和其他配置源中加载。 -
日志系统的配置:将日志记录输送发送到控制台等。
ConfigureWebHostDefaults
方法
- 指定和配置
web
服务器:将Kestrel
服务器用作web
服务器并启用IIS
集成。
为什么要用 HostBuilder
?
-
Host
的职责只是完成主机该有的功能。 -
因为
Host
创建过程非常复杂,所以它的创建及其配置由一个特定的HostBuilder
类完成,它是Host
的创建器(工厂)。
Asp.net Core
的启动步骤
Asp.net Core 主机内部的执行流程
public static IHostBuilder CreateHostBuilder(string[] args)
{
IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);
hostBuilder.ConfigureAppConfiguration(configure =>
{
Console.WriteLine("1. ConfigureAppConfiguration");
});
hostBuilder.ConfigureHostConfiguration(configure =>
{
Console.WriteLine("2. ConfigureHostConfiguration");
});
hostBuilder.ConfigureServices(configure =>
{
Console.WriteLine("3. ConfigureServices");
});
hostBuilder.ConfigureWebHostDefaults(webBuilder =>
{
Console.WriteLine("4. ConfigureWebHostDefaults");
webBuilder.UseStartup<Startup>();
});
return hostBuilder;
}
// output : 4,2,1,3
.NetCore
内置容器
在 .NetCore
里面默认提供一个服务注册和获取的容器,为什么要用这个容器呢?
我们写完了各种对象,在使用的时候,肯定去 new
,这个是经常的操作。
试想另一种情况:如果我们在一个系统中,用的对象非常多,你就得不断的去new对象。
问题:处处在new是不是很麻烦?扩展也是不现实的。
想法:能不能别人帮我new?我想用什么,就得到什么?我们是用对象容器,就是帮我们生成这些对象,
并且对对象的生命周期,统一管理。
好处:不仅能够精确的控制对象的生命周期,而且,还能自动的创建依赖对象
看一下的问题,接口类:
public interface IServiceA
{
void Operation();
}
public interface IServiceB
{
void Operation();
}
public interface IServiceC
{
void Operation();
}
public interface IServiceD
{
void Operation();
}
接口的实现:
/// <summary>
/// 服务A的实现
/// </summary>
public class ObjectA : IServiceA
{
public ObjectA()
{
Console.WriteLine("ObjectA is Created!");
}
public void Operation()=> Console.WriteLine("ObjectA.Operation() is Called!");
}
/// <summary>
/// 服务B的实现
/// </summary>
public class ObjectB : IServiceB
{
private readonly IServiceA serviceA;
public ObjectB(IServiceA service)
{
this.serviceA = service;
Console.WriteLine("ObjectB is Created!");
}
public void Operation()
{
Console.WriteLine("--------------------------------------------");
this.serviceA.Operation();
Console.WriteLine("ObjectB.Operation() is Called!");
}
}
/// <summary>
/// 服务C的实现
/// </summary>
public class ObjectC : IServiceC
{
private readonly IServiceB serviceB;
public ObjectC(IServiceB service)
{
this.serviceB = service;
Console.WriteLine("ObjectC is Created!");
}
public void Operation() => Console.WriteLine("ObjectC.Operation() is Called!");
}
/// <summary>
/// 服务D的实现
/// </summary>
public class ObjectD : IServiceD
{
private readonly IServiceA _serviceA;
private readonly IServiceB _serviceB;
private readonly IServiceC _serviceC;
public ObjectD(IServiceA serviceA, IServiceB serviceB, IServiceC serviceC)
{
this._serviceA = serviceA;
this._serviceB = serviceB;
this._serviceC = serviceC;
Console.WriteLine("ObjectD is Created!");
}
public void Operation()
{
Console.WriteLine("---------------------------------------");
this._serviceA.Operation();
this._serviceB.Operation();
this._serviceC.Operation();
Console.WriteLine("ObjectD.Operation() is Called!");
}
}
main
方法里
static void Main(string[] args)
{
ObjectA obj = new ObjectA(); //直接new 对象
IServiceA a = new ObjectA(); // 基于接口,半解耦
IServiceB b = new ObjectB(a);
IServiceC c = new ObjectC(b);
IServiceD d = new ObjectD(a,b,c)
}
问题:
-
以前方法对于对象之间的关联创建,非常麻烦。因为一个对象所关联的其他对象,必须全部提前创建。
-
这种需求,即使我们以前所学的工厂模式,也很难做到。
Nuget
引入 DI
using Microsoft.Extensions.DependencyInjection;
static void Main(string[] args)
{
//【1】创建服务容器
IServiceCollection services = new ServiceCollection();
//【2】注册服务
services.AddTransient<IServiceA, ObjectA>();
services.AddSingleton<IServiceB, ObjectB>();
services.AddScoped<IServiceC, ObjectC>();
services.AddTransient<IServiceD, ObjectD>();
//【3】创建服务提供者对象
IServiceProvider serviceProvider = services.BuildServiceProvider();
//【4】获取服务 - 可能在系统的其他地方
//IServiceA instanceA = serviceProvider.GetService<IServiceA>();
IServiceD instanceD = serviceProvider.GetService<IServiceD>();
// instanceA.Operation();
Console.Read();
}
引入 Ioc
概念
-
Ioc(Inverse of Control)
控制反转: 就是将对象的控制权由我们开发者转移到容器。 -
好处:开发者不用关注细节,只需要关注抽象接口,非常有利于组件化开发。
依赖注入 DI
和 Ioc
容器
基于 Ioc
容器的 DI
框架两大核心
-
服务注册
-
服务提供
DI
: Dependency Injection
思想
- 服务的使用者基于一个容器(Container)来得到需要的对象,容器在这个对象过程中自动完成所有依赖对象的创建。
常见 DI
容器
-
Autofac
-
Unity
-
Spring.Net
Ioc
和 DI
的区别
-
Ioc
:调用者不关心对象的创建,由Ioc
容器完成,体现的是一种控制权的转移。 -
DI
: 基于Ioc
容器创建需要的对象,同时能够自动完成所依赖对象的创建。体现的是一种依赖对象自动的注入。
总结
ASPNETCore
程序启动的核心方法源码分析
-
CreateDefaultBuilder()
方法 -
ConfigureWebHostDefault()
方法 -
细化
ASP.NET Core
主机内部的执行流程
Ioc
容器的使用
-
IServiceCollection
-
服务注册的三种生命周期
Transient
Singleton
Scoped
-
IServiceProvider
-
GetService()
方法
依赖注入 DI
-
思想:体现的是对象创建中所依赖的对象的自动创建。
-
好处:让模块化开发更加富有弹性。