<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET Core 依賴注入基本用法

      ASP.NET Core 依賴注入

      ASP.NET Core從框架層對依賴注入提供支持。也就是說,如果你不了解依賴注入,將很難適應 ASP.NET Core的開發模式。本文將介紹依賴注入的基本概念,并結合代碼演示如何在 ASP.NET Core中使用依賴注入。

      什么是依賴注入?

      百度百科對于依賴注入的介紹:

      控制反轉(Inversion of Control,縮寫為IoC),是面向對象編程中的一種設計原則,可以用來減低計算機代碼之間的耦合度。其中最常見的方式叫做依賴注入(Dependency Injection,簡稱DI),還有一種方式叫“依賴查找”(Dependency Lookup)。通過控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體將其所依賴的對象的引用傳遞給它。也可以說,依賴被注入到對象中。

      從百科的介紹中可以看出,依賴注入和控制反轉是一回事,依賴注入是一種新的設計模式,通過正確使用依賴注入的相關技術,可以降低系統耦合度,增加系統的可擴展性。

      我們來看一個例子:

      public interface IInterfaceA
      { }
      
      public interface IInterfaceB
      { }
      
      public class ClassA : IInterfaceA
      {
          private IInterfaceB B { get; set; }
      
          public ClassA(IInterfaceB b)
          {
              this.B = b;
          }
      }
      
      public class ClassB : IInterfaceB
      { }
      

      這個時候,如果我們想要獲取IInterfaceA的實例,如果不采用依賴注入,我們的做法通常是這樣的:

      IInterfaceB b = new ClassB();
      IInterfaceA a = new ClassA(b);
      

      這個時候IInterfaceA的控制權,在實例化的時候就已經被限定死了,沒有任何想象空間,就是ClassA的實例,并且我們還要手工的初始化IInterfaceB,同樣B的控制權也被限定死了。這樣的代碼毫無設計、也極不利于擴展。

      如果采用依賴注入,我們看一下代碼:

      var a = container.GetService<IInterfaceA>();
      

      這個時候接口A和B的控制權是由容器來控制的,我們可以通過向容器中注入不同的接口實現來擴展系統的靈活性,由于將控制權交給了IoC容器,我們還可以通過配置的方式靈活的控制對象的生命周期,這一點也是手工創建對象無法實現的。

      控制反轉的關系圖如下(圖片來源于官網):
      image

      ASP.NET Core中的依賴注入

      上面介紹了依賴注入的基本概念,那么在 ASP.NET Core中,我們該如何使用依賴注入呢?在 ASP.NET Core中已經內置了一套依賴注入的容器,我們可以直接使用。

      在Startup.ConfigureServices中添加我們要注冊的服務和實現,添加的時候可以對服務的生命周期進行相應的配置,然后就可以在PageModel、Controller、Views等需要的地方使用了。

      下面的示例將演示如何注冊服務,代碼來源于官網。首先要定義一個服務接口,并實現這個接口:

      public interface IMyDependency
      {
          Task WriteMessage(string message);
      }
      
      public class MyDependency : IMyDependency
      {
          private readonly ILogger<MyDependency> _logger;
      
          public MyDependency(ILogger<MyDependency> logger)
          {
              _logger = logger;
          }
      
          public Task WriteMessage(string message)
          {
              _logger.LogInformation(
                  "MyDependency.WriteMessage called. Message: {MESSAGE}", 
                  message);
      
              return Task.FromResult(0);
          }
      }
      

      然后我們進行服務注冊:

      public void ConfigureServices(IServiceCollection services)
      {
          services.AddScoped<IMyDependency, MyDependency>();
          services.AddMvc();
      }
      
      

      這里我們添加了IMyDependency的注冊,同時也添加了使用Mvc所需要的服務的注冊。這里有兩個問題需要說明:

      • AddScoped是添加一個服務注冊,Scoped是該服務的生命周期,表示按照作用于創建該服務,如果作用域中多次使用到該服務,則只創建一個對象。比如每一個HTTP請求都是一個作用域,那么在這個請求處理過程中,容器只會創建一個對象。與Scoped對應的還有其它的生命周期,我們將服務的生命周期列舉如下:
      • Transient:瞬時服務,表示每次使用都會創建新的對象
      • Scoped:作用域服務,表示每次請求只創建一個對象。這里需要特殊說明一下,如果你的服務是一個中間件,不受此約束,因為中間件都是強制單例的。如果要在中間件中使用Scoped服務,則需要將服務注入到Invoke或InvokeAsync方法的參數中,此處可以參考 ASP.NET Core 中間件基本用法
      • Singleton:單例服務,表示每個應用程序域只會創建一個實力。
      • 基于約定,ASP.NET Core推薦我們采用類似于Add{SERVICE_NAME}的方式添加服務的注冊,比如services.AddMvc(),這種方式可以通過擴展方法來實現,代碼如下:
      namespace Microsoft.Extensions.DependencyInjection
      {
          public static partial class MyDependencyExtensions
          {
              public static IServiceCollection AddMyDependency(this IServiceCollection services)
              {
                  return services.AddScoped<IMyDependency, MyDependency>();
              }
          }
      }
      

      使用依賴注入

      在了解了依賴注入的基本用法之后,我們現在來了解一下如何將服務注入到Controller、Views中。

      在控制器中注入服務

      最常規的用法是采用構造函數注入的方式,將一個服務注入到控制器中,代碼如下:

      public class DefaultController : Controller
      {
          private readonly ILogger<DefaultController> logger;
      
          public DefaultController(ILogger<DefaultController> logger)
          {
              this.logger = logger;
          }
      }
      

      構造函數注入是最常用的注入方式,這種方式要求依賴者提供公有的構造函數,并將依賴項通過構造函數的方式傳入依賴者,完成對依賴項的賦值。

      除此之外,還可以通過參數注入的方式,將依賴項注入到Action中,這里使用到FromServices特性:

      public IActionResult Index([FromServices]ILogger<DefaultController> logger)
      {
          throw new NotImplementedException();
      }
      

      ASP.NET Core 提供了這種支持,但是作者并不推薦這種操作

      在視圖中注入服務

      ASP.NET Core 支持將依賴關系注入到視圖,代碼如下:

      @using Microsoft.Extensions.Configuration
      @inject IConfiguration Configuration
      @{
         string myValue = Configuration["root:parent:child"];
         ...
      }
      

      上面的代碼演示了將IConfiguration服務注入到視圖中,從而實現在視圖中讀取配置的功能。

      有時候將服務注入到視圖中會很有用(例如本地化),但是作者也并不是很推薦這種做法,因為這樣做容易造成視圖和控制器的邊界不清晰。

      在PageModel中注入服務

      在PageModel中注入服務的方式,與在Controller中注入服務的方式相似:

      public class IndexModel : PageModel
      {
          private readonly IMyDependency _myDependency;
      
          public IndexModel(IMyDependency myDependency)
          {
              _myDependency = myDependency;
          }
      }
      

      在main方法中獲取服務

      public static void Main(string[] args)
      {
          var host = CreateWebHostBuilder(args).Build();
      
          using (var serviceScope = host.Services.CreateScope())
          {
              var services = serviceScope.ServiceProvider;
      
              try
              {
                  var serviceContext = services.GetRequiredService<MyScopedService>();
                  // Use the context here
              }
              catch (Exception ex)
              {
                  var logger = services.GetRequiredService<ILogger<Program>>();
                  logger.LogError(ex, "An error occurred.");
              }
          }
      
          host.Run();
      }
      

      在HttpContext.RequestServices中獲取服務

      這種方式不利于測試,不推薦此種用法。

      雖然優先推薦通過構造函數的方式注入來獲取服務,但是很難避免有些時候需要手工獲取服務,在使用手工獲取服務的時候,我們應當從HttpContext.RequestServices中獲取。

      使用第三方依賴注入框架

      ASP.NET Core內置的依賴注入框架功能有限,當我們想使用第三方框架的特性時,我們可以替換默認依賴注入框架。

      ASP.NET Core內置的依賴注入框架未包含的特性:

      • 屬性注入
      • 基于名稱的注入
      • 子容器
      • 自定義生命周期管理
      • 對lazy對象初始化的Func支持

      如果要是用這些功能,我們可以使用第三方框架。本文采用官方文檔中的Autofac框架。

      • 首先添加 Autofac、Autofac.Extensions.DependencyInjection 的引用
      • 在Startup.ConfigureServices中配置容器,并返回IServiceProvider。在使用第三方容器時,必須返回IServiceProvider。
      public IServiceProvider ConfigureServices(IServiceCollection services)
      {
          services.AddMvc();
          // Add other framework services
      
          // Add Autofac
          var containerBuilder = new ContainerBuilder();
          containerBuilder.RegisterModule<DefaultModule>();
          containerBuilder.Populate(services);
          var container = containerBuilder.Build();
          return new AutofacServiceProvider(container);
      }
      
      • 配置Autofac的Module,用來注冊服務等
      public class DefaultModule : Module
      {
          protected override void Load(ContainerBuilder builder)
          {
              builder.RegisterType<CharacterRepository>().As<ICharacterRepository>();
          }
      }
      

      參考資料

      posted @ 2019-05-26 17:15  拓荒者IT  閱讀(9674)  評論(4)    收藏  舉報
      皮膚配置 參考地址:https://www.yuque.com/awescnb/user
      主站蜘蛛池模板: 好紧好湿好黄的视频| 97精品国产91久久久久久久| 自拍偷在线精品自拍偷免费| 欧美日韩另类国产| 亚洲av永久无码精品水牛影视 | 日韩成av在线免费观看| 精品人妻中文字幕在线| 午夜免费视频国产在线| 免费无码又爽又刺激高潮虎虎视频 | 欧美日本在线一区二区三区| 国产美女高潮流白浆视频| 99久久国产精品无码| 黄色A级国产免费大片视频| 国产乱子伦精品免费无码专区| 亚洲成亚洲成网| 国产三级精品三级在线看| 老司机性色福利精品视频| 色噜噜狠狠成人综合| 老熟妇老熟女老女人天堂| 无遮无挡爽爽免费视频| 亚洲第一极品精品无码久久| 国产一区二区三区美女| 东方av四虎在线观看| 国产精品一区中文字幕| 国产精品夫妇激情啪发布| 欧洲一区二区中文字幕| 久久婷婷成人综合色| 国产精品成人午夜久久| 亚洲偷自拍国综合| 亚洲精品中文字幕无码蜜桃| 中文日产幕无线码一区中文| 国产成人AV国语在线观看| 性色av极品无码专区亚洲| 欧美一区二区三区性视频| 亚洲精品日韩中文字幕| 亚洲成在人线在线播放无码 | 日本人一区二区在线观看| 国产中文字幕日韩精品| 国产日韩精品欧美一区喷水| 日本不卡的一区二区三区| 日产国产一区二区不卡|