如何实现缓存属性
本文关键字:缓存 属性 实现 何实现 | 更新日期: 2023-09-27 17:56:19
如何实现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);
}
}
有没有办法使这种语法糖?
您似乎想"接管"属性的get
方法,以便在从属性返回"实际"值之前先检查缓存。 由于无法临时执行财产拦截,因此您必须提前计划此设施。
一种方法是使用接口并将类写入接口。 例如
public interface IAll
{
string N { get; set; }
}
现在,您可以使用代理围绕也实现此接口的原始All
实例创建包装器。 此外,由于您现在完全负责该属性,因此您可以在调用getter
时检查缓存。 由于您可以使用PropertyInfo
/MethodInfo
,因此您可以轻松为每个属性生成唯一键。
因此,每当您实例化 All
的实例时,您也会实例化此代理,并向其传递 All
的实例。 该 All
实例的所有后续用法都应传递代理。 与任何类工厂实现一样,这要求您放弃使用 new 运算符。
或者,您可以使用虚拟方法而不是接口。