我有一个 ASP.NET 核心应用程序,我正在尝试使用 Redis 缓存 - 但是我收到一条错误消息,指出无法访问已处置的对象,所以我一定没有正确设置我的缓存类。我已将缓存服务类提取到我自己的 Nuget 存储库中,以便其他应用程序可以使用它,在其他应用程序中传递与 appsettings.json 不同的 Db 编号
我正在使用内置的 .NET Core DI 来注册缓存服务,如下所示:
services.AddTransient<ICacheService, CacheService>();
然后在我的应用程序中使用缓存服务:
var dataFromCache = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);
我的缓存服务在 nuget pacakge 中的实现如下:
public class CacheService : ICacheService, IDisposable
{
public virtual T TryGetCachedObject<T>(string cacheKey)
{
if (RedisCacheHandler.Cache.KeyExists(cacheKey))
{
return JsonConvert.DeserializeObject<T>(RedisCacheHandler.Cache.StringGet(cacheKey));
}
return default(T);
}
//other metjhods omitted for brevity
我在行 if (RedisCacheHandler.Cache.KeyExists(cacheKey))
我的 redis 缓存处理程序类在下面(如果我一直在尝试但没有成功,则注释掉的行。
public static class RedisCacheHandler
{
private static Lazy<ConnectionMultiplexer> _lazyConnection;
private static ConnectionMultiplexer Connection => _lazyConnection.Value;
//private static CacheSettings _cacheSettings;
public static IDatabase Cache { get; set; }
//public static IDatabase Cache => Connection.GetDatabase(Convert.ToInt32(_cacheSettings.DbNumber));
//private static readonly Lazy<ConnectionMultiplexer> LazyConnection
// = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(_cacheSettings.Connection));
//public static ConnectionMultiplexer Connection => LazyConnection.Value;
public static void AddRedisCacheHandler(this IServiceCollection services, IConfiguration configuration)
{
var cacheSettings = new CacheSettings();
configuration.Bind("CacheSettings", cacheSettings);
//_cacheSettings = cacheSettings;
_lazyConnection = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(cacheSettings.Connection));
Cache = Connection.GetDatabase(Convert.ToInt32(cacheSettings.DbNumber));
}
}
我在 ConfigureServices
方法中调用 asp.net core 启动类中的 AddRedisCacheHandler 方法,如下所示:
services.AddRedisCacheHandler(Configuration);
编辑
这个的用法是我点击一个 API Controller 去获取引用数据。 API Controller 调用服务层,然后检查数据是否在缓存中并从那里检索,否则将从数据库中获取数据并将其设置在缓存中 24 小时
private readonly IMyService _myService
public MyController(IMyService myService)
{
_myService = myService;
}
[Route("SomeReferenceData")]
public IEnumerable<SomeDto> GetReferenceData()
{
var data = _myService.GetRefData();
//do stuff and return
}
在服务层然后代码是:
public class MyService : IMyService
{
private readonly ICacheService _cacheService;
private readonly CacheSettings _cacheSettings;
public MyService(CacheSettings cacheSettings, ICacheService cacheService)
{
_cacheSettings = cacheSettings;
_cacheService = cacheService;
}
public virtual IEnumerable<MyObject> GetRefData()
{
string cacheKey = CachingConstants.CacheKey;
var data = _cacheService.TryGetCachedObject<List<MyObject>>(cacheKey);
if (data != null)
{
return data;
}
//go get data from db
_cacheService.SetCachedObject<IEnumerable<MyObject>>(cacheKey, countries, Convert.ToInt32(_cacheSettings.DurationLongMinutes));
return data;
}
从启动开始,我调用下面的代码来注册所有依赖项,包括缓存服务:
services.RegisterServiceDependencies();
public static class ServiceConfig
{
public static void RegisterServiceDependencies(this IServiceCollection services)
{
services.AddTransient<ICacheService, CacheService>();
//lots of other services
最佳答案
你在这里自杀。从字面上看,这些都不是必需的。 ASP.NET Core 内置了对分布式缓存的支持,包括使用 Redis 作为提供者。在您的 Startup.cs
中:
services.AddDistributedRedisCache(options =>
{
options.Configuration = "localhost";
options.InstanceName = "SampleInstance";
});
然后,当您需要使用缓存时,只需注入(inject)IDistributedCache
。如果你想要一种自包含的方式来自动序列化/反序列化缓存中的值,你可以简单地添加一些扩展方法:
public static class IDistributedCacheExtensions
{
public static async Task<T> GetAsync<T>(this IDistributedCache cache, string key) =>
JsonConvert.DeserializeObject<T>(await cache.GetStringAsync(key));
public static Task Set<T>(this IDistributedCache cache, string key, T value) =>
cache.SetStringAsync(key, JsonConvert.SerializeObject(value));
}
如果您坚持要为此创建一个单独的 CacheService
类,那么只需将 IDistributedCache
注入(inject)其中,然后在那里完成您的工作即可。
关于c# - Redis 缓存无法访问已处置的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54350146/