一、 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、运行结果