久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運營的一線實戰(zhàn)洞察。

ASP.NET Core依賴注入實戰(zhàn):生命周期、作用域與高級玩法

ASP.NET Core依賴注入實戰(zhàn):生命周期、作用域與高級玩法 1. 為什么說依賴注入是 ASP.NET Core 的“地基”我第一次接觸 ASP.NET Core 的時候最直觀的感受就是這和舊的 .NET Framework 時代寫代碼的方式完全不一樣了。以前在 ASP.NET MVC 5 里想要在控制器里用一個服務(wù)通常就是new一個出來或者借助某個靜態(tài)類、某個單例工廠去拿。那時候項目里的服務(wù)之間互相 new、互相依賴代碼耦合得像一團亂麻測試更是難以下手。而 ASP.NET Core 從出生那天起就把依賴注入DI做進了框架的骨髓里。你看到的Startup類里的ConfigureServices方法、控制器構(gòu)造函數(shù)里直接聲明接口參數(shù)、中間件里通過RequestServices獲取服務(wù)這些都是依賴注入在背后起作用??梢哉f不搞懂依賴注入你根本沒法理解 ASP.NET Core 的應(yīng)用是怎么被組裝起來的。那依賴注入到底解決了什么問題我用一句話概括它把“創(chuàng)建依賴”這件事從你手里拿走交給你注冊的容器統(tǒng)一管理。比如你的業(yè)務(wù)服務(wù)OrderService依賴一個IOrderRepository傳統(tǒng)寫法里你必須在OrderService內(nèi)部親手new一個具體的SqlOrderRepository。一旦換了數(shù)據(jù)庫、換了實現(xiàn)方式你得跑到每一處new的地方去改。而依賴注入的做法是OrderService只需要在構(gòu)造函數(shù)里聲明“我需要一個IOrderRepository”至于這個接口到底由哪個類來實現(xiàn)、生命周期是多久全部交給容器在注冊時決定。這不只是“解耦”兩個字那么簡單。它直接改變了你組織代碼的方式。以前你寫代碼的粒度通常是“類”而現(xiàn)在你會下意識地按照“接口 實現(xiàn) 注冊”的方式來組織。你會更自然地拆出小服務(wù)、小組件每個組件只干一件事組件之間通過接口通信。這種代碼風格一旦形成習慣項目的可維護性會肉眼可見地提升。我在帶團隊的時候經(jīng)常說依賴注入不只是一個框架功能它是一套編碼思維。你理解了它再看 ASP.NET Core 的管道、中間件、配置系統(tǒng)、日志系統(tǒng)都會覺得處處相通因為這些底層機制全都建立在 DI 容器之上。反過來如果你只是照著模板抄代碼碰到“在構(gòu)造函數(shù)里注入某個服務(wù)”的寫法也只會在用到的時候照貓畫虎一旦遇到循環(huán)依賴、生命周期沖突這種疑難雜癥就會一臉懵。所以這篇文章我想把自己在實際項目里折騰依賴注入的經(jīng)驗整理出來。從核心概念、生命周期到實戰(zhàn)中繞不開的高級玩法比如工廠模式、裝飾器模式、Scope 驗證再到踩過的坑和調(diào)試技巧爭取講得既有原理又有干貨。不管你是剛接觸 ASP.NET Core 的新手還是寫著寫著總覺得哪里不對勁的老手應(yīng)該都能從里面找到一些有價值的東西。2. 從IServiceProvider說起容器到底替我們做了什么很多人上來就背“構(gòu)造函數(shù)注入”“AddScoped”“AddTransient”但這些概念背熟以后腦子里依然是一團漿糊。我的建議是先弄懂最底層的那個對象——IServiceProvider。在 ASP.NET Core 里整個應(yīng)用其實就是一個“服務(wù)集合”的組裝結(jié)果。你寫builder.Services.AddXxx()的時候本質(zhì)上是在往一個ServiceCollection里添加服務(wù)描述。這個ServiceCollection就像一張菜單列著“什么接口對應(yīng)什么實現(xiàn)以什么生命周期來創(chuàng)建”。等到應(yīng)用啟動框架根據(jù)這張菜單構(gòu)建出一個IServiceProvider實例也就是真正的“服務(wù)容器”。IServiceProvider的核心只有一個方法object GetService(Type serviceType)。你告訴它你想要什么類型它就根據(jù)之前注冊的規(guī)則幫你把這個類型以及它依賴的東西完整地實例化出來。聽起來簡單但這背后牽扯出幾個關(guān)鍵問題構(gòu)造函數(shù)里要的參數(shù)怎么來同一個服務(wù)被請求多次時是返回同一個實例還是每次都新建如果服務(wù)之間有循環(huán)依賴怎么處理我用一個生活里的類比來解釋服務(wù)容器就像一個全能中介。你要租房子解析IOrderRepository中介會根據(jù)你的需求去匹配房東具體實現(xiàn)類SqlOrderRepository。如果房子需要配家具構(gòu)造函數(shù)依賴DbContext中介還會順手聯(lián)系家具商解析DbContext把家具也安排到位。你只需要告訴中介“我要什么”剩下的一堆復雜流程都不用管。實際寫代碼的時候最常用的入口有四個IServiceProvider直接獲取服務(wù)實例IServiceScopeFactory創(chuàng)建子作用域IServiceScope作用域本身ActivatorUtilities在容器之外輔助創(chuàng)建對象同時盡量解析其依賴其中IServiceScopeFactory是很多人一開始容易忽略的。在后臺任務(wù)、控制臺應(yīng)用、或者某些需要“手動解析服務(wù)”的場景里你往往會用serviceProvider.CreateScope()創(chuàng)建一個作用域來拿服務(wù)。如果不這么做直接拿IServiceProvider.GetService(typeof(MyService))去解析一個 Scoped 服務(wù)大概率會得到一個異?;蛘吣玫揭粋€不按預期生命周期工作的實例。關(guān)于這點我踩過比較經(jīng)典的坑是在 ASP.NET Core 的 Startup 階段嘗試解析 Scoped 服務(wù)。比如有人想在Configure方法里通過app.ApplicationServices.GetServiceMyDbContext()直接拿數(shù)據(jù)庫上下文去初始化數(shù)據(jù)。運行起來會發(fā)現(xiàn)這種方式在某些版本里能拿到對象但 DbContext 的跟蹤行為、連接管理并不符合預期甚至可能因為作用域缺失導致連接沒有及時釋放。正確做法是手動創(chuàng)建一個 Scope在這個 Scope 里拿 DbContext 用用完釋放。這個細節(jié)我在后面的生命周期章節(jié)里還會重點展開。理解了IServiceProvider你就抓住了 DI 容器的“心臟”。后面聊生命周期、聊擴展點都是圍繞這個核心展開的。3. 生命周期三兄弟Transient、Scoped、Singleton 到底怎么選ASP.NET Core 的 DI 容器支持三種生命周期模式這恐怕是日常開發(fā)里討論最多、也最容易出問題的地方。先說定義再說我的理解最后講實操選擇。生命周期創(chuàng)建時機特點典型場景Transient瞬態(tài)每次從容器解析時都新建實例最輕、無狀態(tài)輕量工具類、無狀態(tài)服務(wù)Scoped作用域每個作用域內(nèi)只創(chuàng)建一個實例一個請求一個實例DbContext、業(yè)務(wù)服務(wù)Singleton單例整個應(yīng)用生命周期內(nèi)只有一個實例全局共享緩存、配置、日志提供者定義大家都懂但實際選擇時經(jīng)常有爭議。我覺得關(guān)鍵要把握兩條原則有沒有狀態(tài)狀態(tài)的生命周期應(yīng)該有多長Singleton適合“無狀態(tài)或有意共享狀態(tài)”的服務(wù)。比如一個MemoryCache包裝類全局只有一個實例里面的數(shù)據(jù)在所有請求之間共享這很合理。但如果你把一個有狀態(tài)的類比如包含可變字段的服務(wù)注冊成 Singleton就要警惕多線程并發(fā)問題。多個請求同時讀寫同一個實例的字段輕則數(shù)據(jù)錯亂重則出現(xiàn)難以復現(xiàn)的 bug。Scoped適合“一個請求內(nèi)保持一致”的服務(wù)。最典型的就是DbContext。一個 HTTP 請求里你可能會在多個地方使用數(shù)據(jù)庫上下文如果每個地方都拿到不同的 DbContext 實例那么它們各自跟蹤不同的實體狀態(tài)事務(wù)和性能都是災(zāi)難。Scoped 保證同一個請求范圍內(nèi)拿到的都是同一個實例這個問題就自然解決了。Transient適合“每次使用都獨立”的服務(wù)。比如一個EmailValidator它內(nèi)部只保存驗證規(guī)則不保存用戶狀態(tài)每次新建一個實例成本很低也無所謂共享。再比如有些服務(wù)內(nèi)部依賴了另一個 Transient 服務(wù)每次解析都需要一個干凈的組合那么 Transient 就是合適的選擇。但實際項目里經(jīng)常出現(xiàn)“看似無狀態(tài)其實有隱含狀態(tài)”的服務(wù)這是最坑的。我舉一個例子你寫了一個AuditLogger構(gòu)造函數(shù)里注入了一個IHttpContextAccessor用來記錄當前請求的用戶信息。表面上看它沒有字段、沒有狀態(tài)非常適合注冊成 Singleton。但IHttpContextAccessor本身是 Scoped 的它的內(nèi)部邏輯依賴請求上下文如果你把AuditLogger注冊成 Singleton而它又注入了 Scoped 的IHttpContextAccessor這時候容器就會拋異常。為什么因為 Singleton 的實例在應(yīng)用啟動時就創(chuàng)建了它不像請求那樣有明確的生命周期邊界。如果允許一個 Singleton 持有 Scoped 服務(wù)的引用那么這個 Scoped 服務(wù)到底是哪個請求的容器沒法回答這個問題所以干脆在注冊時就不允許這種依賴關(guān)系。這就是著名的“生命周期捕獲”問題是 ASP.NET Core DI 新手最容易踩的大坑之一。我也碰到過這種情況一個實現(xiàn)類被同時注冊成了 Scoped 和 Singleton 兩種方式代碼里有些地方用的是 Scoped 的解析有些地方用的是 Singleton 的解析。結(jié)果是同一個邏輯在某些請求里共享狀態(tài)在某些請求里又各自獨立排查問題的時候讓人非常抓狂。我后來給自己定了一條規(guī)矩同一個服務(wù)類型在整個容器中只注冊一種生命周期除非有極其特殊的需求否則絕不在多個地方用不同生命周期重復注冊。4. Scope 與請求管道為什么你的服務(wù)在一個“虛擬邊界”里工作前面反復提到“作用域Scope”這個詞對新手來說有點抽象。我盡量用最直白的方式拆開講。其實 Scope 就是容器創(chuàng)建的一組服務(wù)實例的“集合邊界”。在 ASP.NET Core 的請求管道里框架會在每個 HTTP 請求開始時自動創(chuàng)建一個 Scope并在請求結(jié)束時把它釋放。這個 Scope 里解析的所有 Scoped 服務(wù)生命周期都跟這一個請求綁定。請求開始服務(wù)創(chuàng)建請求結(jié)束服務(wù)釋放。整個過程你基本不需要手動干預框架已經(jīng)幫你處理好了。但這個“自動”背后有一個重要前提你的代碼必須沿著請求管道走。如果你的代碼是在請求之外的上下文里執(zhí)行比如后臺托管服務(wù)、定時任務(wù)、消息隊列消費者那就沒有現(xiàn)成的 Scope 可用。這時候如果你直接解析 Scoped 服務(wù)就會遇到我前面說的麻煩。我舉個例子。假定你寫了一個IHostedService在應(yīng)用啟動后每 30 秒執(zhí)行一次數(shù)據(jù)清理任務(wù)。任務(wù)里要用到MyDbContextScoped如果你直接注入MyDbContext到后臺服務(wù)構(gòu)造函數(shù)里應(yīng)用啟動時容器就會報錯因為IHostedService本身是 Singleton 的它不能依賴 Scoped 服務(wù)。解決方式是在后臺任務(wù)的每次執(zhí)行中手動創(chuàng)建 Scopepublic class CleanupHostedService : BackgroundService { private readonly IServiceScopeFactory _scopeFactory; public CleanupHostedService(IServiceScopeFactory scopeFactory) { _scopeFactory scopeFactory; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { using (var scope _scopeFactory.CreateScope()) { var dbContext scope.ServiceProvider.GetRequiredServiceMyDbContext(); // 執(zhí)行清理邏輯 } await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken); } } }這里的關(guān)鍵是IServiceScopeFactory本身是 Singleton 安全的你可以放心地把它注入到任何地方。每次要干活的時候用CreateScope()開一個新的“小容器”在這個小容器里解析 Scoped 服務(wù)用完立刻釋放。這樣既遵守了生命周期規(guī)則又不會出現(xiàn)“Singleton 依賴 Scoped”的沖突。我在實際項目里把這個模式用得非常頻繁尤其是寫后臺任務(wù)、定時任務(wù)、消息隊列消費者的時候??梢赃@么理解凡是離開了 HTTP 請求管道、又需要解析 Scoped 服務(wù)的場景都要養(yǎng)成“手動開 Scope”的習慣。這不是可選項是必須項否則你拿到的要么是異常要么是行為詭異的服務(wù)實例。還有一個容易被忽略的場景你在中間件里拿服務(wù)。中間件本身是在請求管道里的所以它默認就有 Scope 的上下文。但如果你用RequestServices.GetService()和直接用構(gòu)造函數(shù)注入結(jié)果是不太一樣的。構(gòu)造函數(shù)注入的中間件實例是 Singleton 創(chuàng)建的它拿不到當前請求的 Scope 服務(wù)而通過RequestServices拿服務(wù)是在當前請求的 Scope 里拿的這才是正確姿勢。我的經(jīng)驗是中間件里如果需要依賴 Scoped 服務(wù)優(yōu)先用RequestServices不要指望構(gòu)造函數(shù)注入。構(gòu)造函數(shù)注入適合 Scoped 服務(wù)那種“每個請求都不同”的場合但中間件只有一個實例所以它沒法持有請求級別的服務(wù)引用。5. 實戰(zhàn)技巧工廠模式、裝飾器模式與條件注冊聊完生命周期我想分享幾個實際項目中經(jīng)常用到的高級玩法。這些玩法不是 AspNet Core DI 的“必學操作”但如果你經(jīng)歷過某個痛點就會知道它們有多香。5.1 工廠模式同一個接口多個實現(xiàn)怎么處理一個接口多個實現(xiàn)類是 DI 里最直接的挑戰(zhàn)。最常見的是接口IPaymentGateway有支付寶實現(xiàn)、微信支付實現(xiàn)、銀聯(lián)實現(xiàn)你想在運行時根據(jù)上下文選擇具體用哪個。最笨的辦法是把所有實現(xiàn)都注冊上去然后靠IEnumerableIPaymentGateway注入進來自己循環(huán)判斷。但這樣代碼會越寫越亂。更優(yōu)雅的方案是注冊一個工廠委托services.AddScopedIPaymentGateway(serviceProvider { var config serviceProvider.GetRequiredServiceIConfiguration(); var providerName config[Payment:Provider]; switch (providerName) { case Alipay: return new AlipayGateway(...); case WeChat: return new WeChatGateway(...); default: throw new InvalidOperationException($Unknown provider: {providerName}); } });工廠委托的優(yōu)勢是你可以在創(chuàng)建服務(wù)時做復雜的初始化、根據(jù)配置選擇實現(xiàn)類、或者做延遲初始化。所以當你發(fā)現(xiàn)某個服務(wù)的構(gòu)造過程不只是一句new Xxx(params...)的時候就該考慮用工廠注冊來代替默認的反射構(gòu)造。5.2 裝飾器模式在不改原代碼的情況下增加橫切邏輯裝飾器模式是 DI 里用來做“橫切關(guān)注點”的利器。什么叫橫切關(guān)注點比如日志、緩存、性能監(jiān)控、故障恢復這些邏輯縱向貫穿業(yè)務(wù)代碼把它寫在業(yè)務(wù)服務(wù)內(nèi)部會讓代碼很臟。舉個例子。你有一個IWeatherService里面提供了GetWeatherAsync。你不想改動WeatherService本身但想在每次調(diào)用時記錄耗時、加緩存、做重試。這時候你寫一個LoggingWeatherService它實現(xiàn)同一個接口內(nèi)部包裝一個真實的IWeatherServicepublic class LoggingWeatherService : IWeatherService { private readonly IWeatherService _inner; private readonly ILoggerLoggingWeatherService _logger; public LoggingWeatherService(IWeatherService inner, ILoggerLoggingWeatherService logger) { _inner inner; _logger logger; } public async TaskWeatherResult GetWeatherAsync(string city) { var sw Stopwatch.StartNew(); try { return await _inner.GetWeatherAsync(city); } finally { _logger.LogInformation(GetWeatherAsync took {Elapsed}ms, sw.ElapsedMilliseconds); } } }注冊的時候稍微繞一下services.AddTransientWeatherService(); // 真實實現(xiàn) services.AddTransientIWeatherService(sp new LoggingWeatherService(sp.GetRequiredServiceWeatherService(), sp.GetRequiredServiceILoggerLoggingWeatherService()));雖然代碼看起來多了一點點但好處是業(yè)務(wù)邏輯類根本不知道日志的存在日志邏輯獨立成一個類可復用、可測試。如果你用 Scrutor 這類庫還能自動掃描程序集批量給所有實現(xiàn)了某個接口的類套上裝飾器省去大量手工注冊代碼。我在項目里用裝飾器做過緩存、重試、審計、分布式鎖等橫切能力效果非常棒。它和 AOP面向切面編程的思想一致但在 .NET 世界里不需要引入復雜的 AOP 框架用 DI 原生的方式就能實現(xiàn)。5.3 條件注冊根據(jù)運行時配置決定要不要注冊某個服務(wù)依賴注入的條件注冊不一定要用第三方庫簡單的判斷完全可以在ConfigureServices里完成if (environment.IsDevelopment()) { services.AddScopedINotificationSender, FakeNotificationSender(); } else { services.AddScopedINotificationSender, EmailNotificationSender(); }這種寫法最常見于“開發(fā)環(huán)境用假數(shù)據(jù)/假服務(wù)生產(chǎn)環(huán)境用真實服務(wù)”的場景。不過我建議盡量少用這種分支邏輯因為它會讓注冊信息分散、難審計。更規(guī)范的做法是把不同環(huán)境的注冊邏輯封裝成IServiceCollection擴展方法按環(huán)境命名比如AddFakeNotificationServices()和AddRealNotificationServices()然后在Program.cs里按環(huán)境調(diào)用。6. 調(diào)試與性能IEnumerable 注入、驗證作用域與避免頻繁解析依賴注入用多了你會發(fā)現(xiàn)大部分問題不是“不會用”而是“出問題時不知道怎么查”。這一章我聊聊調(diào)試和性能優(yōu)化的一些實操經(jīng)驗。6.1 所有注冊的服務(wù)都能通過IEnumerableT獲取在 ASP.NET Core 的容器里如果你注冊了多個IFoo的實現(xiàn)那么注入IEnumerableIFoo時會拿到所有注冊的實例順序按照注冊順序。這個特性有兩個常見的用途實現(xiàn)某種“策略集合”循環(huán)調(diào)用每個策略。典型的例子是多個校驗器按順序執(zhí)行直到有一個不通過。做插件化架構(gòu)時動態(tài)加載程序集里所有實現(xiàn)了某個接口的類然后統(tǒng)一注冊統(tǒng)一解析。我見過不少人為了拿到多個實現(xiàn)自己維護一個列表清單然后在注冊時逐個 new。其實完全可以依賴容器本身用IEnumerableT注入。但注意這個特性和“按名字獲取具體實現(xiàn)”不一樣。如果你需要“根據(jù) key 精確獲取某一個”還是得回到工廠模式或字典映射。6.2 啟動時驗證作用域把問題暴露在啟動階段而不是請求階段ASP.NET Core 提供了ValidateScopes選項用于在啟動時檢測“從根容器解析 Scoped 服務(wù)”這類錯誤。開發(fā)環(huán)境下默認是開啟的生產(chǎn)環(huán)境默認是關(guān)閉的出于性能考慮。但如果你吃了“Singleton 依賴 Scoped”的虧建議在生產(chǎn)環(huán)境也開啟這個驗證代價只是啟動時稍微多做一點檢查但能在部署早期就把問題暴露出來。在 .NET 6 的程序里可以這樣配置var builder WebApplication.CreateBuilder(args); builder.Host.UseDefaultServiceProvider(options { options.ValidateScopes true; // 驗證作用域 options.ValidateOnBuild true; // 啟動時構(gòu)建驗證 });ValidateOnBuild更狠一點會在容器構(gòu)建完成后立即嘗試解析所有注冊的服務(wù)檢查構(gòu)造函數(shù)依賴是否都能滿足、有沒有明顯的循環(huán)依賴。這個對大型項目特別友好因為很多問題不用等到運行時請求才暴露。我記得有一次在重構(gòu)一個老項目把幾個服務(wù)從靜態(tài)類改成 DI 注冊結(jié)果啟動到一個數(shù)據(jù)庫服務(wù)時總是報“Unable to resolve service”錯誤。打開ValidateOnBuild后啟動日志直接把缺失依賴的服務(wù)名打印得清清楚楚我順著依賴鏈一個個補注冊十分鐘就搞定了。以前要是靠跑起來之后某個請求才觸發(fā)那排查時間得多花好幾倍。6.3 性能陷阱頻繁從 IServiceProvider 解析不是免費的IServiceProvider.GetService()的解析成本雖然不算高但也絕不是零成本。在熱路徑比如循環(huán)、高頻接口調(diào)用里反復解析服務(wù)會造成可感知的 CPU 開銷。我見過一個性能問題某個中間件在每次請求里用了十幾次RequestServices.GetService()雖然每次只有微秒級消耗但疊加到每秒幾萬請求的規(guī)模上浪費就很明顯了。最直接的優(yōu)化方式是把服務(wù)依賴挪到構(gòu)造函數(shù)里注入而不是在方法內(nèi)部每次解析。對于必須動態(tài)解析的場景比如策略模式、選路邏輯可以將解析結(jié)果緩存到一個局部變量中循環(huán)外解析循環(huán)內(nèi)復用。6.4 陷阱容器釋放順序與 IDisposable服務(wù)如果實現(xiàn)了IDisposable容器負責在生命周期結(jié)束時釋放它。Singleton 在應(yīng)用停止時釋放Scoped 在請求結(jié)束時釋放Transient 在解析者釋放時釋放如果解析者沒有釋放容器也會在 Scope 釋放時統(tǒng)一釋放。關(guān)于這塊有個容易被誤解的點如果你手動new出來一個服務(wù)沒有經(jīng)過容器容器是不知道也不負責釋放的你需要自己管理它的生命周期。還有一個小坑如果你用工廠注冊AddTransientIFoo(sp new Foo())返回一個實現(xiàn)了IDisposable的對象容器會跟蹤并釋放它前提是它是在容器解析時創(chuàng)建的。如果你的工廠返回的是一個已經(jīng)存在的單例比如靜態(tài)實例容器可能會重復釋放同一個對象這時候要格外小心。經(jīng)驗是讓容器管理生命周期不要在工廠里返回自己管理生命周期的“外來對象”除非你確認不會出現(xiàn)重復釋放問題。7. 架構(gòu)層面的實踐接口、模塊化注冊與可測試性依賴注入的最終勝利不在于“會用”而在于“用得順手”。我自己在架構(gòu)層面有幾條心得分享給大家。7.1 每個項目都按模塊拆分注冊擴展方法我參與過的項目中最容易失控的是那個巨無霸Program.cs或Startup.cs。幾十個AddSomething()擠在一起誰也不敢動改一行都心驚膽戰(zhàn)。后來我養(yǎng)成了一個習慣每個業(yè)務(wù)模塊自己寫一個服務(wù)注冊擴展方法內(nèi)部只負責本模塊依賴的服務(wù)然后在Program.cs里調(diào)用它。舉個例子一個“訂單模塊”可以有一個public static class OrderServiceCollectionExtensions { public static IServiceCollection AddOrderModule(this IServiceCollection services) { services.AddScopedIOrderRepository, SqlOrderRepository(); services.AddScopedIOrderService, OrderService(); services.AddScopedIOrderDomainEventHandler, OrderDomainEventHandler(); return services; } }Program.cs里三五行就搞定builder.Services.AddInfrastructureModule(); builder.Services.AddOrderModule(); builder.Services.AddPaymentModule();這樣每個模塊的依賴關(guān)系集中在模塊自己的擴展方法里找問題的時候直接進模塊文件不用在啟動文件里撈針。配合上模塊化項目的層次結(jié)構(gòu)應(yīng)用層、領(lǐng)域?qū)?、基礎(chǔ)設(shè)施層、表現(xiàn)層每一層的 DI 注冊職責也能被清晰劃分。7.2 用容器做依賴注入但也別把一切都扔進容器有一類東西我不建議放容器里。比如配置對象直接用IOptionsT、靜態(tài)工具類如MathHelper、簡單的數(shù)據(jù)傳輸對象DTO。容器存在的意義是管理復雜依賴關(guān)系和生命周期如果什么東西都硬塞進容器解析鏈會越來越長性能下降排查也麻煩。還有一類需要小心的是“長期存在的服務(wù)”和“短期請求”混合的情況。比如 Singleton 的緩存服務(wù)里不小心引用了 Scoped 的DbContext這就是架構(gòu)層面的錯誤。我給出的建議很簡單畫一條依賴規(guī)則——Singleton 只能依賴 SingletonScoped 可以依賴 Scoped 和 SingletonTransient 可以依賴任意生命周期。寫進團隊規(guī)范當作評審時的關(guān)注點。7.3 依賴注入如何讓測試變得更簡單依賴注入最大的工程紅利是“可測試性”。因為一個類的依賴都是通過接口注進來的測試時你可以隨手替換成假的實現(xiàn)不需要啟動整個應(yīng)用不需要碰數(shù)據(jù)庫不需要真實發(fā)郵件。我寫單元測試時的做法是[Fact] public async Task GetWeatherAsync_WhenCityIsEmpty_ThrowsArgumentException() { var weatherService new WeatherService( Mock.OfIWeatherRepository(), Mock.OfICacheService()); await Assert.ThrowsAsyncArgumentException( () weatherService.GetWeatherAsync()); }這里每個依賴都能用 mock 對象替代測試用例短小明確。如果沒有依賴注入你可能要花大力氣構(gòu)造WeatherService的內(nèi)部依賴甚至要起一個完整的服務(wù)宿主測試效率和可維護性都差很多。7.4 依賴注入與模塊化邊界別讓容器變成“上帝對象”有一種反模式是為了讓某個服務(wù)在任何地方都能拿到把它注冊成 Singleton然后在幾乎每個類里注入它。這會造成隱式的全局依賴代碼之間通過這個“上帝對象”互相通信模塊邊界名存實亡。我在一些老項目里見過這種現(xiàn)象整改起來特別痛苦。正確的做法是依賴關(guān)系要顯式地通過構(gòu)造函數(shù)表達出來。如果一個類需要“當前用戶信息”不要讓它自己去全局容器里拿而是讓調(diào)用方把用戶信息顯式傳進來。容器只用來組裝那些“真正需要容器管理的服務(wù)”不要用它作為傳遞參數(shù)的通道。這一點做得好模塊邊界才能保持清晰。8. 那些坑循環(huán)依賴、作用域失控與我沒能早發(fā)現(xiàn)的錯誤最后一個大章節(jié)聊幾個實際項目中經(jīng)常踩的坑。這些坑每個我都見過或者親身體驗過希望你們能提前避雷。8.1 循環(huán)依賴兩個服務(wù)互相引用彼此依賴注入最經(jīng)典的報錯之一A依賴BB又依賴A。容器在嘗試解析時會發(fā)現(xiàn)依賴鏈成了一個環(huán)然后拋出異常。解決辦法一般有三種重構(gòu)拆分把 A 和 B 之間互相依賴的那部分邏輯抽出來放到第三個類 C 里A 和 B 都依賴 C循環(huán)自然解除。這是最徹底的方案也是我最推薦的方式。改變生命周期如果 A 和 B 都是 Transient改成其中一個為 Singleton 或 Scoped有時能繞過構(gòu)建循環(huán)的問題。但這治標不治本潛在風險仍然在。延遲解析某個服務(wù)在真正用到時才去容器解析通過注入IServiceProvider而不是在構(gòu)造函數(shù)里直接依賴。可以解決問題但代價是“依賴關(guān)系變隱式了”而且會破壞構(gòu)造函數(shù)注入的清晰性。我的經(jīng)驗是遇到循環(huán)依賴先停下來想想設(shè)計問題而不是急著找 hack。循環(huán)依賴通常意味著職責邊界劃分不當。重構(gòu)雖然工作量大一點但以后維護的舒適度完全值得。8.2 作用域失控一個 Scoped 服務(wù)被 Singleton 持有了這個坑我在生命周期章節(jié)提過但值得再具體演示一下。假設(shè)你有一個ICacheService注冊成了 Singleton而它內(nèi)部注入了IBillingRepositoryScoped。容器啟動時不會立刻檢測到錯誤除非開啟了ValidateOnBuild但等到某個請求使用了這個緩存服務(wù)運行時就會拋出異常。這類問題最陰險的地方是它不一定在啟動階段出現(xiàn)而是取決于哪個請求先觸發(fā)。A 客戶端的請求觸發(fā)了一切正常B 客戶端的請求觸發(fā)了直接 500。我見過一個項目因為這個原因偶發(fā)崩潰排查了好久才定位到這層關(guān)系。最好的防線就是我在前面說的同一個服務(wù)生命周期統(tǒng)一Singleton 依賴鏈上全部是 Singleton在開發(fā)環(huán)境開啟服務(wù)作用域驗證。這三條做到了這類坑基本能全部躲掉。8.3 過度注入構(gòu)造函數(shù)動不動就七八個參數(shù)如果一個服務(wù)類構(gòu)造函數(shù)里要注入七八個東西這個類八成違背了“單一職責原則”。七八個依賴意味著它同時在做好幾件事。我見過最夸張的某個服務(wù)構(gòu)造函數(shù)里塞了 12 個依賴每次修改都要傳新參數(shù)測試時 mock 也要寫 12 行。重構(gòu)思路是拆類把數(shù)據(jù)庫訪問拆出去、把通知拆出去、把緩存拆出去然后用門面模式或組合模式把幾個小服務(wù)組合起來。依賴注入容器擅長組裝所以“很多小對象組合成一個大對象”是合理的但“一個大對象硬吞進無數(shù)依賴”是不合理的。8.4 忘記釋放 scope 資源在手動創(chuàng)建 Scope 的場景里后臺任務(wù)、控制臺應(yīng)用如果忘記using釋放 ScopeScoped 服務(wù)里創(chuàng)建的DbContext、HTTP 客戶端連接等資源就會一直占著內(nèi)存時間長了可能引發(fā)連接池耗盡、內(nèi)存泄漏。我給自己定的習慣是所有手動創(chuàng)建的 Scope 一律用using或await using包起來確保離開代碼塊就釋放。哪怕只是解析一個不痛不癢的小服務(wù)也養(yǎng)成這個習慣免得哪天換成DbContext時踩雷。8.5 啟動時解析 Scoped 服務(wù)的“想當然”錯誤前面說過在Program.cs或Startup.cs里直接解析 Scoped 服務(wù)是個常見的坑。比如有人想在啟動時初始化 admin 用戶var adminService app.Services.GetRequiredServiceIAdminService(); adminService.Initialize();如果IAdminService注冊的是 Scoped這段代碼會直接報錯未開啟ValidateScopes時也可能不報錯但行為不保證。正確寫法using (var scope app.Services.CreateScope()) { var adminService scope.ServiceProvider.GetRequiredServiceIAdminService(); adminService.Initialize(); }這個“手動開 Scope 解析服務(wù)”的模式在 .NET 6 的WebApplication環(huán)境里尤其常見因為Program.cs里寫啟動邏輯的人很多。記住一條根容器的ApplicationServices是用來解析 Singleton 和通過工廠解析服務(wù)的不是給你解析 Scoped 服務(wù)的。9. 我的推薦實踐從開發(fā)到生產(chǎn)環(huán)境一路穩(wěn)最后我給出一份我在實際項目里會用的“依賴注入實踐清單”。這些條不是什么金科玉律但經(jīng)過多個項目的錘煉確實能幫我少踩很多坑。注冊入口盡量集中在模塊擴展方法里不要在Program.cs里散落大量注冊代碼。每個模塊對自己負責注冊代碼的查找成本極大降低。生命周期統(tǒng)一且顯式同一個服務(wù)類型只注冊一種生命周期。注冊 Unity 時團隊規(guī)范里寫明“所有服務(wù)必須顯式指定生命周期”不允許使用默認的自動注冊工具把一切都變成 Transient 或 Singleton。在開發(fā)環(huán)境和生產(chǎn)環(huán)境都開啟ValidateScopes。雖然生產(chǎn)環(huán)境有一些性能開銷但換來的是早期發(fā)現(xiàn)生命周期錯誤。如果對性能極度敏感可以在生產(chǎn)環(huán)境關(guān)閉但要保證測試和預發(fā)布環(huán)境開啟。堅持構(gòu)造函數(shù)注入避免屬性注入和服務(wù)定位器模式。構(gòu)造函數(shù)注入最顯式依賴關(guān)系一目了然。雖然屬性注入寫起來更少但“依賴關(guān)系隱式化”后代碼的可讀性和可測性會變差。使用IOptionsT來管理配置不要直接把配置對象注冊成 Singleton。這樣配置的刷新、熱更新才有標準支持測試時替換配置也更靈活。對資源型服務(wù)比如 DbContext、數(shù)據(jù)庫連接優(yōu)先使用 Scoped并且確保在請求管道或手動 Scope 里使用。如果需要在后臺任務(wù)里使用就手動創(chuàng)建并釋放 Scope。依賴方向只允許單向流動接口定義在一個模塊實現(xiàn)放在基礎(chǔ)設(shè)施層應(yīng)用層只依賴接口。這樣 Web API、后臺任務(wù)、測試都能共用同一個接口層模塊之間的耦合被降到最低。定期做依賴關(guān)系審計可以寫一個簡單的構(gòu)建腳本在 CI 階段把服務(wù)注冊列表輸出到日志里看看有沒有某個模塊的注冊依賴異常。這個對團隊協(xié)作特別有幫助。我可以坦誠地說依賴注入這套機制我自己從“會用”到“覺得香”經(jīng)歷了挺長時間。很多經(jīng)驗也是靠踩坑換來的——特別是那幾個生命周期相關(guān)的坑我至今記憶猶新。希望這篇長文能幫你把 ASP.NET Core 依賴注入從“知道概念”推向“理解本質(zhì)”以后在項目里用它建模、設(shè)計服務(wù)邊界、排查疑難問題的時候能更有底氣。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
丰满人妻一区二区三区在线| 熟女欧美日韩综合婷婷| 超碰97久久| 久操视频免费观看| 91亚洲不卡一区| 精品一区二区成人动漫| 岛国福利在线精品播放| 搡老女人老91妇女熟女| 密臀在线免费观看| 混色激情av| 中文字幕日本久久| 欧美日本久久精品一区 | 蜜乳av首页| 日韩欧美性吧婷婷乱伦大香蕉| 色97综合中文字幕| 精品成人女人久久| 欧美精品97| 婷婷性网| 青青草在线视频播放器| 啊啊啊啊好疼视频| 亚洲日韩少妇一道本视频| 91狠狠综合久久久久久| 狠狠色婷婷7777久| 色官网在线| 亚洲天堂AV在线播放| jizz啪啪| 精品成人亚洲午夜电影| 嫩呦国产一区二区三区AV| 亚洲一区二区AV| 色色九区| 777AV电影| 欧美成年人性爱视频免费观看| 精品人妻一区二区三区在线视频不卡| 一本色道熟妇| 加勒比99999| 欧美色吧综合| 91亚洲人| 久久性生大片免费观看性| 97鸡把在线视频| 女人香蕉久久毛毛片精品| 中文无线日韩一区| 91色婷婷综合久久中文字幕二区| 四虎影视欧美| 久久久性| 人人操人人插人人摸人人干| 92午夜免费福利视频| 成人无码影片视频在线| 色啪网| 人人做人人妻人人夜视频| 中国一区二区亚洲人妻| 色婷婷aV一区二区三区麻豆综合| 操学生天天| 97在线青| 精品人妻一区二区三区不卡断| 久久风骚城市| 久久久999| 99国产在线 精品 视频| 91扒丝袜综合在线| 国产中文字幕在线观看| 亚洲自拍天堂| 女人被添高潮免费视频| 日韩情色视频| 91 亚洲情侣偷拍 久久| 亚洲中文sv| 性91| 韩国一级婬片A片无码天美| 国产女人与拘做受视频免费| 欧美熟妇视频| 国产农村妇女毛片精品久久| 国产强奸乱伦无码视频| 五月丁香拍拍激情综合三级| 九月AV| 欧美第二页午夜| 久久精品免费| 人妻乱仑一区二区三区| 女同性恋久久| 有码免费观看| 丝袜美腿丝袜| 日本 色 导航| 日日黄色三级网站| 精品少妇99| 中文字幕精品一区二| 久久久久国产一区二| 狠狠干综合| 老司机免费视频在线91| 日韩一二三区| 综合色播| 亚洲 欧美综合| 国产又黄又粗的视频| 手机在线观看不卡无码av| 91在线限制级| 老熟女乱伦片| 欧美亚洲日韩人妻在线观看| 蜜臀中文无码午夜| 狼人久草| 丰满人妻-区二区三区免费看| 麻花豆传媒剧国产MV出差| 麻豆国产尤物AV| 98福利在线视频| 天天干人人看综合| 很很干很很操| 天天色欧美| 女人被添高潮免费视频| 久久久内射良家| 夜夜操美女| 夜夜嗨AV一区天天| 亚洲性高潮| 91成人久久 | 老熟妇综合| 亚洲情欲| 中文字幕视频2区| 日产精品久久久一区二区| 国产一区二区a毛片| 天天爽夜夜欢视| 久久久精品| 天天插天天插| 91殴美| 日韩欧美国产高清视频| 黄色一区三区| 国人欧美精品一区二区| 色阁阁AV综合网| 成人免费性爱视视| 中文字幕88av在线| 久操网无码在线| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 性色av蜜臀av色欲aV| 白丝AV网站| 91色人妻| 精品无码一区二区人妻久久蜜桃| av一区二区三区 中文| 精品国产乱码久久久影院| 色欲蜜臀AV| 成人黄页| 中文字幕在线观看丝袜| 亚洲色图91| 毛片视频白嫩| 久思思热视频在线观看| 日韩精品人妻中文字幕不卡乱码| 日韩精品 资源| 欧美不在线| 国产剧情一区在线观看| 欧亚乱色熟女一区二区| 熟妇人妻一二三区免费| 最新加勒比丝袜在线| 欧美传媒| 亚洲日本天堂| 校园春色之综合网| 91碰超| 久久久九| 亚州Av天美传媒| 99操视频| 亚洲国产精品有声| 激情小说激情视频| 91丝袜美腿网站| 精品成人无码| 日本三级精品| 日韩少妇无吗| 九九综合久久| 九草在线大香蕉| 91在线超高颜值国产| 91N综合网| 亚洲色9| 久久久国产三级黄色片| 亚洲熟女乱色一区二区三区| 蜜臀在线网站| 国产AV线| 大香蕉中文aV在线| 香蕉久久国产AV一区二区| 放黄片放3级黄片没穿衣服| 人人搡人人肉久久精品| 人妻密肉在线观看| 中文字幕一区二区三区视频播放| 国产无码三级视频在线观看| 美女高潮国产高清| 97网址97| 蜜桃色院一区久久| 久久99国产综合精品女同| 精品一区二区成人动漫| 亚洲第一在线视频| 国产精品爱欲| 国产精品99999| 俺去啦自拍| 在线综合 亚洲 欧美中文字幕 | 簧片免费看视频| 欧洲性爱无码区| 人妻精品一区二区三区| 清纯唯美综合亚洲| 91美女視頻| 青青青操| 青娱乐av在线| 日韩三级一区| 91亚洲黑人| 另类 日韩 熟女| www.99色| 国产亚洲精品A在线观看下载| 性欧美| 欧色性第一页| 成人久久久精品| 91色黑人少妇| 精品人妻一区二区免费蜜桃| 超碰超碰95| 99精品热| 素人美腿视频网站| 免费的av网| 大香蕉伊人久久| 日韩亚洲Av人人夜夜澡人人爽| 国产精品点击进入在线影院| 成在线人在线观看视频| 欧美国产欧美在线观看| 亚洲暴力强奸AV| 亚洲欧洲日韩天堂av| 久久精品人人做人人看| 国产一区二区欧美日本| 91足交| 91强热人妻| 思思热免费在线视频| 国产在线强奸视频| 久久av一级av少妇av高潮| 亚洲国产精品无码AV久久久| 综合欧美激情网| 国产一进一出视频网站| 亚洲成人网站在线观看| 碰碰在线视频| 亚洲色性情三级| 黄色十八禁网站| 亚洲资源网| 91美女看B| 龙兴卡官方查询| 福利大香蕉| 精品日韩产品在线,日韩在线不卡视频,欧美日韩免费专区/久, | 97超碰人人操人人操| 另类图片综合| 亚洲精品国产无码高清| 午夜无码精品免费看性色| 亚洲 国产 精品一区| 操屄不卡视频| 天天操妹子| 97久久国产| 日本αv| 亚洲熟女性高潮久久久| 噜噜噜无码AV一级一级久久影院 | 极品人妻少妇综合| 国产精品人妻无码久久久老鸭窝 | 亚洲激情网一二三四区| AV天堂男人的天堂| 女人18精品一区二区三区| 91精品91久久久中77777| 大香蕉伊人网| 国模少妇一区二区三区| 伊人久久亚洲中文字幕| 东北女人性交| 性爱视频啪啪啪啪| 蜜臀久久久久久999| 日韩少妇在线视频| 97视频在线免费观看| 操逼国产免费| 国产精品小视频一区二区三区| 久久久久久久久久久久久久久久9| 青草精品视频一日本久久久久网站| 91久久久亚洲| 91chinese在线| 麻豆黄四叶草网站| 欧美精品三级黄片| 红杏大香蕉| 激情四射五月天| 少妇综合网| 99热只有这里有精品| 夜夜操夜夜爽夜夜高潮| 人人澡人人干| 日本午夜福利影院| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 久久99操天天日| 欧美日韩国产人人| 精品久久久高清无码| 精品国产乱码久久久久久影片| 欧美第二页午夜| 妇女性内射冈站HDWWWCOM| 伊人激情| 国产精品午夜福利| 婷婷性爱| 婷婷人妻激情| 婷婷AV一区二区三区| 97这里只精品| 天天干天天燥| 91真人天天在线| 偷拍精品一区二区三区| 6080yy午夜理论三级一区二区三区无码| 激情小说亚洲视频| 成人福利视频网| 欧美日韩亚洲电影| 久久av一级av少妇av高潮| 亚洲乱色视频一区、二区在线| 天天干人人乐| 婷婷六月色| 亚洲欧美洲综合| 乱精品一区字幕二区| 久久97视频| 涩五月婷婷| 清纯唯美第一页| 国产免费永久精品无码| 国产午夜福利合集| 色婷婷电影网| 天天躁日日躁狠狠躁| 爽爽歪在线视频| 婷婷涩嫩草鲁丝久久午夜精品| 五月天婷婷色色| 日韩精品中文字幕二区| 99re99在线视频| 五月天婷婷色色| 亚洲无码一区成人免费午夜| 欧美色三级片91| 亚洲av青草久久一区二区| 精品久久在线区一区| 国产品精品自在在线午夜免费| 中文字幕91综合| 国产欧美日本亚洲精品| 国产熟码AV| 超碰99热| 日韩欧美加勒比| 国产久久久9999| 18禁无码永久免费无限制| 97视频900| 日本3级一区二区免费| 60秒不遮不挡| 亚洲www91| 亚洲日韩精品在线播放| 欧美性生活男人的天堂| 很狠操| 人妻丝袜无 码视频专区| 91精品人| 丝袜加勒比| 日产国产精品中文久久婷婷| 逼逼逼逼操操操操操操操操操午夜剧场| 欧美激情一| 99精品丰满人妻无| 九九热AV| 天天插夜夜操| 91人妻人人澡人人爽人人精品| 天天日日本| av天堂5| 国产二区三区免费视频| 十八禁黄色| 欧美在线55555| 激情婷婷五月天| 亚洲国产婷婷在线播放| 农村女一级毛卡片| 97日韩欧美亚洲| 物尤视频一区二区| 95精品在线| 国产成人bd在线观看| 东京热毛片177b2viP| 亚洲少妇在线影音| 日欧美色| 青青国产精品在线| 日韩免费性爱视频在线观看| 黄在线| 伊人久久综合影院精品久久久| 久久99干一本高清| 情色五月天网| 中文字幕版| 色噜噜综合在线| 国产在线精品偷| 国产精品一区av在线| 92久久| 欧美日韩制服| 色69大色97香蕉| 亚洲电影中字一区二区| 性色综合网| 91欧美少妇| 蘋果手機免費看成人Av| 69人妻精品丰满熟女区| 久久久999日本大片| 日本在线激情一区二区三区| 天天操天天干一区二区 | 白天啪啪晚上啪啪视频| 久久久精品91八戒| 97精品熟女少妇一区| 无码久久亚洲高清,| 亚洲风情在线观看| 久艹日日日| 99热销国产这里有精品| w w w.久久精品| 亚洲情欲| 久久久少妇| 亚洲中文字幕精品一区| 亚洲中文字幕精品一区| 亚洲中文字幕精品一区| 成人午夜高潮av猛片| 97色网| 人人弄人人摸| 国产精品视频91久久| 五月天婷婷在线看| 色操逼网| 噜噜噜无码AV一级一级久久影院 | 后入人妻无码| 日韩91网站| 91亚洲人| 99久久精品无码一区二区毛片免费| 综合久久久久久久久91| 一类av片在线看| 大香蕉专区| 岛园激情| 蜜臀少妇一区二区| 第四色色综合91| 超碰这里只有精品| 日韩特一级久久| 传媒在线观看一区二区三区| 四虎免费在线观看| 国产精品日韩在线一区| 日韩中文字幕视频在线观看| 一本道综合色图| 蜜臀精品1区2区| 久久日本熟女精品一区| 日韩欧美久久婷婷网站| 欧美色人| 日本丝袜人妻内射| 99热亚洲| 玖玖爱在线视频免费观看| 日韩免费簧片| 日韩乱插| 人人摸人人干| 色偷偷2020免费视频播放| 97极品无码| 精品一区二区在线针对华人免费观看这里只有精品免费观看 | 色汉综合| 国产AV高清AV无码| 麻豆人妻少妇在线免费观看| 67914在线兔费成人视频| 欧美色涩| 欧亚在线视频| 久久夜嗨| 欧美AB在线| 久操网线| 九九成人精品| 亚欧美色| 欧美黄色片AAAAA| 九九精品美女高溯喷水| 亚洲丨在线| 91av一区二区在线观看| 国模限制级电影| nuu12国产麻豆精品| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 色成人Www精品永久观看| 超碰97起碰| 91日日夜夜| www.久久制服糖| 欧美1727免费观看视频| 热热色青青草| 日本精品高清一二区一本到| 亚洲drav色图| 99国产在线 精品 视频| 青青草亚洲一区 | 艹我哪美一区无码| aV中文麻| 91精品黄在线观看| 色偷偷综合91久久噜噜| 欧美日韩亚洲国产中文永久天天看| 色九久| 亚洲欧美人妻| www.99热| 大JI巴好深好爽又大又粗视频| 亚洲日韩AV视色| 国产偷拍网站| 久久99国产综合精品女同| 精品国产99999| 欧美性爱视频免费一区一A| 污污污8888| 日本十八禁免费看污网站| 国产精品久久久视频| 国产精品自拍视频| 国产精品久久久亚洲一区| 深夜激情| 久色网| 国产激情在线| 日韩三级视频一区二区三区| 人妻天堂网| 人人摸人人干| 青草精品视频-日本久久久久网站| 国产一区二区视频在线播放| 精品少妇一区二区| 视频二区美腿丝袜制服人妻欧美| 男人在线天堂| 成人色女网| 午夜福利无毒不卡| 91九色丰满高潮| 99久久婷婷国产综合| 噜噜噜噜久久久精品免费| 91精品久久久久久综合五月天| www.人人摸在线视频| 婷婷五月天成人| 亚洲欧美第一页| 亚州综合电影| a级理论午夜日本| 97综合激情| 91n美女视频| AV天堂国产| 九热超碰| 国产精品小视频一区二区三区| 亚洲精品一二牛牛| 亚洲怡春院| 好吊妞转入那个网| 男女猛烈无遮掩视频免费软件| 色九九九综合| 六月激情网| 精品无码一区二区三区| 精品成人无码| 人人妻天天做天天爽| 五月婷在线| 翔田千里无码一区| 蜜汁欧美| 欧亚第一综合网| 亚洲 欧美 手机在线观看| 97 色综合| 久久m| 婷婷综合视频| 黄色一区二区秘书性感| 中文字幕熟女人妻丝袜| 综合色久欲| 炮色五月| 久久国产视频性吧 | 青青久久艹| 久久国模av| 亚洲色婷婷| 黄色片一区二区三区四区五区 | 99久久网站| 麻豆国产视频精品观看| 999精品乱码| 97天天插| 91中文精品日韩欧美在线| 婷婷五月天激情网| 日本女优在线视频福利| 国产久久免费精品视频| 91天天看| 大香蕉欧美| 一二区在线观看视频| 色天堂综合| 男人的天堂激情| 九九AV| 婷婷五月天激情网| 秋霞久久亚洲精品成人| 大香蕉乱级| 精品999999| 91精品国产91熟女| 丝袜美腿91| 91亚.色| 啊啊啊啊好疼视频| 1024午夜激情男人的天堂| 中文字日本乱码| 超AV色女| 欧美熟妇精品黑人巨大一二三区| 精品久久視頻在线| 蜜臀中文无码午夜| 国产成人精品午夜福利| 97久久久精品| 一区二区三区 丝袜高跟| 青青青国产| 91n美女视频| 久久久久骚| 亚洲熟妇图片| 久草色悠悠在线视频| 久久这里精品国产99丫e6| 国产少妇与亚洲av| 欧美日韩理论一区| 欧美色图中文字幕| 亚洲少妇在线影音| 秋霞鲁丝午夜无码一区二区三| 色香在线| 一区二区三区四区在线不卡| 夜夜高潮夜夜爽国产伦精品| 精品国产综合久久福利,热99这里有精品综合久久,99热这里只有免费国产精品,精 | 九九视品黄色| 第二页中文字幕| 亚洲精品欧洲精品| 中文字幕人乱码中文字的预防方法 | 97亚洲精品超碰| 亚洲毛片基地专区| 国产黄色小视频网站| 园内精品自拍视频在线播放| 精品黑人一区二区| 天天做天天爱天天高潮| 九九久久久久久爱| 久久这里| 少妇三p| 欧美精品成人一区二区在线观看| 欧洲综合无码| 天天色播亚洲综合网站| A V少妇特黄三级| 欧美激情 日韩精品| 伊人伊人LD| 小电影欧美91| 伊人专区一区二区三区| 精品一区二区亚洲国产| 俺去久久| 智利AV在线网| 爱爱动态60秒| 3P乱轮视频| 黄色AV影视| 综合91网| 思思热一热婷婷热一热| 约操熟妇| 青娱乐亚洲热| 亚洲大色鬼| 亚洲日韩国产精品| 97任你吞精| 天天干天天日天天射黄色大片| 日韩淫色网| 蜜臀视频网站| 久久久精品成人国产| 用力操死我| 少妇高潮九九九九九九九| 欧美黄色手机在线观看| 97干在线视频| 制服诱惑亚洲一区二区三区在线观看| 男人的天堂va在线| 在线观看亚洲专区| 成人综合视频久久| 亚洲有码视频二区| 久久婷婷综合国际产色怕| 久久精品亚洲东京热色播| 亚洲中文字幕av | 国产四虎在线| 好涩综合| 在线可观看的黄色网址| 精品乱子一区二区三区99| 怡红院成人视频| 一,爱啪啪,在线免费视频| 91欧美偷拍| 精品国产乱码久久久久久网站入口| 色网在线视频观看免费| 亚洲色图 欧美热图 清纯唯美 另类自拍| 加勒比av网| 人妻一区视频| 东京热av男人的天堂| 色呦呦国产精品免费看| 青草青青久久久久久国产| 欧美综合天堂| 国产超碰在线| 清纯唯美综合| 午夜丁香| AV女资源| 色情婷婷| 91人人操| 精品四五区| 天堂无码| 美日韩一卡二卡三卡免费人妻精品| 国产熟女无套内射| 骚逼高潮久久精品| 97资源久久| 天天日日舔舔| 91免费看一区二区三区| 亚洲日韩av一区二区三区百合| 亚洲男人天堂AV| 91N欧美| 欧美一区二区三区不卡高清视频| 亚洲精品一二三四区| 日韩一级欧美一级国产一级台湾| 国产精品乱人伊人网| 亚洲影院成人| 美女91在线观看| 伊人久久在线视频观看| 欧美一级专区免费大片| 粉嫩不卡一区二区性爱| 天天日骚逼熟女| 亚洲av乱伦色图网站| 久久久久成人网| 99热在线观看| 日韩成人高清一区二区| 嗯嗯啊啊视频一区二区三区| AAAAAAAAA黄片| 亚春色色| 99啪啪视频| 欧美一级A片不卡视频。| 国产精彩女在线观看视频| 亚洲欧洲网站免费观看| 狠狠操狠狠操操| 韩国女主播青草在线| 中国女人内射6XXXXX| 久久有码视频| 精品无人区麻豆乱码久久久| 日韩丰满熟妇| 丰满人妻一区二区三区免费| 亚洲激情 欧美色图| 亚洲天堂AV在线播放| 国产美女高潮视频| 97精品久久久久久久| 懂色AV蜜臀无码精品APP| 久久激情婷婷| 激情四射五月天| 日本大片日本一区二区免费高清| 九九视频黄色片| 日本天堂在线播放| 亚洲中文人妻色| 国产视频一区二区免费| 日韩啊V| 中文字幕av片| 欧美老妇女内射网址| 久久久97| 一本久道在线综合视频| 老熟女综合| 蜜臀aV午夜一区二区三区| 青青操青娱乐| 黄片无码在线制服| 日韩福利综合一区| 亚洲人妻五月丁香婷婷| 日韩丝袜高跟制服在线观看| 不卡在线一区,精品一区二区三区中| 免费福利视频中文字幕| 97网色| 久久久久国产精品人妻aⅴ天堂| 久操九九九九| 91久久久久久久久18| 密乳无码| 欧美成年人性爱视频免费观看| 人妻激情视频| 99精品丰满人妻无码| 安徽熟妇视频| 久久精品免费| 女优免费一区二区永久| www.av在线观看| 伊人久久大香线蕉无码| 久久久久久99AV无码免费网站| 久久久久久久久久久久97 | 色色色色网站| 日本熟妇人妻中出视频| 一类av片在线看| 国产成人91一区二区三区| 超碰97国产欧美| 蜜臀99久久精品| 日韩 女同 综合| 亚洲精品蜜桃久久久久久久| 日韩AV一区二区三区三州三州| 男人的天堂不卡一区二区 | 青青草女人天天干| 日韩 女同 综合| 99热18这里只有精品| 区二区亚洲婷| 少妇精品久久久| 欧美伦乱爱| 免费网色网站| 亚洲色图欧美色图制服诱惑| 日欧毛片久久| 伊人色综合欧美| 97精品在线| 青久久| 亚洲人精品久久久| 极品美女嘿咻| 久久久不卡| 啊啊啊想要| 91少妇| 在线观看一级α片刺激高潮视频| 秋霞操逼片| αⅴ天堂| 中文字幕精品区先锋资源| 久久欧美性爱视频| 天天综合色| 人人澡人人爽人人精品| 91国产大片| 91N综合网在线| 超碰在线1234区| 久久久极品| 大色综合| 超碰色男人操熟女| 亚欧无码在线| 婷婷综合在线| 怡红院怡春院| 午夜精品久久999热蜜桃介男人用| 欧美国产操逼| 亚洲第一页色网| 翔田千里AV无码秘 三区| 秋霞一级鲁丝片A片| 国产高清26uuu| 91热爆在线| 韩日男人的天堂| 麻豆精品三区视频| 91白虎| 人人人摸人人| 2020国产精品| 亚洲综合有玛| 激情文学亚洲| 婷婷伊人五月| 人人摸人人叼| 色呦呦、国产精品| 69丨亚洲丨精品丨入口免费播放| www亚洲欧美| 免费人成在线观看网站品爱网| 亚洲aV性爱| 91在线视频免费中出| 国产后入内射| 麻豆三极片| 手机看片1024你懂的国产| 天天淫人人妻日日色| 欧美黑人91| 亚洲AV成人精品网站在AV| 精品国产久热在线观看| 国产13区| 日比av无码| 九色精品视频导航1| 中文字幕大片三级狠狠干| 狠狠干妹子| 欧美一区二区一级岛国大片| 成片免费观看视频大全| 欧美激情久久久久| 永久电影三级在线观看| 亚洲成人网站在线观看| 在线观看午夜婷婷久久久久清性观看| 精品对白久久不卡| 第一高清av中文字幕| 少妇三P| av网站免费看| 午夜人妻精品综合在线| 91亚洲欧美综合高清在线| 久久 国产 无码| 亚洲AV小说| 91天美免费| 插日本熟女视频| 麻豆伊人网| 亚洲影院无码在线| baisiav| 日本欧美不卡| 亚洲一区中文字幕一区| 亚洲清纯唯美| 亚洲情色中文字幕一区| 韩国女主播青草在线| 亚洲婷婷综合网| 精品国产乱码久久久久久影片| 蜜汁欧美| 午夜色婷婷| 在线观看啊啊啊啊啊| 一区二区三区免费岛国片| 国产肏屁眼视频| 久久av无码| 亚洲另类色图片| 激情小说图片亚洲首页| 91女神在线视频| 日韩av性爱在线播放| 日本一二区免费| 天天影视色香欲综合网小说| 久妇网| 国产在线综合福利网站| 精品无吗久久| 国产一区二区在线播放量| 夜夜嗨av午夜成人| 操逼大黄片| 亚洲伊人久久精品影院| 欧美日韩国产中文精品字幕自在自线| 欧美天天综合站| 国产操逼逼网| 久久久青草青青国产亚洲免观精品高清完整版_97久久综合区小说区图片区,国精品 | 欧美色网| AV高清一区| 亚洲精品性爱片| 啊啊啊啊啊啊啊网址在线观看| 国产精品一区二区三区,亚洲综合| 亚洲男人的天堂网| 欧美特大黄一级片片免费| 亚洲中文丝袜美腿诱惑字幕| 一区二区日韩欧美久久| 久久色网| 日日做夜狠狠爱欧美黑人| 操逼操网| 97色综合中文网| 天天日日日射| 男人a天堂手机在线版| 亚洲自拍小说| 久久久久久大| 欧美日韩香蕉| 96精品久久| 啊啊啊不要啊啊受不了了视频在线| 精品人妻一区二区视频| 偷偷人人精品女女久久| 人人澡人人爽人人精品| 国产人妖视频一区在线观看| AV女资源| 久久中出在线| 91色婷婷综合久久中文字幕二区| 久久久蜜桃臀无码视频| 欧美在线视频播放| 人妻嗯啊啊在线播放| 无码操逼视频一下| 大香蕉一人| 操香逼| 99久久久久| 日韩熟女操逼| 久久线上视频免费看| 精品国产一区二区三区久久久蜜臀| 国产尤物AV尤物在线观看不卡| 激情小说亚洲色图| 色综合20p| 91N欧美| 丰满人妻一区二区三区大胸懂色| 97超碰久久| 伊人在线大香蕉视频久久| 老鸭窝亚洲毛片| 睡产熟女乱伦| 韩三级a视频在线观看| 欧美操逼录像国产黄色国产| 久9久9精品| 亚州色交| 美女自卫慰黄网站免费| 日本精品网站在线中文| 国产极品馒头逼| 欧美96交| a人片中文字幕一区二区| yirendaxiangjiashipin| 99精品久久久久久久婷婷蜜桃| 欧美性爱无码一区二区三区| 欧美加勒比| 九九九偷拍| 五毛骚逼极品美女怕怕| 一区,二区,三区网站| 美女刺激久久国产欧美| 女同性恋久久| 两性色网| 国产精品久久久久久久AV大片| 日韩小电影| 亚洲综合色图欧美| 97精品网站| 六月婷婷一区二区三区| 国产老熟女| 美女露胸露尿口| 综合熟女| 六月婷婷激情| 久久九色| 激情久久av一区av二区av| 在线看片国产精品每日更新| 国产男女边吃边摸视频网站| 精品免费视频国产一区| 大奶的诱惑| 美女黄站| 97天天日| 97视频免费在线观看| 久久东京热久久| 精品一区二区三区麻豆| 91精品国产91熟女| 国产AV中文| 91欧美综合| 97超碰欧美| 日本一级特级毛片视频| 国产高清自拍| 国产精品点击进入在线影院高清| 日本不卡五区| 襙一襙| 日婷婷| 国产精品亚洲天堂网址| 久久91精品国产9丨久久分亭| 日韩丰满熟妇| 深田咏美亚洲精品福利社| 极品尤物在线观看| www.狠狠操| 性色乱AV一区二区| 99热导航| 超碰久久网| 天天天干977| 超碰97久久| 成人无码电影在线观看网| 亚洲精美粉嫩嫩泬在线观看| 日韩AV熟女乱伦| 欧美亚洲日韩人妻在线观看| 欧美熟妇乱码在线一区| 国产精品视频| 美女上床网站| 久久专区| 2017人人操,人人摸| 夜间福利片1000无码| 婷婷久久五月| 男人天堂站| 久久视频,这里只有精品| 青青在线视频免费| 立川理惠被中出无码| 中国zzijzzijzzwww精品| aaa一级黄片| 视频在线观看一二三区| 91老熟女老女人国产老太| 日韩天天综合| 岛国黄片网站| 一区三区啪啪| 天天摸夜夜摸| 久久风骚城市| 国产强奸乱伦第1页| 精品一区二区综合熟妇| 欧美色图天堂在线| 无码男人天堂| 天天综合~91| 国产精品一二三在线看| 欧美不卡在线美女| 少妇99| 午夜小电影在线插入淫高潮| 思思热er精品视频| 日本有码影片下载| 欧美亚洲高清晰| 尤物av网站免费在线播放| 天天躁日日躁XXXXYY| 熟妇一区二区三区| 蜜臀99久久精品久久久久久| 被男人吃奶很爽的毛片| 日韩成人精品中文字幕| 九九九九免费高| 成人精品在线免费视频| 极品色www影院| 中文字幕人妻色偷偷久久皮| 色香欲综合| 丰满人妻av一区二区三区| 射欧美综合| 久久久久久久性爱| 欧美性爱在线无码| 97碰碰日本乱偷人妻中文的| 在线视频97| 97综合在线| 黄色一区三区| 色天使亚洲综合在线观看| 亚洲AV无码天美传媒一区| 精品超碰色| 黄色网址在线免费观看| 97久久久精品| 91精品无码久久久久久久| 亚洲欧美精品91| 超碰欧美COM| 激情啪啪拍91| 欧美综合 站| 成年人三级黄色片视频| 中文字幕视频2区| 欧美99999| 蜜臀久久99精品久久久老,,| 亚洲成人AB| 性爱av网站| 久久 久久国内精品亚洲| 不卡av在线中文字幕| 日少妇亚洲版| 国产精品久久aV| 亚洲s在线观看| 99久久精品国产系列| 怡红院视频在线| 亚洲影视综合| 青青草日韩无码| 中国少妇啪啪视频| 99激情视频| 热热色91| 中文字暮97| 亚洲天堂男人的天堂| www.狠狠干.coom| 好爽视频在线观看视频| 精品女人999| 亚洲无线观看久久| 久久色一区| 人人操 欧美| 天天影视射综合网| 中文字幕一区二区韩| 97干综合网| 五月色网| 亚洲资源站| 冬京热男人的天堂| 亚洲国产一区二区日韩专区| 亚洲精品国产av天美传媒| 成人a大片在线观看| 国产免费一区| 亚洲综合色婷婷| 射综合网| 午夜欧美J进J出白浆流出久久久| 欧美大香蕉久| 久操影视| 激情小说五月天| 一二三区操逼国产91| 91网站18在线| 在线观看黄色电话| 国产成人五月天丁香花| 丝袜内射| 亚欧视频在线| 国产搭汕a级片| 欧美日韩人人精品| 国产免a费看黄片在线| 997色在线| 天天色悠悠激情| 天天操夜夜操狠很操| 福利天天都操| 艳美熟妇先锋一二三区| 国产乱色国产精品免费视| 91综合天天看| 精品无码一区二区| www.91理论| 精品天堂| 天天综合网1| 久久婷婷影院| 欧美在线永久天堂| 91精品91久久久久77777| 旡码电影特区| 国产精品久久久久久片| 综合夜夜| 狠狠爱夜夜干| 亚洲AV乱码专区国产噜噜亚洲| 日本无码1| 综合久久97| 人妻喷水| 亚洲三级网址久久最新| 国产久久久久久久久一区二区| 国产二区三区免费视频| 久久激情视频| 日韩啪啪啪视频| 人妻少妇精品一区二区三区| 天天操天天射天天日| 国产女人视频三四五区| 伊人久久亚洲色欲综合网站 | 日韩成人无码| 99热在线只有精品| 日韩少妇无吗| 久jiu久神马影院| 亚洲精品日日夜夜52| 家庭乱伦国产| 欧美极品| 亚洲情色 自拍| 欧美综合 站| 日本加靬比网站发布页| 这里只有精品久久| 天堂中文资源在线bt| 日韩成人高清一区二区| 九久久九九久视频| 久久人人爽av亚洲精品天堂桃色| 青青草视频爽一爽| 国产少妇肉丝在线观看| 亚洲国产成人高清在线| 二男一女成人A片| 久久草草亚洲蜜桃臀| 欧美色性情| 91欧| 亚洲 欧美 日韩另类 麻豆| 美美91成人国产精品欧美精品久久久久久久 | 久久欧洲| 91欧美偷拍| 荡小穴在线观看| 亚洲综合网电影91| 色婷婷丁香五月天| 午夜福利成人免费视频| 亚洲AV无码AV吞精久久久久| 岛国毛片在线观看免费| 精品无码一区二区三区| 伊人国产成人av网站| 亚洲天堂男人网| 久久激情婷婷| 大香蕉综合网| 欧色综合| 中文字幕视频2区| 亚洲精品影视老司机| 婷婷久草| 国产 丝袜 欧美中文 另类| 秋霞影音一区二区三区| 国语国产操逼伊人AV网| 精品视频免费在线一区| 久久这里是精品| 国产亚洲女v在线观看| 人人潮人人摸| 国产精品呦一区二区三区| 这里只有精品视频在线观看麻豆| 一级片在线观看高清无码| 国产精品嫩草久久久久| 亚洲制服aⅴ中文字幕| 久干9操| 嫖老熟女A片一二三区| 亚洲精品三| 欧美夜夜狠| 800zy一区二区| 老汉网|