在缓存不同类型时使用泛型避免投射

问题描述:

我正在使用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); 
    } 

然后我注入ICacheStorage在CacheManager中(实现的ICacheManager)。我试图分离依赖关系并简化CacheStorage,所以当我需要更改缓存类型时,我只实现了ICacheStorage。在CacheManager中,我们注入了所有在特殊键传递时获取一些数据的服务。

的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的方法,如果缓存是空的,它会调用该服务,然后将数据存储在一个函数缓存并返回。

我的问题是我需要避免投射,因为我可能会返回不同的对象,我如何继续使用泛型,所以我传递了返回的对象的类型。

正如您在下面看到的一个编译错误,由于无法将类型对象转换为Dictionay,因此需要显式转换才能解析。

是否有更好的,优雅的方式来实现整个想法?

enter image description here

阅读错误信息。
您需要明确指定类型参数。

你可以让这更好的与类型安全密钥:

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从钥匙,并会阻止您传递错误的类型。

+0

'公共Ť的GetItem (CacheKey 键) { 如果(key.Name == SecuritySystemParams.Name) 返回_cacheStorage.GetItem (key.Name,_paramService.GetSystemParameters()); return _cacheStorage.GetItem (key.Name); }'。我想我误解了这一点,但我们仍然错过了一些东西,因为它不能将'_paramService.GetSystemParameters()'的返回对象转换为'T'。那么,实现如何在内部发生变化。 – Coding

+0

@ h.salman:使用'(T)(object)...' – SLaks