在缓存不同类型时使用泛型避免强制转换
Using Generics to avoid casting when caching different types
我正在使用 ASP.NET Core 和 Redis 缓存。我试图在缓存中存储不同类型的不同对象,并且我想避免显式转换。
这是我的 Redis 缓存包装器
public class RedisCacheStorage : Contracts.ICacheStorage
{
private CachingFramework.Redis.Context _context = null;
public RedisCacheStorage(string configuration)
{
_context = new CachingFramework.Redis.Context(configuration, new CachingFramework.Redis.Serializers.JsonSerializer());
}
public void SetItem<T>(string key, T value)
{
_context.Cache.SetObject<T>(key, value);
}
public T GetItem<T>(string key)
{
return _context.Cache.GetObject<T>(key);
}
public T GetItem<T>(string key, Func<T> loadCacheFunc)
{
return _context.Cache.FetchObject<T>(key, loadCacheFunc);
}
然后我在 CacheManager(它实现了 ICacheManager)中注入 ICacheStorage。我试图隔离依赖关系并保持 CacheStorage 简单,因此当我需要更改缓存类型时,我只需要实现 ICacheStorage。在 CacheManager 中,我们正在注入所有在传递特殊键时获取一些数据的服务。
缓存管理器:
public class CacheManager : Contracts.ICacheManager
{
private Contracts.ICacheStorage _cacheStorage;
private SecurityCore.ServiceContracts.IParametersService _paramService;
public CacheManager(Contracts.ICacheStorage cacheStorage, SecurityCore.ServiceContracts.IParametersService paramService)
{
_cacheStorage = cacheStorage;
_paramService = paramService;
}
public Object GetItem(string key)
{
if (key == Constants.CacheKeys.SecuritySystemParams)
return _cacheStorage.GetItem<Dictionary<string, string>>(key, _paramService.GetSystemParameters);
//if (key == Constants.CacheKeys.EffectivePermissions)
// return List of Effective Permissions
return _cacheStorage.GetItem<Object>(key);
}
_cacheStorage.GetItem<Dictionary<string, string>>(key, _paramService.GetSystemParameters);
传递一个使用Redis的Fetch方法的函数,如果缓存为空,它调用服务,然后将数据存储在缓存中并return返回。
我的问题是我需要避免转换,因为我可能会 returning 不同的对象,我如何才能继续使用泛型,所以我传递了对象的类型 returned。
正如您在下面看到的编译错误,由于无法将类型对象转换为 Dictionay,这需要解决显式转换问题。
是否有更好、更优雅的方式来实现整个想法?
阅读错误信息。
您需要明确指定类型参数。
您可以使用类型安全的键来改善这一点:
class CacheKey<T> {
public string Name { get; }
public string ToString() => Name;
public CacheKey(string name) { Name = name; }
}
public T GetItem<T>(CacheKey<T> key) { ... }
public CacheKey<Dictionary<string, string>> SecuritySystemParams { get; } = new CacheKey<Dictionary<string, string>>("SecuritySystemParams");
这将使 GetItem()
从密钥中推断出 T
,并防止您传递错误的类型。
我正在使用 ASP.NET Core 和 Redis 缓存。我试图在缓存中存储不同类型的不同对象,并且我想避免显式转换。
这是我的 Redis 缓存包装器
public class RedisCacheStorage : Contracts.ICacheStorage
{
private CachingFramework.Redis.Context _context = null;
public RedisCacheStorage(string configuration)
{
_context = new CachingFramework.Redis.Context(configuration, new CachingFramework.Redis.Serializers.JsonSerializer());
}
public void SetItem<T>(string key, T value)
{
_context.Cache.SetObject<T>(key, value);
}
public T GetItem<T>(string key)
{
return _context.Cache.GetObject<T>(key);
}
public T GetItem<T>(string key, Func<T> loadCacheFunc)
{
return _context.Cache.FetchObject<T>(key, loadCacheFunc);
}
然后我在 CacheManager(它实现了 ICacheManager)中注入 ICacheStorage。我试图隔离依赖关系并保持 CacheStorage 简单,因此当我需要更改缓存类型时,我只需要实现 ICacheStorage。在 CacheManager 中,我们正在注入所有在传递特殊键时获取一些数据的服务。
缓存管理器:
public class CacheManager : Contracts.ICacheManager
{
private Contracts.ICacheStorage _cacheStorage;
private SecurityCore.ServiceContracts.IParametersService _paramService;
public CacheManager(Contracts.ICacheStorage cacheStorage, SecurityCore.ServiceContracts.IParametersService paramService)
{
_cacheStorage = cacheStorage;
_paramService = paramService;
}
public Object GetItem(string key)
{
if (key == Constants.CacheKeys.SecuritySystemParams)
return _cacheStorage.GetItem<Dictionary<string, string>>(key, _paramService.GetSystemParameters);
//if (key == Constants.CacheKeys.EffectivePermissions)
// return List of Effective Permissions
return _cacheStorage.GetItem<Object>(key);
}
_cacheStorage.GetItem<Dictionary<string, string>>(key, _paramService.GetSystemParameters);
传递一个使用Redis的Fetch方法的函数,如果缓存为空,它调用服务,然后将数据存储在缓存中并return返回。
我的问题是我需要避免转换,因为我可能会 returning 不同的对象,我如何才能继续使用泛型,所以我传递了对象的类型 returned。
正如您在下面看到的编译错误,由于无法将类型对象转换为 Dictionay,这需要解决显式转换问题。
是否有更好、更优雅的方式来实现整个想法?
阅读错误信息。
您需要明确指定类型参数。
您可以使用类型安全的键来改善这一点:
class CacheKey<T> {
public string Name { get; }
public string ToString() => Name;
public CacheKey(string name) { Name = name; }
}
public T GetItem<T>(CacheKey<T> key) { ... }
public CacheKey<Dictionary<string, string>> SecuritySystemParams { get; } = new CacheKey<Dictionary<string, string>>("SecuritySystemParams");
这将使 GetItem()
从密钥中推断出 T
,并防止您传递错误的类型。