在.NET Web应用程序中使用Castle DynamicProxy的性能建议

Rag*_*dda 5 .net aop castle castle-dynamicproxy dynamic-proxy

我开始使用Castle DynamicProxy,我有这个示例来跟踪对象属性的更改.

问题:

  • 我应该缓存(在静态字段中)我在AsTrackable()中使用的ProxyGenerator()实例吗?我将在ASP.NET网络应用程序中使用,我不确定该类是否是线程安全的?创建起来很昂贵吗?
  • 如果我按原样保留代码,生成的代理类型是否会被不同的ProxyGenerator实例重用.我阅读了缓存教程,但不确定"模块范围"是什么意思.
  • 从性能角度来看,是否还有其他建议来改进代码?

码:

class Program
{
    static void Main(string[] args)
    {
        var p = new Person { Name = "Jay" }.AsTrackable();

        //here's changed properties list should be empty.
        var changedProperties = p.GetChangedProperties();

        p.Name = "May";

        //here's changed properties list should have one item.
        changedProperties = p.GetChangedProperties();
    }
}

public static class Ext
{
    public static T AsTrackable<T>(this T instance) where T : class
    {
        return new ProxyGenerator().CreateClassProxyWithTarget
        (
          instance, 
          new PropertyChangeTrackingInterceptor()
        );
    }

    public static HashSet<string> GetChangedProperties<T>(this T instance) 
    where T : class
    {
        var proxy = instance as IProxyTargetAccessor;

        if (proxy != null)
        {
            var interceptor = proxy.GetInterceptors()
                                   .Select(i => i as IChangedProperties)
                                   .First();

            if (interceptor != null)
            {
                return interceptor.Properties;
            }
        }

        return new HashSet<string>();
    }
}

interface IChangedProperties
{
    HashSet<string> Properties { get; }
}

public class PropertyChangeTrackingInterceptor : IInterceptor, IChangedProperties
{
    public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();

        this.Properties.Add(invocation.Method.Name);
    }

    private HashSet<string> properties = new HashSet<string>();

    public HashSet<string> Properties
    {
        get { return this.properties; }
        private set { this.properties = value; }
    }
}

public class Person
{
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

}

Kir*_*oll 9

缓存代理生成器的静态副本是线程安全的,你绝对应该这样做.这被认为是使用此API的最佳实践,如果不这样做,将无缘无故地导致新动态程序集中定义的额外类型.