无论如何在C#中缓存函数/方法
我厌倦了一次又一次地写代码来缓存数据访问层中的对象。
无论如何都要缓存c#函数结果而不需要对函数进行太多更改。
目前是否有任何框架支持此function?
我可以通过编写自定义“c#函数属性”来存档吗? 如果是这样,请给我一些积分来开始实施?
您可以使用PostSharp创建缓存属性。 这是一个例子。
可能性1:使用IL编织
之前提到过Postsharp。
您也可以尝试MethodCache.Fody包。
可能性2:使用代理/拦截框架
示例(Ninject和Ninject.Interception):
public class CacheAttribute : InterceptAttribute { public override IInterceptor CreateInterceptor(IProxyRequest request) { return request.Context.Kernel.Get(); } } public class CachingInterceptor : IInterceptor { private ICache Cache { get; set; } public CachingInterceptor(ICache cache) { Cache = cache; } public void Intercept(IInvocation invocation) { string className = invocation.Request.Target.GetType().FullName; string methodName = invocation.Request.Method.Name; object[] arguments = invocation.Request.Arguments; StringBuilder builder = new StringBuilder(100); builder.Append(className); builder.Append("."); builder.Append(methodName); arguments.ToList().ForEach(x => { builder.Append("_"); builder.Append(x); }); string cacheKey = builder.ToString(); object retrieve = Cache.Retrieve
然后你可以装饰这样的函数:
[Cache] public virtual Customer GetCustomerByID(int customerID) { return CustomerRepository.GetCustomerByID(customerID); }
截获的函数必须是虚拟的,并且必须由Ninject内核创建类。 如果依赖性能,可以直接通过Castle.DynamicProxy(Ninject.Extensions.Interception.DynamicProxy内部使用)代理类。
可能性3:使用表达式包装器
您可以将函数作为表达式传递,生成包含类,方法和参数信息的缓存键,并在缓存中找不到表达式(如果未找到)。 这比AOP / Proxy框架增加了更多的运行时开销,但对于简单的解决方案来说已足够。
private T CacheAction(Expression> action, [CallerMemberName] string memberName = "") where T : class { MethodCallExpression body = (MethodCallExpression)action.Body; ICollection
如果我认为你的问题是正确的,你想要的正确术语就是记忆 。 维基百科提供了有关该主题的更多细节。 不幸的是,没有提到支持它的C#库。
缓存应用程序块是Microsoft对.NET中缓存的内置库的回答。
Lazy在首次运行后存储它的值。 示例: http : //msdn.microsoft.com/en-us/vstudio/bb870976
我建议使用Spring.Net AOP。 它基本上创建了一个代理,并且可以从/向缓存重定向调用。 http://www.springframework.net/doc/reference/html/aop-quickstart.html
然后你可以得到类似的建议:
public class CachingAroundAdvice : IMethodInterceptor { #region Variable Declarations private Priority priority = Priority.Normal; #endregion public object Invoke(IMethodInvocation invocation) { // declare local variables string cacheKey = string.Empty; object dataObject = null; // build cache key with some algorithm cacheKey = CreateCacheKey(invocation.Method, invocation.Arguments); // retrieve item from cache dataObject = CacheManager.Cache.GetData(cacheKey); // if the dataobject is not in cache proceed to retrieve it if (null == dataObject) { dataObject = invocation.Proceed(); // add item to cache CacheManager.Cache.Add(cacheKey, dataObject, CachePriority, null, Expiration); } // return data object return dataObject; }