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

发布于 2024-11-14 13:11:25 字数 2316 浏览 3 评论 0原文

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

问题:

  • 我应该缓存(在静态字段中)在 AsTrackable() 中使用的 ProxyGenerator() 实例吗?我要在 ASP.NET Web 应用程序中使用,但我不确定该类是否是线程安全的?创建成本高吗?
  • 如果我保留代码不变,生成的代理类型是否会被不同的 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; }
}

}

I am starting out with Castle DynamicProxy and I have this sample to track changes to properties of an object.

Questions:

  • Should I cache (in a static field) the ProxyGenerator() instance I use in AsTrackable()? I going to use in an ASP.NET web-app, and I was not sure if the class is thread-safe? Is it expensive to create?
  • If I leave the code as is, will the generated proxy types be re-used by the different ProxyGenerator instances. I read the caching tutorial, but not sure what "module scope" means.
  • Is there any other advice from a performance standpoint to improve the code?

Code:

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; }
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╭ゆ眷念 2024-11-21 13:11:25

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

It is thread-safe to cache a static copy of your proxy generator and you absolutely should do this. That is considered best-practice with this API and not doing so will result in extra types defined in new dynamic assemblies for no reason.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文