• 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

  • 相关阅读:
    bzoj千题计划202:bzoj3191: [JLOI2013]卡牌游戏
    bzoj千题计划201:bzoj1820: [JSOI2010]Express Service 快递服务
    bzoj千题计划200:bzoj3106: [cqoi2013]棋盘游戏
    bzoj千题计划199:bzoj1055: [HAOI2008]玩具取名
    NOIP2017 小凯的疑惑
    Codeforces 837E. Vasya's Function
    bzoj1084: [SCOI2005]最大子矩阵
    bzoj4247: 挂饰
    Codeforces Round #276 (Div. 1) A. Bits
    bzoj千题计划196:bzoj4826: [Hnoi2017]影魔
  • 原文地址:https://www.cnblogs.com/nullcodeworld/p/15402053.html
Copyright © 2020-2023  润新知