우리는 우리의 클라이언트 측 캐싱 PostSharp의 형태로 AOP 사용, 우리는 단순히 캐시 방법 및 비올라에 속성을 추가 - 실제 캐시 구현을 ICacheService
의 인스턴스로 연기하지만 아이디어를 얻습니다.
[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, PersistMetaData = true)]
public class MethodCacheAttribute : MethodInterceptionAspect
{
public const int DefaultCacheSeconds = 600;
private ICacheService CacheService { get; set; }
private string methodName;
[IntroduceMember(Visibility = PostSharp.Reflection.Visibility.Family, OverrideAction = MemberOverrideAction.Ignore, IsVirtual = true)]
public double CacheForSeconds { get; set; }
public MethodCacheAttribute() : this(DefaultCacheSeconds) { }
public MethodCacheAttribute(int seconds)
{
this.CacheForSeconds = seconds;
}
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
this.methodName = method.Name;
}
public sealed override void OnInvoke(MethodInterceptionArgs args)
{
var key = this.BuildCacheKey(args.Arguments,args.Method);
var item = ServiceLocator.Current.GetInstance<ICacheService>().Cache<object>(key,() =>
{
return args.Invoke(args.Arguments);
},CacheForSeconds ==0 ? TimeSpan.MaxValue : TimeSpan.FromSeconds(CacheForSeconds));
args.ReturnValue = item;
}
private string BuildCacheKey(Arguments arguments, MethodBase method)
{
var sb = new StringBuilder();
sb.Append(this.methodName);
foreach (var argument in arguments.ToArray())
{
sb.Append(argument == null ? "_" : argument.GetHashCode().ToString());
}
if (method.IsGenericMethod)
{
var genericArgs = String.Join("-", method.GetGenericArguments().Select(t => t.Name));
sb.Append(genericArgs);
}
return sb.ToString();
}
}
감사합니다. 이것은 내가 현재 사용하고있는 전략이다. 나는 다른 대안이 있는지보기 위해보고있었습니다. – DoronBM