Asp.Net Core 内置IOC容器的理解
01.使用IOC容器的好处
- 对接口和实现类由原来的零散式管理,到现在的集中式管理。
- 对类和接口之间的关系,有多种注入模式(构造函数注入、属性注入等)。
- 对实现类的声明周期进行了统一管理(创建、释放、和监控)。
- 对类的依赖有编译时到运行时。
02.实际使用
1.创建控制台项目并添加Nuget包引用
Nuget包:Microsoft.Extensions.DependencyInjection
2.简单使用
class Program
{
static void Main(string[] args)
{
// 正常使用
Bird bird = new Bird(); //IFly bird=new Bird();
bird.Fly();
//IOC使用
ServiceCollection serviceCollection = new ServiceCollection(); //创建IOC容器
serviceCollection.AddTransient<IFly, Bird>(); //将服务注入容器
var provider = serviceCollection.BuildServiceProvider(); //创建Provider
var fly = provider.GetService<IFly>(); //获取注入的类型
fly.Fly(); //调用
}
}
interface IFly
{
void Fly();
}
class Bird : IFly
{
public void Fly()
{
Console.WriteLine("鸟飞起来了........");
}
}
3.日志注册
- NetGut包:Microsoft.Extensions.Logging.Console
class Program
{
static void Main(string[] args)
{
ServiceCollection serviceCollection = new ServiceCollection();
//注册日志服务
serviceCollection.AddLogging(configure =>
configure.AddConsole()
);
serviceCollection.AddTransient<IFly, Bird>();
var provider = serviceCollection.BuildServiceProvider();
provider.GetService<ILoggerFactory>();
var fly = provider.GetService<IFly>();
fly.Fly();
}
}
interface IFly
{
void Fly();
}
class Bird : IFly
{
private readonly ILogger<Bird> _iLogger;
public Bird(ILoggerFactory logger)
{
_iLogger = logger.CreateLogger<Bird>();
}
public void Fly()
{
_iLogger.Log(LogLevel.Information, "日志消息.....");
Console.WriteLine("鸟飞起来了........");
}
}
4.生命周期
- AddTransient 每次请求都会被创建
- AddSingleton 单例模式
- AddScoped 作用域(范围)内是单例模式
AddScoped案例代码
class Program
{
static void Main(string[] args)
{
ServiceCollection serviceCollection = new ServiceCollection();
////每次请求都创建
//serviceCollection.AddTransient<IFly, Bird>();
////单例模式,永远都是一个
//serviceCollection.AddSingleton<IFly, Bird>();
//在某个作用域下是单例
serviceCollection.AddScoped<IFly, Bird>();
var provider = serviceCollection.BuildServiceProvider();
//创建两个scope
var scope1 = provider.CreateScope();
var scope2 = provider.CreateScope();
//第一个作用域
scope1.ServiceProvider.GetService<IFly>();
//第二个作用域
scope2.ServiceProvider.GetService<IFly>();
//第三个作用域 注意:这里是获取了两次
var fly = provider.GetService<IFly>();//第一次
fly = provider.GetService<IFly>();//第二次
fly.Fly();
}
}
interface IFly
{
void Fly();
}
class Bird : IFly
{
public Bird()
{
Console.WriteLine("初始化构造函数......");
}
public void Fly()
{
Console.WriteLine("鸟飞起来了........");
}
}
运行结果:调用了三次构造函数....