丰富的客户端数据处理和缓存模式

时间:2012-12-02 08:37:38

标签: design-patterns caching mvvm prism

我正在使用WPF-PRISM-MVVM开发一个富客户端应用程序 客户端与存储库服务交互,该服务器提供CRUD功能并通过WCF通道发布域实体的任何更改 客户端处理域实体缓存以提高性能并提供脱机功能 为此,我编写了一个存储库代理服务,它位于客户端并包装存储库服务并处理缓存并将传播更改为对域实体更改感兴趣的相关客户端组件。

经过长时间的介绍,我的问题是这样做的方法吗? 我应该注意哪些客户端数据处理和缓存模式?

干杯,
多伦

2 个答案:

答案 0 :(得分:0)

我们以AOP的形式使用PostSharp进行客户端缓存,我们只需在方法中添加一个属性,然后缓存它:

我们的方面看起来像这样 - 它将实际的缓存实现推迟到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();
    }
}

答案 1 :(得分:0)

Decorator Pattern的一个相当经典的应用是添加缓存功能。您基本上将实际组件实现与另一个实例组合,以缓存某些类型的请求,从而提高性能。这是IMO一种简单而优雅的方法。

  Component myComponent = new ScientificCalculator();
  Component myDecorator = new ComponentDecorator(myComponent);
  // expensive
  double result = myComponent.doExpensiveComputation();

  // use the Decorator and cache the first time
  result = myDecorator.doExpensiveComputation();
  // and now is cheap
  result = myDecorator.doExpensiveComputation();