【问题标题】:Using Generics to avoid casting when caching different types缓存不同类型时使用泛型避免强制转换
【发布时间】:2016-11-07 15:18:58
【问题描述】:

我正在使用 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&lt;Dictionary&lt;string, string&gt;&gt;(key, _paramService.GetSystemParameters);

传递一个使用Redis的Fetch方法的函数,如果缓存为空,则调用服务,然后将数据存入缓存并返回。

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

正如您在下面看到的编译错误,由于无法将类型对象转换为 Dictionay,这需要解决显式转换。

有没有更好、更优雅的方式来实现整个想法?

【问题讨论】:

    标签: c# generics caching casting stackexchange.redis


    【解决方案1】:

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

    您可以使用类型安全的键使这变得更好:

    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,并防止您传递错误的类型。

    【讨论】:

    • public T GetItem&lt;T&gt;(CacheKey&lt;T&gt; key) { if (key.Name == SecuritySystemParams.Name) return _cacheStorage.GetItem&lt;T&gt;(key.Name, _paramService.GetSystemParameters()); return _cacheStorage.GetItem&lt;T&gt;(key.Name); }。我想我误解了这一点,但我们仍然遗漏了一些东西,因为它无法将_paramService.GetSystemParameters() 的返回对象转换为T。那么,实现将如何在内部发生变化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多