开发者

How to implement a cache attribute?

开发者 https://www.devze.com 2023-03-05 15:50 出处:网络
How can I implement a CacheAttribute so I can have the same logic for all properties in one place? I am doing this to cache

How can I implement a CacheAttribute so I can have the same logic for all properties in one place?

I am doing this to cache

[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);
    }
}

And I want to use this instead

[TestClass]
public class All
{
    [Cache(Duration=500开发者_运维百科0)]
    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);
    }
}

Is there a way to make this syntax sugar?


It seems you want to "take over" the get method for the property so as to inspect a cache first before returning the "actual" value from your property. Since there is no way to perform property interception on an ad-hoc basis, you'll have to plan ahead for this facility.

One approach would be to use interfaces and write your classes to the interface. For example,

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

Now you can use proxies to create a wrapper around the original instance of All that also implements this interface. Furthermore, since you're fully in charge of the property now, you can check the cache whenever the getter is called. Since you'll have the PropertyInfo/MethodInfo at your disposal, you should have no trouble generating a unique key per property.

So, whenever you would instantiate an instance of All, you also instantiate this proxy, passing it the instance of All. All subsequent usages of that instance of All should instead be passed the proxy. Like any class factory implementation, this requires you to forgo use of the new operator.

Alternatively, you can use virtual methods instead of interfaces.

0

精彩评论

暂无评论...
验证码 换一张
取 消