asp.net core 3.1學習筆記——DI依賴注入的幾種方式

一、依賴注入核心組件包:

Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection
 
使用接口實現分離模式實現,核心類包括:
IServiceCollection  --負責服務的註冊;
ServiceDescriptor  --每一個服務註冊的信息;
• IServiceProvider  --服務具體容器,由 ServiceCollection Build 構建;
IServiceScope  --表示一個子容器的生命週期;
 
asp.net core 內置生命週期(ServiceLifetime):
單例 Singleton,在整個根容器的生命週期內都是單例模式(全局範圍);
• 作用域 Scoped,在容器(或子容器)的生存週期內,若容器釋放掉對象也隨即釋放,同時在容器(或局部作用域)範圍內能得到一個單例模式;
瞬時(暫時)Transient ,每一次從容器獲取對象時都可以得到一個全新的對象;
 

二、服務註冊的幾種方式:

在 Startup.cs 文件中,Startup.ConfigureServices 中有如下幾種服務註冊方式:

1.常規服務註冊:

#region 註冊不同生命週期的服務
services.AddSingleton<IMySingletonService, MySingletonService>();
services.AddScoped<IMyScopedService, MyScopedService>();
services.AddTransient<IMyTransientService, MyTransientService>();
#endregion

2.常規服務的“花式”註冊:

services.AddSingleton<IOrderService>(new OrderService());  //直接注入實例
//同接口(IOrderService)不同實例(OrderServiceEx,OrderService)註冊
services.AddSingleton<IOrderService, OrderServiceEx>(); 
services.AddSingleton<IOrderService, OrderService>();

//匿名方式註冊,可實現具體服務攔截
services.AddSingleton<IOrderService>(serviceProvider =>
{
    return new OrderServiceEx(); //serviceProvider 對象可用
});

services.AddScoped<IOrderService>(serviceProvider =>
{
    return new OrderServiceEx();
});

3.嘗試(或試圖)註冊:

services.TryAddSingleton<IOrderService, OrderServiceEx>(); //服務被註冊就不是再次註冊,反之就註冊;

//相同類型的服務接口,如果實現不同即可註冊,實現相同就不會註冊
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(new OrderServiceEx()));
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(p =>
{
    return new OrderServiceEx();
}));

//嘗試或試圖註冊的好處:避免重複的服務接口註冊或者控制同接口不同實現的服務註冊;

4.移除和替換註冊:

services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>()); //指定原有接口服務的註冊,替換(或更改)爲現有接口服務實現;
services.RemoveAll<IOrderService>(); //移除所有的接口服務註冊的實例;

5.泛型模板模板註冊:

services.AddSingleton(typeof(IGenericService<>), typeof(GenericService<>));

//使用方式,Controller構造函數注入
IOrderService _orderService;
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger, IOrderService orderService, IGenericService<IOrderService> genericService)
{
   _orderService = orderService; //泛型模板構造函數注入使用
   _logger = logger;
}

三、兩種依賴注入的實例獲取方法:

1.默認構造函數注入服務使用,通常是接口服務實例的全部使用;(類似如上泛型模板註冊)

2.[FromServices]局部方法注入服務使用,通常指依賴使用某個服務中的一個方法使用;

[HttpGet]
public int GetService([FromServices]IMySingletonService singleton1,
                      [FromServices]IMySingletonService singleton2,
                      [FromServices]IMyTransientService transient1,
                      [FromServices]IMyTransientService transient2,
                      [FromServices]IMyScopedService scoped1,
                      [FromServices]IMyScopedService scoped2)
{
      Console.WriteLine($"singleton1:{singleton1.GetHashCode()}");
      Console.WriteLine($"singleton2:{singleton2.GetHashCode()}");

      Console.WriteLine($"transient1:{transient1.GetHashCode()}");
      Console.WriteLine($"transient2:{transient2.GetHashCode()}");

      Console.WriteLine($"scoped1:{scoped1.GetHashCode()}");
      Console.WriteLine($"scoped2:{scoped2.GetHashCode()}");

      Console.WriteLine($"========請求結束=======");
      return 1;
}

public int GetServiceList([FromServices]IEnumerable<IOrderService> services)
{
    foreach (var item in services)
    {
       Console.WriteLine($"獲取到服務實例:{item.ToString()}:{item.GetHashCode()}");
    }
    return 1;
}

asp.net core 裏面的依賴注入,原理介紹見上一篇(ASP.NET Core 2.0系列學習筆記-DI依賴注入):https://blog.csdn.net/ChaITSimpleLove/article/details/79402008

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章