一、 ASP.NET Core本身自帶IOC容器
ASP.NET Core本身已經集成了一個輕量級的IOC容器,開發者只需要定義好接口後,在Startup.cs的ConfigureServices方法裏使用對應生命週期的綁定方法即可,常見方法如下
1 services.AddTransient<IApplicationService,ApplicationService> 2 3 services.AddScoped<IApplicationService,ApplicationService> 4 5 services.AddSingleton<IApplicationService,ApplicationService>
對於上述的三種DI注入方式,
- Transient
Transient 服務在每次請求時被創建,它最好被用於輕量級無狀態服務(如我們的Repository和ApplicationService服務) - Scoped
Scoped 服務在每次請求時被創建,生命週期橫貫整次請求 - Singleton
顧名思義,Singleton(單例) 服務在第一次請求時被創建(或者當我們在ConfigureServices中指定創建某一實例並運行方法),其後的每次請求將沿用已創建服務。如果開發者的應用需要單例服務情景,請設計成允許服務容器來對服務生命週期進行操作,而不是手動實現單例設計模式然後由開發者在自定義類中進行操作。 - 此段說明來源於:https://www.cnblogs.com/Wddpct/p/5764511.html
如果我們使用自帶的容器,代碼看起來更加的清晰,但是如果接口類過多的情況,就會出現如下圖,每一個接口和實現都需要去"手動"注入,如果一旦漏掉注入,就會導致項目無法正確的運行等情況。
二、AutoFac批量注入
1、安裝AutoFac注入需要的包
2、新建一個AutoFacxxxx或者其他名稱的配置/注入文件
1 private static object _lock = new object(); 2 /// <summary> 3 /// //創建一個新IOC容器 4 /// </summary> 5 private static IContainer _container; 6 /// <summary> 7 /// AutoFac的容器 判斷是否存在,存在就直接使用,不存在就創建 8 /// </summary> 9 /// <param name="svrName">服務程序集名稱</param> 10 /// <returns></returns> 11 public static IServiceProvider Register(IServiceCollection services, string[] svrNames) 12 { 13 if (_container == null) 14 { 15 lock (_lock) 16 { 17 if (_container == null) 18 { 19 // IOC容器註冊 構造一個AutoFac的builder容器 20 ContainerBuilder builder = new ContainerBuilder(); 21 builder.Populate(services); 22 List<Type> types = new List<Type>(); 23 foreach (string item in svrNames) 24 { 25 // 加載接口服務實現層。 26 Assembly SvrAss = Assembly.Load(item); 27 // 反射掃描這個程序集中所有的類,得到這個程序集中所有類的集合。 28 types.AddRange(SvrAss.GetTypes()); 29 } 30 // 告訴AutoFac容器,創建stypes這個集合中所有類的對象實例 在一次Http請求上下文中,共享一個組件實例 31 Autofac.Builder.IRegistrationBuilder<object, Autofac.Features.Scanning.ScanningActivatorData, Autofac.Builder.DynamicRegistrationStyle> register = builder.RegisterTypes(types.ToArray()).AsImplementedInterfaces().InstancePerLifetimeScope().PropertiesAutowired();//指明創建的stypes這個集合中所有類的對象實例,以其接口的形式保存 32 33 //創建一個真正的AutoFac的工作容器 34 _container = builder.Build(); 35 } 36 } 37 } 38 return new AutofacServiceProvider(_container); 39 }
3、Statup的調用,需要修改原始 ConfigureServices的返回類型爲IServiceProvider
///支持多個Service注入
return AutoFacConfig.Register(services, new string[] { "Business.Service", "Business.Services" });
三、代碼實例
1、項目結構
2、Model層
public class Student { public int StuNo { get; set; } public string StuName { get; set; } public int StuAge { get; set; } }
3、Interface-》IStudentService
public interface IStudentService { List<Student> GetStudentList(); }
4、Service->StudentService
public class StudentService : IStudentService { public List<Student> GetStudentList() { List<Student> list = new List<Student>(); list.Add(new Student() { StuNo = 1, StuAge = 18, StuName = "張三" }); list.Add(new Student() { StuNo = 1, StuAge = 17, StuName = "王麻子" }); return list; } }
5、Controller->StudentController
[Route("api/[controller]")] [ApiController] public class StudentController : ControllerBase { IStudentService _studentService; /// <summary> /// 構造函數注入 /// </summary> /// <param name="studentService"></param> public StudentController(IStudentService studentService) { _studentService = studentService; } public object GetStudent() { var list = _studentService.GetStudentList(); return list; } }
6、運行結果