编辑
2025-02-03
C# 应用
00
请注意,本文编写于 92 天前,最后修改于 92 天前,其中某些信息可能已经过时。

目录

目录
引言
开发通用的 CacheService
ICacheService 接口
CacheService 实现
配置依赖注入
缓存应用场景示例
数据库查询结果缓存
DatabaseService.cs
程序入口
API 响应缓存
ApiService.cs
程序入口
复杂计算结果缓存
CalculationService.cs
程序入口
总结

在现代应用程序中,缓存是一种有效的优化手段,能够显著提高系统的性能,减少延迟。缓存可以用于数据库查询结果的存储、API 响应的缓存、复杂计算结果的保存等多个场景。本文将介绍如何开发一个通用的 CacheService 类,并展示其在不同场景中的应用。

目录

  1. 引言
  2. 开发通用的 CacheService
  3. 缓存应用场景示例
  4. 总结

引言

缓存是一种存储机制,用于临时性地保存数据,以减少数据获取的时间和频次。在高性能应用程序中,合理使用缓存,可以显著提高系统的响应速度,减轻后台服务的负担。接下来我们讲解如何开发一个通用的 CacheService 并展示其在具体场景中的应用。

开发通用的 CacheService

ICacheService 接口

首先,定义一个 ICacheService 接口,定义基本的缓存操作:

C#
using System; using System.Threading.Tasks; public interface ICacheService { void Set<T>(string key, T value, TimeSpan expiration); T Get<T>(string key); Task SetAsync<T>(string key, T value, TimeSpan expiration); Task<T> GetAsync<T>(string key); void Remove(string key); Task RemoveAsync(string key); }

CacheService 实现

接下来,开发 CacheService 类,它实现了 ICacheService 接口。该类同时支持内存缓存和分布式缓存(例如 Redis),基于启动时的配置选择缓存方式:

C#
using System; using System.Threading.Tasks; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; public class CacheService : ICacheService { private readonly IMemoryCache _memoryCache; private readonly IDistributedCache _distributedCache; private readonly ILogger<CacheService> _logger; private readonly bool _useDistributedCache; public CacheService(IMemoryCache memoryCache, IDistributedCache distributedCache, ILogger<CacheService> logger, bool useDistributedCache = false) { _memoryCache = memoryCache; _distributedCache = distributedCache; _logger = logger; _useDistributedCache = useDistributedCache; } public void Set<T>(string key, T value, TimeSpan expiration) { if (_useDistributedCache) { var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = expiration }; var serializedValue = System.Text.Json.JsonSerializer.Serialize(value); _distributedCache.SetString(key, serializedValue, options); } else { var cacheEntryOptions = new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = expiration }; _memoryCache.Set(key, value, cacheEntryOptions); } } public T Get<T>(string key) { if (_useDistributedCache) { var serializedValue = _distributedCache.GetString(key); if (serializedValue != null) { return System.Text.Json.JsonSerializer.Deserialize<T>(serializedValue); } return default; } _memoryCache.TryGetValue(key, out T value); return value; } public async Task SetAsync<T>(string key, T value, TimeSpan expiration) { if (_useDistributedCache) { var options = new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = expiration }; var serializedValue = System.Text.Json.JsonSerializer.Serialize(value); await _distributedCache.SetStringAsync(key, serializedValue, options); } else { var cacheEntryOptions = new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = expiration }; _memoryCache.Set(key, value, cacheEntryOptions); } } public async Task<T> GetAsync<T>(string key) { if (_useDistributedCache) { var serializedValue = await _distributedCache.GetStringAsync(key); if (serializedValue != null) { return System.Text.Json.JsonSerializer.Deserialize<T>(serializedValue); } return default; } _memoryCache.TryGetValue(key, out T value); return await Task.FromResult(value); } public void Remove(string key) { if (_useDistributedCache) { _distributedCache.Remove(key); } else { _memoryCache.Remove(key); } } public async Task RemoveAsync(string key) { if (_useDistributedCache) { await _distributedCache.RemoveAsync(key); } else { _memoryCache.Remove(key); } } }

配置依赖注入

在项目的 Program.cs 中配置依赖注入:

C#
using System; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; public class Program { static void Main(string[] args) { var serviceProvider = new ServiceCollection() .AddMemoryCache() .AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }) .AddLogging() .AddSingleton<CacheService>() .BuildServiceProvider(); // 使用缓存服务的示例 var cacheService = serviceProvider.GetService<CacheService>(); cacheService.Set("key1", "value1",new TimeSpan(0, 10, 0)); var value = cacheService.Get<string>("key1"); } }

我们还可以启用分布试的缓冲(Redis)

C#
static void Main(string[] args) { var serviceProvider = new ServiceCollection() .AddMemoryCache() .AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }) .AddLogging() .AddSingleton<CacheService>(sp => { var memoryCache = sp.GetRequiredService<IMemoryCache>(); var distributedCache = sp.GetRequiredService<IDistributedCache>(); var logger = sp.GetRequiredService<ILogger<CacheService>>(); return new CacheService(memoryCache, distributedCache, logger, useDistributedCache: true); }) .BuildServiceProvider(); // 使用缓存服务的示例 var cacheService = serviceProvider.GetService<CacheService>(); cacheService.Set("key1", "value1",new TimeSpan(0, 10, 0)); var value = cacheService.Get<string>("key1"); }

image.png

缓存应用场景示例

数据库查询结果缓存

DatabaseService.cs

C#
using System; public class DatabaseService { private readonly ICacheService _cacheService; public DatabaseService(ICacheService cacheService) { _cacheService = cacheService; } public string GetDataFromDatabase(string query) { string cacheKey = $"DatabaseQuery-{query}"; var cacheData = _cacheService.Get<string>(cacheKey); if (cacheData != null) { return cacheData; } // 模拟数据库查询操作 string data = "返回数据"; _cacheService.Set(cacheKey, data, TimeSpan.FromMinutes(5)); return data; } }

程序入口

C#
internal class Program { static void Main(string[] args) { var serviceProvider = new ServiceCollection() .AddMemoryCache() .AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }) .AddLogging() .AddSingleton<CacheService>() .AddSingleton<ICacheService, CacheService>() .AddSingleton<DatabaseService>() .BuildServiceProvider(); var databaseService = serviceProvider.GetService<DatabaseService>(); string query = "SELECT * FROM Users"; Console.WriteLine("Query Result: " + databaseService.GetDataFromDatabase(query)); // 再次调用以展示缓存效果 Console.WriteLine("Query Result from Cache: " + databaseService.GetDataFromDatabase(query)); } }

image.png

API 响应缓存

ApiService.cs

C#
using System; using System.Net.Http; using System.Threading.Tasks; public class ApiService { private readonly ICacheService _cacheService; private readonly HttpClient _httpClient; public ApiService(ICacheService cacheService, HttpClient httpClient) { _cacheService = cacheService; _httpClient = httpClient; } public async Task<string> GetApiResponseAsync(string url) { string cacheKey = $"ApiUrl-{url}"; var cacheData = await _cacheService.GetAsync<string>(cacheKey); if (cacheData != null) { return cacheData; } var response = await _httpClient.GetStringAsync(url); await _cacheService.SetAsync(cacheKey, response, TimeSpan.FromMinutes(10)); return response; } }

程序入口

C#
using System.Net.Http; using System.Threading.Tasks; public class Program { public static async Task Main(string[] args) { var serviceProvider = new ServiceCollection() .AddMemoryCache() .AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }) .AddLogging() .AddSingleton<HttpClient>() .AddSingleton<CacheService>() .AddSingleton<ICacheService, CacheService>() .AddSingleton<ApiService>() .BuildServiceProvider(); var apiService = serviceProvider.GetService<ApiService>(); string apiUrl = "https://jsonplaceholder.typicode.com/posts"; var result = await apiService.GetApiResponseAsync(apiUrl); Console.WriteLine("API Response: " + result); // 再次调用以展示缓存效果 var cachedResult = await apiService.GetApiResponseAsync(apiUrl); Console.WriteLine("Cached API Response: " + cachedResult); } }

image.png

复杂计算结果缓存

CalculationService.cs

C#
using System; public class CalculationService { private readonly ICacheService _cacheService; public CalculationService(ICacheService cacheService) { _cacheService = cacheService; } public int HeavyComputation(int input) { string cacheKey = $"HeavyComputation-{input}"; var cacheData = _cacheService.Get<int>(cacheKey); if (cacheData != 0) { return cacheData; } // 模拟复杂计算 int result = input * input; _cacheService.Set(cacheKey, result, TimeSpan.FromMinutes(10)); return result; } }

程序入口

C#
public class Program { public static void Main(string[] args) { var serviceProvider = new ServiceCollection() .AddMemoryCache() .AddStackExchangeRedisCache(options => { options.Configuration = "localhost:6379"; }) .AddLogging() .AddSingleton<CacheService>() .AddSingleton<ICacheService, CacheService>() .AddSingleton<CalculationService>() .BuildServiceProvider(); var calculationService = serviceProvider.GetService<CalculationService>(); int input = 42; Console.WriteLine("Computation Result: " + calculationService.HeavyComputation(input)); // 再次调用以展示缓存效果 Console.WriteLine("Cached Computation Result: " + calculationService.HeavyComputation(input)); } }

总结

本文介绍了如何开发一个通用的 CacheService,并展示了其在不同场景中的应用:数据库查询结果缓存、API 响应缓存、复杂计算结果缓存。这种通用的缓存服务设计,可以显著提高应用的性能和响应速度,减少对外部资源(如数据库、外部 API)的频繁访问,从而优化用户体验。

通过上述示例,开发者可以更轻松地在项目中集成和管理缓存,提高应用的整体性能和可靠性。希望本文对你有所帮助,能够在实际项目中充分利用缓存技术。

本文作者:rick

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!