asp.net core服務的生命週期

風靈使發表於2018-07-27
  • Transient:每一次GetService都會建立一個新的例項
  • Scoped:在同一個Scope內只初始化一個例項 ,可以理解為( 每一個request級別只建立一個例項,同一個http request會在一個 scope內)
  • Singleton:整個應用程式生命週期內只建立一個例項

上面描述的比較抽象,不容易理解,用例項來講解會比較直觀。

下面通過具體的例子進行演示。

定義三個空的介面:IArticleService、IProductService、IUserService

然後定義三個實現:ArticleService、ProductService、UserService

1.將介面和實現注入到DI容器

StartUp類的ConfigureServices方法新增下圖程式碼

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.Configure<Test>(Configuration.GetSection("Test"));

            //演示生命週期
            services.AddTransient<IUserService, UserService>();
            services.AddScoped<IArticleService, ArticleService>();
            services.AddSingleton<IProductService, ProductService>();
        }

2.新增私有欄位,在測試Controller:LifeTimeController中新增下圖程式碼

        private readonly IUserService _userService1;
        private readonly IUserService _userService2;
        private readonly IArticleService _articleService1;
        private readonly IArticleService _articleService2;
        private readonly IProductService _productService1;
        private readonly IProductService _productService2;

3.新增構造方法

        public LifeTimeController(
            IUserService userService1, IUserService userService2,
            IArticleService articleService1, IArticleService articleService2,
            IProductService productService1, IProductService productService2
        )
        {
            _userService1 = userService1;
            _userService2 = userService2;
            _articleService1 = articleService1;
            _articleService2 = articleService2;
            _productService1 = productService1;
            _productService2 = productService2;
        }

4.新增測試程式碼

        public IActionResult Index()
        {
            var sb = new StringBuilder();
            sb.Append("transient1:" + _userService1.GetHashCode() + "<br />");
            sb.Append("transient2:" + _userService2.GetHashCode() + "<br />");
            sb.Append("scope1:" + _articleService1.GetHashCode() + "<br />");
            sb.Append("scope2:" + _articleService2.GetHashCode() + "<br />");
            sb.Append("singleton1:" + _productService1.GetHashCode() + "<br />");
            sb.Append("singleton2:" + _productService2.GetHashCode() + "<br />");
            
            Response.ContentType = "text/html";
            return Content(sb.ToString());
        }

5.執行結果

第一次重新整理:

transient1:66454027
transient2:35021870
scope1:38350037
scope2:38350037
singleton1:4417230
singleton2:4417230

第二次重新整理:

transient1:103653
transient2:5079042
scope1:47546512
scope2:47546512
singleton1:4417230
singleton2:4417230

可見

  • transient型別的生命週期,每次使用都不一樣,不同的類或不同的方法使用都不一樣
  • scope型別的生命週期,在同一個請求內是一樣的
  • singleton型別的生命週期,每次請求都是一樣的

所以理解了生命週期的作用,我們在開發的時候就可以根據需要對不同的服務選擇不同的生命週期了。

相關文章