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("鳥飛起來了........");
}
}
運行結果:調用了三次構造函數....