.NET開發(fā)中全局?jǐn)?shù)據(jù)存儲(chǔ)的常見方式
一、靜態(tài)類與靜態(tài)成員
實(shí)現(xiàn)方式
public static class GlobalData { public static string ApplicationName { get; set; } = "MyApp"; public static int MaxConnections { get; } = 100; private static readonly ConcurrentDictionary<string, object> _cache = new ConcurrentDictionary<string, object>(); public static void SetCache(string key, object value) { _cache[key] = value; } public static T GetCache<T>(string key) { return _cache.TryGetValue(key, out var value) ? (T)value : default; } }
特點(diǎn)
- 生命周期:應(yīng)用程序域生命周期
- 線程安全:需要手動(dòng)實(shí)現(xiàn)(如使用 ConcurrentDictionary)
- 適用場(chǎng)景:小型應(yīng)用、工具類、全局配置
優(yōu)缺點(diǎn)
- 簡(jiǎn)單易用
- 訪問速度快
- 缺乏持久化
- 測(cè)試?yán)щy(靜態(tài)依賴)
二、應(yīng)用程序配置系統(tǒng)
1. appsettings.json (ASP.NET Core)
{ "AppConfig": { "Theme": "Dark", "Timeout": 30 } }
使用方式
// 在Startup中配置 services.Configure<AppConfig>(Configuration.GetSection("AppConfig")); // 注入使用 public class MyService { private readonly AppConfig _config; public MyService(IOptions<AppConfig> config) { _config = config.Value; } }
2. 用戶設(shè)置 (WinForms/WPF)
// 保存設(shè)置 Properties.Settings.Default.Theme = "Dark"; Properties.Settings.Default.Save(); // 讀取設(shè)置 var theme = Properties.Settings.Default.Theme;
特點(diǎn)
- 生命周期:持久化到配置文件
- 線程安全:內(nèi)置線程安全
- 適用場(chǎng)景:應(yīng)用程序配置、用戶偏好設(shè)置
三、依賴注入容器
ASP.NET Core 示例
// 注冊(cè)服務(wù) services.AddSingleton<IGlobalCache, MemoryCache>(); services.AddScoped<IUserSession, UserSession>(); // 使用 public class MyController : Controller { private readonly IGlobalCache _cache; public MyController(IGlobalCache cache) { _cache = cache; } }
特點(diǎn)
生命周期:
- Singleton: 應(yīng)用程序生命周期
- Scoped: 請(qǐng)求生命周期
- Transient: 每次請(qǐng)求新實(shí)例
線程安全:取決于實(shí)現(xiàn)
適用場(chǎng)景:ASP.NET Core 應(yīng)用、服務(wù)共享
四、內(nèi)存緩存 (IMemoryCache)
實(shí)現(xiàn)方式
// 注冊(cè) services.AddMemoryCache(); ???????// 使用 public class DataService { private readonly IMemoryCache _cache; public DataService(IMemoryCache cache) { _cache = cache; } public string GetCachedData(string key) { return _cache.GetOrCreate(key, entry => { entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30); return ExpensiveDatabaseCall(); }); } }
特點(diǎn)
- 生命周期:應(yīng)用程序重啟后丟失
- 線程安全:內(nèi)置線程安全
- 適用場(chǎng)景:頻繁訪問的臨時(shí)數(shù)據(jù)
五、分布式緩存 (IDistributedCache)
實(shí)現(xiàn)方式
// 使用Redis services.AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }); // 使用 public async Task<byte[]> GetCachedDataAsync(string key) { return await _distributedCache.GetAsync(key); }
特點(diǎn)
- 生命周期:持久化到外部存儲(chǔ)
- 線程安全:內(nèi)置線程安全
- 適用場(chǎng)景:分布式應(yīng)用、多實(shí)例共享數(shù)據(jù)
六、HttpContext.Items (ASP.NET Core)
實(shí)現(xiàn)方式
// 中間件中設(shè)置 app.Use(async (context, next) => { context.Items["RequestStartTime"] = DateTime.UtcNow; await next(); }); // 控制器中訪問 var startTime = HttpContext.Items["RequestStartTime"] as DateTime?;
特點(diǎn)
- 生命周期:?jiǎn)蝹€(gè)HTTP請(qǐng)求期間
- 線程安全:每個(gè)請(qǐng)求獨(dú)立
- 適用場(chǎng)景:請(qǐng)求級(jí)數(shù)據(jù)共享
七、環(huán)境變量
訪問方式
var envVar = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
特點(diǎn)
- 生命周期:進(jìn)程生命周期或系統(tǒng)級(jí)
- 線程安全:只讀操作安全
- 適用場(chǎng)景:部署配置、環(huán)境特定設(shè)置
八、數(shù)據(jù)庫(kù)存儲(chǔ)
實(shí)現(xiàn)方式
// 使用EF Core public class AppDbContext : DbContext { public DbSet<GlobalSetting> GlobalSettings { get; set; } } // 使用 var setting = await _dbContext.GlobalSettings .FirstOrDefaultAsync(s => s.Key == "MaintenanceMode");
特點(diǎn)
- 生命周期:持久化
- 線程安全:取決于數(shù)據(jù)庫(kù)訪問層
- 適用場(chǎng)景:需要持久化的全局配置
九、選擇指南
存儲(chǔ)方式 | 生命周期 | 持久化 | 分布式支持 | 典型使用場(chǎng)景 |
---|---|---|---|---|
靜態(tài)成員 | 應(yīng)用程序域 | 否 | 否 | 全局常量、簡(jiǎn)單緩存 |
應(yīng)用程序配置 | 持久化 | 是 | 部分 | 應(yīng)用設(shè)置、用戶偏好 |
依賴注入容器 | 取決于注冊(cè)類型 | 否 | 否 | 服務(wù)共享、全局服務(wù) |
內(nèi)存緩存 | 應(yīng)用程序 | 否 | 否 | 頻繁訪問的臨時(shí)數(shù)據(jù) |
分布式緩存 | 持久化 | 是 | 是 | 多實(shí)例共享數(shù)據(jù) |
HttpContext.Items | 請(qǐng)求期間 | 否 | 否 | 請(qǐng)求級(jí)數(shù)據(jù)傳遞 |
環(huán)境變量 | 進(jìn)程/系統(tǒng) | 是 | 是 | 部署配置、環(huán)境特定設(shè)置 |
數(shù)據(jù)庫(kù)存儲(chǔ) | 持久化 | 是 | 是 | 需要持久化的全局配置 |
十、最佳實(shí)踐建議
1.按需選擇:根據(jù)數(shù)據(jù)特性(大小、訪問頻率、生命周期)選擇合適方式
2.分層設(shè)計(jì):
- 高頻小數(shù)據(jù):內(nèi)存緩存
- 配置數(shù)據(jù):appsettings.json
- 用戶數(shù)據(jù):數(shù)據(jù)庫(kù)
3.線程安全:
- 多線程訪問時(shí)使用線程安全集合(如 ConcurrentDictionary)
- 考慮使用 Immutable 集合避免意外修改
4.性能考慮:
- 大數(shù)據(jù)集避免使用靜態(tài)變量
- 考慮使用緩存過期策略
5.測(cè)試友好:
- 避免過度使用靜態(tài)類
- 優(yōu)先使用依賴注入
6.分布式場(chǎng)景:
- 多服務(wù)器環(huán)境使用分布式緩存
- 考慮使用消息隊(duì)列同步狀態(tài)
十一、高級(jí)模式示例
混合緩存策略
public class HybridCache { private readonly IMemoryCache _memoryCache; private readonly IDistributedCache _distributedCache; public HybridCache(IMemoryCache memoryCache, IDistributedCache distributedCache) { _memoryCache = memoryCache; _distributedCache = distributedCache; } public async Task<T> GetOrCreateAsync<T>(string key, Func<Task<T>> factory, TimeSpan expiration) { if (_memoryCache.TryGetValue(key, out T memoryValue)) { return memoryValue; } var distributedValue = await _distributedCache.GetStringAsync(key); if (distributedValue != null) { var value = JsonSerializer.Deserialize<T>(distributedValue); _memoryCache.Set(key, value, expiration); return value; } var newValue = await factory(); _memoryCache.Set(key, newValue, expiration); await _distributedCache.SetStringAsync(key, JsonSerializer.Serialize(newValue), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = expiration }); return newValue; } }
配置熱重載
// Program.cs builder.Services.Configure<AppConfig>(builder.Configuration.GetSection("AppConfig")); builder.Services.AddSingleton<IOptionsMonitor<AppConfig>>(provider => provider.GetRequiredService<IOptionsMonitor<AppConfig>>()); ???????// 使用 public class ConfigService { private readonly AppConfig _config; public ConfigService(IOptionsMonitor<AppConfig> configMonitor) { _config = configMonitor.CurrentValue; configMonitor.OnChange(newConfig => { _config = newConfig; }); } }
通過合理選擇和組合這些全局?jǐn)?shù)據(jù)存儲(chǔ)方式,可以構(gòu)建出既高效又易于維護(hù)的 .NET 應(yīng)用程序架構(gòu)。
到此這篇關(guān)于.NET開發(fā)中全局?jǐn)?shù)據(jù)存儲(chǔ)的常見方式的文章就介紹到這了,更多相關(guān).NET全局?jǐn)?shù)據(jù)存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET?MVC遍歷驗(yàn)證ModelState的錯(cuò)誤信息
這篇文章介紹了ASP.NET?MVC遍歷ModelState錯(cuò)誤信息的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09詳解.NET Core+Docker 開發(fā)微服務(wù)
這篇文章給大家分享了.NET Core+Docker 開發(fā)微服務(wù)的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們參考下。2018-09-09ASP.NET動(dòng)態(tài)加載用戶控件的實(shí)現(xiàn)方法
動(dòng)態(tài)加載用戶控件的方法,用asp.net的朋友推薦2008-10-10asp.net實(shí)現(xiàn)根據(jù)城市獲取天氣預(yù)報(bào)的方法
這篇文章主要介紹了asp.net實(shí)現(xiàn)根據(jù)城市獲取天氣預(yù)報(bào)的方法,涉及asp.net調(diào)用新浪接口獲取天氣預(yù)報(bào)信息的實(shí)現(xiàn)技巧,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下2015-12-12Asp.net Core中如何使用中間件來管理websocket
這篇文章主要給大家介紹了關(guān)于Asp.net Core中如何使用中間件來管理websocket的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09ASP.NET網(wǎng)站實(shí)時(shí)顯示時(shí)間的方法
這篇文章主要介紹了ASP.NET網(wǎng)站實(shí)時(shí)顯示時(shí)間的方法,主要通過AJAX控件來實(shí)現(xiàn)該功能,是非常具有實(shí)用價(jià)值的技巧,需要的朋友可以參考下2014-11-11在.net core中實(shí)現(xiàn)字段和屬性注入的示例代碼
這篇文章主要介紹了在.net core中實(shí)現(xiàn)字段和屬性注入的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08