ASPNET5的依賴注入

ASP.NET5設計的時候就是以DI為基礎的,它可以利用內建的框架在Startup類的方法中,把依賴注入進去。應用服務也可以被配置的注入。默認的服務容器提供一些基本的功能,它并不打算代替現代主流的DI框架。

1. 什么是Dependency Injection?

DI的概念相信大家已經了解了,不了解的可以查一下資料。我們來講一講ASP.NET 5內建的DI容器。

ASP.NET5包含一個簡單的內建容器,它的表現形式是IServiceProvider接口, 默認支持構造函數的注入,ASP.NET通過它注入相關的服務類。ASP.NET的容器引用的類型,在它里面叫做服務,在下面的內容當中,服務就當然于ASP.NET Ioc容器當中管理的類型。你可以通過Startup類中的CongureServices注入內建的服務。

2. 構架提供的服務

Startup類中的ConfigureServices方法定義了應用程序需要的服務,像Entity Framework, MVC等,它由IServiceCollection的擴展方法來添加. 例如:

public void ConfigureServices(IServiceCollection services)

{

  services.AddEntityFramework().AddSqlServer().AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

  services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();

????? servies.AddMvc();

????? services.AddTransient<IEmailSender, AuthMessageSender>();

  services.AddTransient<ISmsSender, AuthMessageSender>();

}

3. 注冊你自己的服務

上面的代碼當中:

services.AddTransient<IEmailSender, AuthMessageSender>();

services.AddTransient<ISmsSender, AuthMessageSender>();

AddTransient方法用來添加抽象類型到具體的類型映射,并且申明了它的生命周期,在你注冊服務時,選擇合適的對象生命周期很重要。

我們來看一個例子:

public class CharactersController : Controller

{

  private readonly ICharacterRepository _characterRepository;

  public CharactersController(ICharacterRepository characterRepository)

  {

    _characterRepository = characterRepository;

  }

  public IActionResult Index()

  {

    var characters = _characterRepository.ListAll();

    return View(characters);

  }

}

public interface ICharacterRepository

{

?  IEnumberable<Character> ListAll();

}

public class CharacterRepository : ICharacterRepository

{

  private readonly ApplicationDbContext _dbContext;

  public CharacterRepository(ApplicationDbContext dbContext)

  {

    _dbContext = dbContext;

  }

  public IEnumerable<Character> ListAll()

  {

    return _dbContext.Characters.AsEnumberable();

  }

}

注意CharacterRepository的構造函數當中需要一個ApplicationDbContext,像它這樣的注入方式并不常見,在每個申請當中,容器負責提供每一個對象的具體依賴對象。

在這個例子當中,ICharacterRepository和ApplicationDbContext都必須在ConfigureServices當中被注冊。

services.AddEntityFramework().AddSqlServer().AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration["Data:DefaultCOnnection:ConnectionString"]));

services.AddScoped<ICharacterRepository, CharacterRepository>();

EntityFramework context 應該被以Scoped的生命周期增加到容器當中,Repositories用到EntityFramework, 所以它應該使用同一個生命周期。

4. 服務的生命周期和注冊選項

ASP.NET 服務可以配置對象的生命周期如下所示:

Transient

  它是意思每個請求都創建一個新的對象,這個適合輕量的,無狀態的服務。

Scoped

  每個申請只創建一個對象。

Singleton

  它是在首次被申請調用時創建一次, 以后所有的請求都會被重用,如果你的應用程序需要單例,推薦使用些方法,而不要自己實現單例模式。

Instance

  它與Singleton相似 ,唯一的區別是,Instance在ConfigureServices的時候就創建了,而Singleton要在第一次請求的時候才創建。

5. 請求的服務和應用服務

ASP.NET當中服務在HttpContext的ApplicationServices和RequestServices中能夠得到

RequestServices里的服務是配置和請求你的應用程序的一部分,ApplicationServices里的服務是被限制在應用程序啟動的時候的服務,任何Scoped的應用程序都能在RequestServices得到,但是在ApplicationServices里得不到。當你的對象申明依賴時,這些依賴在RequestServices里能夠得到,在ApplicationServices里得不到,

一般地,你不需要直接用這些屬性,而可以通過構造函數注入。

6. 用DI設計你的服務

你應該用DI來設計你的應用,不要用函數狀態的靜態方法調用,或者直接地實例化你的服務。用DI ,你的類比較小,而且是靈活的,可測試的。

當你一個類依賴很多的時候,你就要意識到是否違反了單一職責原則。你可以重構你的代碼,把一些依賴移到其它的新類當中。注意在你Controler 類當中應該注意在UI上面,因此你的業務邏輯和數據訪問通過UI的職責的分來被相應地合理分開。

當用到數據訪問時,你可以注入EntityFramework的DbContext類型到你的controllers里面,不過首先你要確保EF在Startup類中被配置了,然而,避免在UI里直接使用DbContext, 你應該把它放到抽象當中去,例如Repository的接口中去。這樣可以減少你的應用和數據的耦合。也能使你的應用程序可以很容易地被測試。

7 替代默認的服務容器

在ASP.NET當中,你可以很容易地替代內建的服務容器,在ConfigureServices方法當中一般返回void, 但是如果它返回IServiceProvider, 一個不同的容器可以被返回,我們以autofac為例。

首選,你必須在project.json加如下的配置:

"dependencies":{

  "Autofac": "4.0.0-beta8",

  "Autofac.Framework.DependencyInjection": "4.0.0-beta8"

},

接下來,改寫ConfigureServices

public IServiceProvider ConfigureServices(IServiceCollection services)

{

  services.AddMvc();

  

  // Add Autofac

  var containerBuilder = new ContainerBuilder();

  containerBuilder.RegisterModule<DefaultModule>();

  containerBuilder.Populate(services);

  var container = containerBuilder.Build();

  return container.Resolve<IServiceProvider>();

}

最后,配置Autofac在DefaultModule里面

public class DefaultModule : Module

{

  protected override void Load(ContainerBuilder builder)

  {

    builder.RegisterType<CharacterRepository>.As<ICharacterRepository>();

  }

}

現在,Autoface被用來生成你的服務在DI里面。

ASP.NET 5/DNX Containers

Autofac.Dnx???? http://autofac.org

StructureMap.Dnx?? http://structuremap.github.io

8. 建議

* DI用于復雜的依賴,控制器、服務、倉儲等

* 不要直接利用DI存儲數據和配置

* 不要靜態地訪問服務

* 不要在應用程序當中手動使用服務定位

* 不要靜態地訪問HttpContext

記住,不要把DI和static/global對應混用,否則你就感覺不到DI的好處了

轉載于:https://www.cnblogs.com/superkklot/p/5055685.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397033.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397033.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397033.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java 權限控制 demo_Java-訪問控制權限

Java面向對象-訪問控制權限Java中&#xff0c;可以通過一些Java關鍵字&#xff0c;來設置訪問控制權限&#xff1b;主要有 private(私有)&#xff0c; package(包訪問權限)&#xff0c;protected(子類訪問權限)&#xff0c;public(公共訪問權限)privatepackageprotectedpublic同…

《未來世界的幸存者》筆記

https://ruanyf.github.io/survivor/ 這兩天一直在上下班途中&#xff0c;讀阮一峰的這本書 《未來世界的幸存者》。還是有不少感慨的。做一下記錄。 未來人類社會的形態&#xff0c;將發生顛覆性的變化。舊的社會結構已經在崩潰了&#xff0c;但社會底層的機會變得更少了&…

python類中沒有屬性_如何在python語言中在類中刪除屬性和添加屬性

在python語言中的類&#xff0c;可以使用class定義類&#xff0c;調用__init__方法進行初始化&#xff1b;默認傳入self&#xff0c;可以在后面在添加幾個屬性。可以使用setattr()添加屬性&#xff0c;也可以使用delattr()刪除屬性。下面利用幾個實例說明這兩個方法的用法&…

mysql 數據復制停止工作_linux – Mysql GTID復制停止工作

我在主服務器和從服務器之間設置了mysql gtid復制.有趣的是,我發現復制在幾分鐘后停止工作,我必須使用stop slave并啟動slave來重啟mysql復制.誰能告訴我是什么原因導致這個問題&#xff1f;改變奴隸主&#xff1a;mysql> change master to-> master_host master.com,-&…

python學生管理系統gui版好例子網_python圖書管理系統gui 相關實例(示例源碼)下載 - 好例子網...

開發語言&#xff1a;Python | 大小&#xff1a;19.05M | 發布時間&#xff1a;2019-05-27 | 發布人&#xff1a;李易峰 相關標簽&#xff1a; 立即下載 開發語言&#xff1a;Python | 大小&#xff1a;0.21M | 發布時間&#xff1a;2020-08-23 | 發布人&#xff1a;聶嘉輝 相關…

COM組件的運行機制

COM組件的運行機制  構造一個創建COM組件的最小框架結構    IUnknown *pUnkNULL;    IObject *pObjectNULL;    CoInitialize(NULL);    CoCreateInstance(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IUnknown, (void**)&pUnk);    pUnk->Qu…

申請去國外讀博士

必須要做的事情是&#xff1a; 考過GRE和TOEFL 準備推薦信 個人CV 聯系導師一般就是發郵件 轉載于:https://www.cnblogs.com/zhulinmails/p/5078695.html

動態編譯

下面的demo就涵蓋了動態編譯和運行類的過程 package 動態編譯; import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader; import javax.tools.JavaCompiler;import javax.tools.ToolProvider; public class Demo { public static void main(Stri…

python怎么打開spyder_Python開發環境Spyder安裝方法

Spyder(Scientific PYthon Development EnviRonment)是一個強大的交互式 Python 語言開發環境&#xff0c;提供高級的代碼編輯、交互測試、調試等特性&#xff0c;支持包括 Windows、Linux 和 OS X 系統。 本文在只安裝過python2.7的Win7環境下進行安裝Spyder&#xff0c;其他環…

矩陣、向量求導法則

復雜矩陣問題求導方法&#xff1a;可以從小到大&#xff0c;從scalar到vector再到matrix。 x is a column vector, A is a matrix practice: 轉載于:https://www.cnblogs.com/vincentQin/p/5406010.html

java字符函數_java字符串函數用法匯總

替換字符串中的字符例如有如下x的字符串String x "[kllkklk\kk\kllkk]";要將里面的“kk”替換為&#xff0c;可以使用兩種方法得到相同的結果replace(CharSequence target, CharSequence replacement) —— x.replace("kk", "")replaceAll(Stri…

[Vue]Scoped Css與Css Modules的區別

均為解決CSS全局作用域問題&#xff08;樣式沖突&#xff08;污染&#xff09;&#xff09;的一個解決方案。 1.Scoped CSS 當 <style> 標簽有 scoped 屬性時&#xff0c;相當于在元素中添加了一個唯一屬性用來區分。 <style scoped> .example {color: red; } <…

mysql數據庫-mysql數據定義語言DDL (Data Definition Language)歸類(六)

0x01 創建數據庫并指定字符集和排序規則 -- 三種實例寫法 create database temptab2 character set utf8 collate utf8_general_ci; create database temptab3 charset utf8 collate utf8_general_ci; create database temptab4 character setutf8 collate utf8_general_ci; 查…

vue antd admin怎么切換到basic分支_vue菜鳥從業記:前端如何與后端哥們進行接口聯調...

最近我的朋友王小閏進入一家新的公司&#xff0c;正好公司項目采用的是前后端分離架構&#xff0c;技術棧是王小閏非常熟悉的vue全家桶&#xff0c;后端用的是Java語言。在前后端開發人員碰面之后&#xff0c;協商確定好了前端需要的數據接口(扯那么多&#xff0c;其實也就是關…

ASP.NET AntiXSS的作用

XSS跨站腳本攻擊是指用戶輸入HTML編碼對網站進行跨站攻擊。通過使用FCKeditor、FreeTextBox、Rich TextBox、Cute Editor、TinyMCE等等Html編輯器&#xff0c;用戶可以輸入一些危險字符&#xff0c;注入到網站中&#xff0c;形式XSS。&#xff08;一般的解決辦法是使用BBCode的…

p1358

這是一道二維樹狀數組模板題。 需要注意的可能只有這些xy有可能為零。那每次輸入之后全部&#xff0c;相當于全部向右下角移了一位。 那就直接給代碼了呦。 using namespace std; int c[1050][1050],n,m; int i,f; int a1,b1,a2,b2,tx,ty,tk; int ans; int lowbit(int x) {retu…

java中對象的生存期_深入理解Java虛擬機-判斷對象是否存活算法與對象引用

我們知道Java中的對象一般存放在堆中&#xff0c;但是總不能讓這些對象一直占著內存空間&#xff0c;這些對象最終都會被回收并釋放內存&#xff0c;那么我們如何判斷對象已經成為垃圾呢&#xff1f;這篇文章會提出兩種算法解決這個問題。另外&#xff0c;本文還要談一談對象引…

大數據高效復制的處理案例分析總結

一個老客戶提出這樣的需求&#xff0c;希望將SQLServer中的某個表的數據快速復制到SQLite數據庫里面以便進行定期的備份處理&#xff0c;數據表的記錄大概有50多萬條記錄&#xff0c;表有100個字段左右&#xff0c;除了希望能夠快速做好外&#xff0c;效率是第一位的&#xff0…

@autowired注解注入為null_Intellij IDEA中Mybatis Mapper自動注入警告的6種解決方案

相信使用Mybaits的小伙伴們一定會經常編寫類似如下的代碼&#xff1a;可以看到 userMapper 下有個紅色警告。雖然代碼本身并沒有問題&#xff0c;能正常運行&#xff0c;但有個警告總歸有點惡心。本文分析原因&#xff0c;并列出解決該警告的幾種方案。原因眾所周知&#xff0c…

五 Python之socket網絡編程

<1>socket概念 socket通常也稱作"套接字"&#xff0c;用于描述IP地址和端口&#xff0c;是一個通信鏈的句柄&#xff0c;應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。ocket本質上就是在2臺網絡互通的電腦之間&#xff0c;架設一個通道…