谈到服务注册, 首先我们先了解一下服务注册时使用的三种方式, 也代表了不同的服务生命周期:
- AddTransient
- AddScoped
- AddSingleton
AddSingleton 生命周期最长, 其生命周期范围描述为: 从应用程序启动到应用程序结束. 在第一次请求时会创建一个实例, 之后的每次请求都会使用同一个实例.
AddTransient 生命周期最短, 在服务请求时会创建一个实例, 服务请求结束生命周期即结束, 之后的每一次请求都会创建不同的实例.
AddSingleton 生命周期介于上述两者之间, 这里用客户端请求会话的概念来描述比较清晰一点, 它也是在服务请求时创建实例, 但是在同一个会话周期内, 之后的每次请求都会使用同一个实例, 直至会话结束才会创建新的实例.
ASP.NET Core 框架支持我们以如下方式注册我们自己的服务.
services.AddScoped<ITest, Test>();
其中第一个泛型类型 (如: ITest) 表示将要从容器中请求的类型 (通常是一个接口). 第二个泛型类型(如: Test) 表示将由容器实例化并且用于完成这些请求的具体实现类.
具体我们一起看下面的例子:
首先, 我们创建一个需要实现查询功能的服务接口 ITest
- public interface ITest
- {
- Task<string> Get();
- }
然后, 我们创建功能类 Test 实现这个接口
- public class Test : ITest
- {
- private readonly ILogger logger;
- public Test(ILogger<Test> _logger)
- {
- logger = _logger;
- }
- public Task<string> Get()
- {
- logger.LogInformation("自定义服务查询");
- return Task.FromResult("Hello World");
- }
- }
最后, 我们需要我们自己的服务注册到容器中.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddScoped<ITest, Test>();
- }
以上我们便简单完成了自定义服务的注册.
随后我这里创建了一个 Controller 用以使用该服务.
- [Route("api/[controller]")]
- [ApiController]
- public class ValuesController : ControllerBase
- {
- // 声明服务
- private readonly ITest service;
- /// <summary>
- /// 通过构造函数的方式注入自定义服务类
- /// </summary>
- /// <param name="_service"></param>
- public ValuesController(ITest _service)
- {
- service = _service;
- }
- /// <summary>
- /// 调用服务中实现的 Get 方法
- /// </summary>
- /// <returns></returns>
- [HttpGet]
- public Task<string> Get()
- {
- return service.Get();
- }
- }
ASP.NET Core 框架默认支持我们以构造函数的方式注入我们的服务以使用.
我想写到这里, 大家也会有疑问, 如果我们有很多 service, 这样一个个注册写起来代码很低效, 这里我们简单给大家介绍一种批量注册的方式:
这里我们创建了一个批量注册服务派生类:
- public static class ServiceExtensions
- {
- /// <summary>
- /// 批量注册程序集下的服务类
- /// </summary>
- /// <param name="services"></param>
- public static IServiceCollection AddBatchServices(this IServiceCollection services)
- {
- // 根据指定程序集名称获取待注册服务
- var batchServices = GetConfigureClass("webApiApplication");
- foreach (var type in batchServices)
- {
- type.Value.ToList().ForEach(i =>
- {
- // 注册服务类
- services.AddScoped(i, type.Key);
- });
- }
- return services;
- }
- /// <summary>
- /// 根据程序集名称获取自定义服务
- /// </summary>
- /// <param name="assembly"></param>
- /// <returns></returns>
- public static Dictionary<Type, Type[]> GetConfigureClass(string assembly)
- {
- Dictionary<Type, Type[]> dic = new Dictionary<Type, Type[]>();
- if (!string.IsNullOrEmpty(assembly))
- {
- // 获取程序集对应的类型
- Assembly dll = Assembly.LoadFrom(assembly);
- List<Type> lstType = dll.GetTypes().ToList();
- lstType.ForEach(x =>
- {
- // 筛选满足条件的服务类
- if (x.IsClass && x.GetInterfaces().Length> 0)
- {
- dic.Add(x, x.GetInterfaces());
- }
- });
- }
- return dic;
- }
- }
然后我们 ConfigureServices 方法中注册:
- public void ConfigureServices(IServiceCollection services)
- {
- // 批量注册
- services.AddBatchServices();
- }
对于批量注册, ASP.NET Core 允许我们更换默认的 IoC 容器, 感兴趣的同学可以试试 AutoFac 容器支持的程序集扫描式注册.
注册我们自己的服务, 往往在项目开发过程中是必要的, 希望以上简单的分享能给需要的小伙伴们带来一点收货.
来源: https://www.cnblogs.com/chenxf1117/p/12970731.html