Asp.Net Core入门之自定义服务注册
谈到服务注册,首先我们先了解一下服务注册时使用的三种方式,也代表了不同的服务生命周期:
1 AddTransient 2 AddScoped 3 AddSingleton
AddSingleton生命周期最长,其生命周期范围描述为:从应用程序启动到应用程序结束。在第一次请求时会创建一个实例,之后的每次请求都会使用同一个实例。
AddTransient生命周期最短,在服务请求时会创建一个实例,服务请求结束生命周期即结束,之后的每一次请求都会创建不同的实例。
AddScoped生命周期介于上述两者之间,这里用客户端请求会话的概念来描述比较清晰一点,它也是在服务请求时创建实例,但是在同一个会话周期内,之后的每次请求都会使用同一个实例,直至会话结束才会创建新的实例。
ASP.Net Core框架支持我们以如下方式注册我们自己的服务。
services.AddScoped<ITest, Test>();
其中第一个泛型类型(如:ITest)表示将要从容器中请求的类型(通常是一个接口)。第二个泛型类型(如:Test)表示将由容器实例化并且用于完成这些请求的具体实现类。
具体我们一起看下面的例子:
首先,我们创建一个需要实现查询功能的服务接口ITest
public interface ITest { Task<string> Get(); }
然后,我们创建功能类Test实现这个接口
1 public class Test : ITest 2 { 3 private readonly ILogger logger; 4 public Test(ILogger<Test> _logger) 5 { 6 logger = _logger; 7 } 8 public Task<string> Get() 9 { 10 logger.LogInformation("自定义服务查询"); 11 return Task.FromResult("Hello World"); 12 } 13 }
最后,我们需要我们自己的服务注册到容器中。
public void ConfigureServices(IServiceCollection services) { services.AddScoped<ITest, Test>(); }
以上我们便简单完成了自定义服务的注册。
随后我这里创建了一个Controller用以使用该服务。
1 [Route("api/[controller]")] 2 [ApiController] 3 public class ValuesController : ControllerBase 4 { 5 //声明服务 6 private readonly ITest service; 7 8 /// <summary> 9 /// 通过构造函数的方式注入自定义服务类 10 /// </summary> 11 /// <param name="_service"></param> 12 public ValuesController(ITest _service) 13 { 14 service = _service; 15 } 16 17 /// <summary> 18 /// 调用服务中实现的Get方法 19 /// </summary> 20 /// <returns></returns> 21 [HttpGet] 22 public Task<string> Get() 23 { 24 return service.Get(); 25 } 26 }
ASP.Net Core框架默认支持我们以构造函数的方式注入我们的服务以使用。
我想写到这里,大家也会有疑问,如果我们有很多service,这样一个个注册写起来代码很低效,这里我们简单给大家介绍一种批量注册的方式:
这里我们创建了一个批量注册服务派生类:
1 public static class ServiceExtensions 2 { 3 /// <summary> 4 /// 批量注册程序集下的服务类 5 /// </summary> 6 /// <param name="services"></param> 7 public static IServiceCollection AddBatchServices(this IServiceCollection services) 8 { 9 //根据指定程序集名称获取待注册服务 10 var batchServices = GetConfigureClass("WebApiApplication"); 11 foreach (var type in batchServices) 12 { 13 type.Value.ToList().ForEach(i => 14 { 15 //注册服务类 16 services.AddScoped(i, type.Key); 17 }); 18 } 19 return services; 20 } 21 22 /// <summary> 23 /// 根据程序集名称获取自定义服务 24 /// </summary> 25 /// <param name="assembly"></param> 26 /// <returns></returns> 27 public static Dictionary<Type, Type[]> GetConfigureClass(string assembly) 28 { 29 Dictionary<Type, Type[]> dic = new Dictionary<Type, Type[]>(); 30 if (!string.IsNullOrEmpty(assembly)) 31 { 32 //获取程序集对应的类型 33 Assembly dll = Assembly.LoadFrom(assembly); 34 List<Type> lstType = dll.GetTypes().ToList(); 35 lstType.ForEach(x => 36 { 37 //筛选满足条件的服务类 38 if (x.IsClass && x.GetInterfaces().Length > 0) 39 { 40 dic.Add(x, x.GetInterfaces()); 41 } 42 }); 43 } 44 return dic; 45 } 46 }
然后我们ConfigureServices方法中注册:
public void ConfigureServices(IServiceCollection services) { //批量注册 services.AddBatchServices(); }
对于批量注册,ASP.Net Core允许我们更换默认的IOC容器,感兴趣的同学可以试试AutoFac容器支持的程序集扫描式注册。
注册我们自己的服务,往往在项目开发过程中是必要的,希望以上简单的分享能给需要的小伙伴们带来一点收货。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构