如何实现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);
}
}
有没有办法让这种语法变糖?
答案 0 :(得分:0)
您似乎希望“接管”该属性的get
方法,以便在从您的属性返回“实际”值之前先检查缓存。由于无法在临时基础上执行属性拦截,因此您必须提前计划此工具。
一种方法是使用接口并将类编写到接口。例如,
public interface IAll
{
string N { get; set; }
}
现在,您可以使用proxies围绕同样实现此接口的All
原始实例创建包装器。此外,由于您现在完全负责该属性,因此只要调用getter
,您就可以检查缓存。由于您可以使用PropertyInfo
/ MethodInfo
,因此您可以毫不费力地为每个属性生成唯一键。
因此,每当您实例化All
的实例时,您还要实例化此代理,并将All
的实例传递给它。该All
实例的所有后续用法应该通过代理传递。与任何类工厂实施一样,这要求您放弃使用 new 运算符。
或者,您可以使用虚拟方法而不是接口。