ASP.NET Core 服务
枚举出程序中已添加的服务
Asp.Net Core 项目中的“服务”,指的是用于扩展应用程序功能的一系列类型。
在程序初始化期间,会把需要的服务类型实例添加到ServiceCollection集合中,这些服务实例将通过依赖注入提供给其他代码使用。
下面遍历一下已添加的服务:
public static void Main(string[] args) { var host = new WebHostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) .UseKestrel() .UseStartup<Startup>() .Build(); host.Run(); }
public void ConfigureServices(IServiceCollection services) { foreach (var sv in services) { string msg = $"服务类型:{sv.ServiceType?.Name ?? "<无>"}"; msg += $",实现类型:{sv.ImplementationType?.Name ?? "<无>"}"; Console.WriteLine(msg); } } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); }
结果:
服务类型:IOptionsSnapshot`1,实现类型:OptionsManager`1 服务类型:IOptionsMonitor`1,实现类型:OptionsMonitor`1 服务类型:IOptionsFactory`1,实现类型:OptionsFactory`1 服务类型:IOptionsMonitorCache`1,实现类型:OptionsCache`1 服务类型:ILoggerFactory,实现类型:LoggerFactory 服务类型:ILogger`1,实现类型:Logger`1 服务类型:IConfigureOptions`1,实现类型:<无> 服务类型:IStartupFilter,实现类型:AutoRequestServicesStartupFilter 服务类型:IServiceProviderFactory`1,实现类型:DefaultServiceProviderFactory 服务类型:ObjectPoolProvider,实现类型:DefaultObjectPoolProvider 服务类型:ITransportFactory,实现类型:SocketTransportFactory 服务类型:IConfigureOptions`1,实现类型:KestrelServerOptionsSetup 服务类型:IServer,实现类型:KestrelServer 服务类型:IStartup,实现类型:<无> 服务类型:DiagnosticListener,实现类型:<无> 服务类型:DiagnosticSource,实现类型:<无> 服务类型:IApplicationLifetime,实现类型:ApplicationLifetime 服务类型:IApplicationLifetime,实现类型:<无> 服务类型:HostedServiceExecutor,实现类型:HostedServiceExecutor
服务类型
编写服务类型有三种方案:
(1)接口实现形式;
(2)抽象类实现形式;
(3)直接定义类形式;
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IService1, MyService1>(); // 接口实现 services.AddSingleton<ServiceBase, MyService2>(); // 抽象类实现 services.AddSingleton<MyService3>(); // 直接定义类 }
服务生命周期
服务类型添加到ServiceCollection
容器后,其生命周期将由框架自动管理。
容器中存在三种服务生命周期:
(1)暂时服务:通过调用AddTransient
方法添加。服务生命周期最短,每次被请求都会实例化一次,属于轻量级服务。就算在同一请求中多次访问,暂时服务每次都会实例化。
(2)作用域服务:通过调用AddScoped
方法添加。这个范围是单个请求中,不管被请求多少次,都只实例化一次。
(3)单例服务:通过调用AddSingleton
方法添加。它在整个应用程序运行期间不管多少次请求只创建一个实例。
- 实例:
Asp.Net Core Web应用程序项目中,先声明一个ServiceBase类,作为三个服务的共同基类,主要作用是产生新的Guid。
public class ServiceBase { public Guid ID { get; } protected ServiceBase() { ID = Guid.NewGuid(); } }
ServiceBase派生三个类,代表三个服务。
public sealed class ServiceA : ServiceBase { } public sealed class ServiceB : ServiceBase { } public sealed class ServiceC : ServiceBase { }
再定义一个类,用来在构造函数中接收来自前三个服务的注入。
public class ServiceDependencyAll { public ServiceDependencyAll(ServiceA sva, ServiceB svb, ServiceC svc) { Service_A = sva; Service_B = svb; Service_C = svc; } public ServiceBase Service_A { get; } public ServiceBase Service_B { get; } public ServiceBase Service_C { get; } }
定义Demo控制器,在其构造函数中注入四个服务。Check方法作为MVC中的Action。
public class DemoController : Controller { private readonly ServiceA _serviceA = null; private readonly ServiceB _serviceB = null; private readonly ServiceC _serviceC = null; private readonly ServiceDependencyAll _serviceDep = null; public DemoController(ServiceA a, ServiceB b, ServiceC c,ServiceDependencyAll d) { _serviceA = a; _serviceB = b; _serviceC = c; _serviceDep = d; } public IActionResult Check() { List<string> strLines = new List<string>(); strLines.Add($"暂时服务:{_serviceA.ID}"); strLines.Add($"作用域服务:{_serviceB.ID}"); strLines.Add($"单一实例服务:{_serviceC.ID}"); strLines.Add(string.Empty); strLines.Add("存在依赖关系的服务:"); strLines.Add($"暂时服务:{_serviceDep.Service_A.ID}"); strLines.Add($"作用域服务:{_serviceDep.Service_B.ID}"); strLines.Add($"单一实例服务:{_serviceDep.Service_C.ID}"); return View("~/DemoView.cshtml", strLines); } }
DemoView.cshtml页面。
@model IList<string> <html> <body> <div> @{ foreach (string line in Model) { @line <br/> } } </div> </body> </html>
把前面定义的四个服务都添加到服务容器中。
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddTransient<ServiceA>(); services.AddScoped<ServiceB>(); services.AddSingleton<ServiceC>(); services.AddTransient<ServiceDependencyAll>(); }
运行程序,在浏览器(我的是 http://localhost:54450/Demo/Check )中访问。进行三次请求,观察生成的Guid。
第一次:
暂时服务:baeee348-a41e-43fa-bd9f-cb8b97813e45 作用域服务:acc22a18-eef9-45c5-a216-3c0adbe4d453 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7 存在依赖关系的服务: 暂时服务:d68e412a-85b2-4e1c-9ab5-3fea97a44a23 作用域服务:acc22a18-eef9-45c5-a216-3c0adbe4d453 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7
第二次:
暂时服务:b5627905-175f-4691-b691-1afb85a534ff 作用域服务:96cd6e17-dd7b-47e4-a407-25564082e194 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7 存在依赖关系的服务: 暂时服务:2ea9b719-2e68-4136-972b-a6a3e67729d6 作用域服务:96cd6e17-dd7b-47e4-a407-25564082e194 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7
第三次:
暂时服务:85d4da68-2d52-47db-aca8-01b63f89bb5d 作用域服务:a8ac3436-b53a-46be-b467-ea0474516783 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7 存在依赖关系的服务: 暂时服务:10783740-2e4e-41ee-91c7-22f75713366e 作用域服务:a8ac3436-b53a-46be-b467-ea0474516783 单一实例服务:79fd5729-b651-4f4d-9a40-35ed42a393e7
结果可以看出,在同一次请求中,作用域服务被访问了两次,但Guid是相同的,说明它在同一请求范围内只创建了一个实例;而暂时服务不管什么范围内每次都会创建;单例始终不变,说明在整个应用程序中只创建了一个实例。
本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/15402053.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2019-10-13 lamda表达式写GroupBy分组查询
2019-10-13 丰桃之秋