【问题标题】:How to implement a cache attribute?如何实现缓存属性?
【发布时间】:2011-05-14 02:32:07
【问题描述】:

如何实现CacheAttribute,以便在一个地方为所有属性设置相同的逻辑?

我这样做是为了缓存

[TestClass]
public class All
{
    public string N
    {
        get
        {
            var value =
                MemoryCache.Default.Get("Website.Tests.All.N") as string;

            if (value != null)
            {
                return value;
            }

            value = DateTime.Now.ToString("HH:mm:ss.ffff");

            MemoryCache.Default.Add("Website.Tests.All.N", value,
                new CacheItemPolicy
                {
                    AbsoluteExpiration =
                        new DateTimeOffset(DateTime.Now.AddSeconds(5))
                });

            return value;
        }
    }

    [TestMethod]
    public void Extension()
    {
        var start = N;

        Thread.Sleep(1000);

        var end = N;

        Assert.AreEqual(start, end);
    }
}

我想改用这个

[TestClass]
public class All
{
    [Cache(Duration=5000)]
    public string N
    {
        get
        {
            return DateTime.Now.ToString("HH:mm:ss.ffff");
        }
    }

    [TestMethod]
    public void Extension()
    {
        var start = N;

        Thread.Sleep(1000);

        var end = N;

        Assert.AreEqual(start, end);
    }
}

有没有办法让这种语法糖化?

【问题讨论】:

标签: c# caching attributes properties


【解决方案1】:

您似乎想“接管”该属性的get 方法,以便在从您的属性返回“实际”值之前先检查缓存。由于无法临时执行财产拦截,因此您必须提前计划此设施。

一种方法是使用接口并将您的类写入接口。例如,

public interface IAll 
{
    string N { get; set; }
}

现在您可以使用proxies 围绕同样实现此接口的All 的原始实例创建一个包装器。此外,由于您现在完全负责该属性,因此您可以在调用 getter 时检查缓存。由于您可以随意使用PropertyInfo/MethodInfo,因此您应该可以轻松地为每个属性生成唯一密钥。

因此,每当您实例化All 的实例时,您也会实例化此代理,并将All 的实例传递给它。 All 实例的所有后续用法都应通过代理传递。与任何类工厂实现一样,这要求您放弃使用 new 运算符。

或者,您可以使用虚拟方法代替接口。

【讨论】:

    猜你喜欢
    • 2016-09-13
    • 2011-07-15
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2012-12-06
    相关资源
    最近更新 更多