【问题标题】:Writing a cache provider with Redis and Service Stack for Piranha - keeping track of cached object type使用 Redis 和服务堆栈为 Piranha 编写缓存提供程序 - 跟踪缓存对象类型
【发布时间】:2014-03-30 14:43:44
【问题描述】:

我正在编写一个缓存提供程序来缓存任何类型的对象。当我从缓存中读取值时,问题是转换为正确的类型。

using (var redisClient = redisClientsManager.GetClient())
{
    redisClient.Set(key, value, new TimeSpan(1, 0, 0));
}

因此很容易将对象放入缓存中,然后将其转换为字符串。当我把它从缓存中拉出来时,它会变得很有趣

 using (var redisClient = redisClientsManager.GetClient())
 {
     return redisClient.Get<object>(key);
 }

这不起作用,因为我们没有正确的类型来转换,所以默认是返回 json 字符串。

我在想我应该为我所有的食人鱼对象创建一个哈希,然后有这样的东西

 piranha:cache id = "{ some json }"
 piranha:cache id:type = PAGETYPE

这将允许我在将对象保存到缓存时设置对象类型。我想知道是否有更好的方法来获取/设置正在缓存的对象类型?

理想情况下,代码会显式进行强制转换,但目前 redis 中的缓存只使用对象类型(我认为)。


public object this[string key]
{
    get
    {
        using (var redisClient = redisClientsManager.GetClient())
        {
            if (redisClient.HashContainsEntry(PiranhaHash, key))
            {
                string resultJson = redisClient.GetValueFromHash(PiranhaHash, key);
                string objType = redisClient.GetValueFromHash(PiranhaHash, String.Format("{0}:Type", key));

                Type t = JsonConvert.DeserializeObject<Type>(objType);
                object result = JsonConvert.DeserializeObject(resultJson, t);

                return result;
            }
        }
        return null;
    }
    set
    {
        using (var redisClient = redisClientsManager.GetClient())
        {
            redisClient.SetEntryInHash(PiranhaHash, key, JsonConvert.SerializeObject(value));
            redisClient.SetEntryInHash(PiranhaHash, String.Format("{0}:Type", key), JsonConvert.SerializeObject(value.GetType()));
        }
    }
}

在大多数情况下,此实现应该可以工作,但是 Page 对象不会正确地从 Json 反序列化,并且控制器将始终为空。我认为必须进行一些后端更改才能使这成为可能。

【问题讨论】:

    标签: caching redis servicestack.redis piranha-cms


    【解决方案1】:

    由于目前不同的缓存提供者的数量非常有限,我们总是可以更改提供者接口,以便从长远来看会更好地工作。我也有一些关于使 Get 操作通用以清理访问缓存的代码的想法。

    也许这个界面从长远来看会更好用:

    /// <summary>
    /// Gets the cached model for the given key.
    /// </summary>
    /// <typeparam name="T">The model type</typeparam>
    /// <param name="key">The unique key</param>
    /// <returns>The model</returns>
    T Get<T>(string key);
    
    /// <summary>
    /// Sets the cached model for the given key.
    /// </summary>
    /// <param name="key">The unique key</param>
    /// <param name="obj">The model</param>
    void Set(string key, object obj);
    
    /// <summary>
    /// Removes the cached model for the given key.
    /// </summary>
    /// <param name="key">The unique key</param>
    void Remove(string key);
    

    由于此类更改将导致核心存储库中大量更新,因此我必须在单独的分支中实现它以进行测试,您可以使用它来实现您的提供程序。


    编辑

    我仔细查看了 Page 对象,字段 Controller, View, Redirect, IsPublished &amp; IsStartpage 是没有设置访问器的计算属性。此字段不应序列化为 JSON。正在使用哪个序列化程序以及可以使用哪些属性使序列化程序忽略属性(如 ScriptIgnore)。

    此外,TemplateController, TemplateView, TemplateRedirect &amp; TemplateName 的属性有私有集合访问器,我不知道这是否会成为使用 JSON 序列化程序的问题。

    问候

    哈坎

    【讨论】:

    • 嗨,Hakan,我认为这将是最好的解决方案,但我仍然不确定它是否能解决 Page 对象无法正确序列化/反序列化为 json 的问题。
    • 嗨,我尝试了服务堆栈序列化程序和 newtonsoft。我明天会尝试为您创建一个拉取请求
    猜你喜欢
    • 1970-01-01
    • 2012-03-24
    • 2017-09-28
    • 1970-01-01
    • 2016-03-29
    • 2019-08-03
    • 2018-09-05
    • 2013-09-02
    • 1970-01-01
    相关资源
    最近更新 更多