日韩欧美人妻无码精品白浆,夜夜嗨AV免费入口,国产欧美官网在线看,高校回应聋哑女生因长相完美被质疑

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#.NET 依賴注入中的 Captive Dependency

freeflydom
2025年1月10日 9:2 本文熱度 949

今天我先給大家出一道題:

    public interface IDbContext
    {
    }
    public class SqlServerDbContext : IDbContext
    {
    }
    public class LongTermSerive : BackgroundService
    {
        private readonly IDbContext _context;
        public LongTermSerive(IDbContext context)
        {
            _context = context;
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return Task.CompletedTask;
        }
    }
builder.Services.AddScoped<IDbContext, SqlServerDbContext>();
builder.Services.AddHostedService<LongTermSerive>();

請問以上服務(wù)的注冊有沒有問題?
熟悉 .NET 的同學(xué)很快就會說:這當(dāng)然有問題,IDbContext 是 Scope 生命周期,LongTermSerive 因為注冊成了 HostedService 所以實際上它是 Singleton 生命周期。Singleton 不能持有 Scope 生命周期的服務(wù)。說的更通用一點的話就是:生命周期長的服務(wù)無法依賴生命周期比它的服務(wù)。
真的是這樣嗎???
以上回答只說對了一半。這時候肯定馬上會有同學(xué)跳出來說,“這怎么會不對呢?我剛剛都試過了,VS直接報錯了”。

System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: DevelopmentTest.LongTermSerive': Cannot consume scoped service 'DevelopmentTest.IDbContext' from singleton 

不要著急讓我們繼續(xù)分析下去。

Captive Dependency#

首先讓我們澄清一個概念。像以上這種情況:當(dāng)生命周期長(Singleton)的服務(wù)持有生命周期短(Scope)的服務(wù)的時候我們叫做 "Captive Dependency"(Transient不在討論范圍內(nèi))。

不知道怎么翻譯成中文比較合適。微軟的文檔上翻譯作"捕獲依賴",個人認(rèn)為不太恰當(dāng)。

"Captive Dependency" 會帶來什么問題?

  1. 生命周期短的服務(wù)會被 DI 容器及時釋放,比如調(diào)用了 Dispose 方法,導(dǎo)致后續(xù)的操作失敗。
  2. 非線程安全。Singleton 的對象很容易被多個線程共享,但 Scope 的話大多數(shù)情況都是非線程安全的。比如上面的 DbContext,當(dāng)在線程內(nèi)共享,發(fā)生并發(fā)操作的時候程序是無法保證正確運行的。

.NET DI 支持 Captive Dependency 嗎?#

當(dāng)我們了解這個概念后,上面的問題可以轉(zhuǎn)換成 " .NET DI 支持 Captive Dependency 嗎?"。

根據(jù)上一次我們的文章的內(nèi)容,我們知道 .NET DI 的行為是跟所在的環(huán)境有關(guān)系的。所以討論這個問題我們還是要分開來看待:

  • Development 環(huán)境下,.NET DI 會在構(gòu)建 ServiceProvider 的時候去校驗服務(wù)的依賴關(guān)系。這個時候就會像上面提到的一樣,直接報錯。
  • 非 Development 環(huán)境下在構(gòu)建 ServiceProvider 的時候不會校驗服務(wù)間的依賴關(guān)系,程序有可能正確運行。為什么說是有可能呢?因為這個完全取決與你的代碼是怎么寫的。也許你短生命周期的服務(wù)在某些場景下正巧可以工作,又或者正巧不能工作。但是有一點是明確的,就是 Captive Dependency 是危險的。因為當(dāng)你注冊成 Scope 或者 Transient 的時候往往是帶了某種暗示。比如 Scope 對象是非線程安全的。顯然 Socpe 服務(wù)的編寫者沒有義務(wù)去考慮被 Singleton 服務(wù)依賴時候的問題。
  • 手動開啟 ValidateScopes = true 的時候不管什么環(huán)境下都會進(jìn)行依賴關(guān)系的校驗,類似 Development 環(huán)境下。

總結(jié)#

現(xiàn)在我們可以作一個總結(jié):
.NET DI 是支持 Captive Dependency 的,但是在 Development 環(huán)境下或者手動開啟 ValidateScopes = true 的時候它不支持,它會阻止 Captive Dependency。換句話說 .NET DI 在阻止 Captive Dependency 上只做了一半的工作,并不能 100% 確保不發(fā)生 Captive Dependency。開發(fā)者們在寫代碼的時候還是要自己注意了,不能完全依賴 .NET 的檢測。
關(guān)于這個問題,我也在 .NET Runtime 的 Repository 下開了一個 ticket 進(jìn)行討論。微軟給出的理由是基于性能的考慮,生產(chǎn)環(huán)境這個校驗?zāi)J(rèn)不開啟。其實我個人覺得微軟應(yīng)該不管在什么環(huán)境下都默認(rèn)開啟校驗,盡可能的避免 Captive Dependency。因為 90% 的項目其實并不在乎這點性能開銷。如果你的應(yīng)用程序真的很在乎性能那么可以手動關(guān)閉這個校驗,這個時候開發(fā)者自己需要完全對這個依賴關(guān)系負(fù)責(zé)。

https://blog.ploeh.dk/2014/06/02/captive-dependency/
https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-guidelines#captive-dependency
https://github.com/dotnet/runtime/discussions/109491

?轉(zhuǎn)自https://www.cnblogs.com/kklldog/p/18663148/captive-dependency


該文章在 2025/1/10 9:02:30 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved