How to implement a cache attribute?
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.
精彩评论