Castle DynamicProxy:代理接口时如何代理等于?

2023-11-26

我需要使用 Castle DynamicProxy 通过向 ProxyGenerator.CreateInterfaceProxyWithTarget 提供接口实例来代理接口。我还需要确保对 Equals、GetHashCode 和 ToString 的调用会命中我正在传递的具体实例上的方法,但我无法使其正常工作。

换句话说,我想要打印这个小样本True两次,而实际上它打印了True,False:

using System;
using Castle.Core.Interceptor;
using Castle.DynamicProxy;

public interface IDummy
{
    string Name { get; set; }
}

class Dummy : IDummy
{
    public string Name { get; set; }

    public bool Equals(IDummy other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Equals(other.Name, Name);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as IDummy);
    }      
}

class Program
{
    static void Main(string[] args)
    {
        var g = new ProxyGenerator();
        IDummy first = new Dummy() {Name = "Name"};
        IDummy second = new Dummy() {Name = "Name"};
        IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, new ConsoleLoggerInterceptor());
        IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, new ConsoleLoggerInterceptor());

        Console.WriteLine(first.Equals(second));         
        Console.WriteLine(firstProxy.Equals(secondProxy));
    }
}

internal class ConsoleLoggerInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Invoked " + invocation.Method.Name);
    }
}

这可以通过 DynamicProxy 实现吗?如何 ?


这有点棘手。看一下文档关于代理如何工作。接口代理包装对象并拦截对指定接口的调用。自从Equals不是该接口的一部分,第二次调用 equals 是比较代理,而不是它们的目标。

那么第二个的实现是什么呢?Equals call?

代理只是另一个实现你的类IDummy界面。与任何类一样,它也有一个基类,这是Equals被调用。该基类默认为System.Object

我希望你现在明白事情的发展方向了。此问题的解决方案是告诉代理实现一些代理感知基类,该基类会将调用转发到代理目标。其部分实现可能如下所示:

public class ProxyBase
{
    public override bool Equals(object obj)
    {
        var proxy = this as IProxyTargetAccessor;
        if (proxy == null)
        {
            return base.Equals(obj);
        }
        var target = proxy.DynProxyGetTarget();
        if (target == null)
        {
            return base.Equals(obj);
        }
        return target.Equals(obj);
    }
    // same for GetHashCode
}

现在您只需指示代理生成器为您的接口代理使用此基类,而不是默认的。

var o = new ProxyGenerationOptions();
o.BaseTypeForInterfaceProxy = typeof(ProxyBase);
IDummy firstProxy = g.CreateInterfaceProxyWithTarget(first, o);
IDummy secondProxy = g.CreateInterfaceProxyWithTarget(second, o);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Castle DynamicProxy:代理接口时如何代理等于? 的相关文章

随机推荐

  • 如何在 json 数据文件更改时刷新页面

    所以我有一个名为 data json 的本地文件 其中包含各种数据 我只想在 json 文件中的某些数据发生更改时刷新页面 如果您能用一些代码来解释我 我将感谢您的帮助 我在互联网上搜索 找不到合适的答案 创建一个计时器 每 X 毫秒获取
  • 如何隐藏或删除 jQuery 选择下拉列表中的选项

    我想隐藏使用 选择 插件创建的下拉列表中的某些元素 我尝试删除它 option contains Swatch 1 remove trigger chosen updated 并隐藏它 chosen results li contains
  • 如何将字典列表转换为两个列表?

    例如 persons id 1 name john id 2 name mary id 3 name tom 我想从中得到两个列表 ids 1 2 3 names john mary tom 我做了什么 names d name for d
  • Scala Play 2,将请求传递给方法

    我有一个Play 2 0 app TestController scala def foo p1 String Action implicit request gt Ok bar p1 private def bar p1 String a
  • JVM 在 libzip.so 处崩溃

    我的 JVM 总是在 libzip so 处连续意外地崩溃 我已向 Oracle 提交了该错误 但决定看看这里是否有人遇到过该问题 如果有 您是如何处理的 这是一个正在运行的网络应用程序 Linux 2 6 34 gentoo r6 1 S
  • 无法在 Windows 10 上安装 Windows SDK 7.1

    我是一名软件开发人员 拥有一台 Windows 10 电脑 我必须支持一些使用 Windows SDK 7 1 在 Visual Studio 2010 中编写的旧软件 在尝试搭建开发环境时 我已经成功安装了VS2010 并来安装Windo
  • GoogleTagManager 警告:未找到默认容器。容器需要添加到容器文件夹并添加到目标

    当尝试在我的 Swift 应用程序中实现 Google 跟踪代码管理器 v5 时 我遇到了以下警告 这给我带来了一些麻烦 GoogleTagManager 警告 未找到默认容器 需要将容器添加到容器文件夹并添加到目标 我花了比应有的时间更多
  • 无法将数据列从一个数据表复制到另一个数据表

    如何将 1 个数据表中的 1 个数据列复制到新的数据表中 当我尝试这样做时 我收到错误列 XXX 已经属于另一个数据表 dataColumn datatable1 Columns 1 datatable2 new DataTable dat
  • 如何以编程方式编辑路由表

    我正在编写一个在嵌入式平台上运行的守护程序 需要根据给定时间连接的接口来更改设备的默认路由 我怎样才能以编程方式做到这一点 我知道我可以使用 system route del default Route add default gatewa
  • 由于加密消息,无法将存储过程添加到数据库

    我设置了一个本地数据库 SQL Server 2017 Express 一切工作正常 但在 SSMS 中创建一个简单的存储过程时 我会遇到错误 例如 这个 CREATE PROCEDURE dbo EMS Operations SyncAs
  • 将 EF Core 列/字段指定为只读

    我有一个 SQL Server 表 其中包含数据库通过默认值设置的某些字段 一旦保存 应该never再次修改 例如DateCreated 在 Entity Framework Core 2 1 模型构建器或类中 我们如何将字段 标记 为本质
  • Plotly 中的行悬停文本

    我正在用 Plotly 绘制一个类似于Plotly 网站上的示例 除了图形节点上的悬停文本之外 我还希望边缘上有悬停文本 我尝试通过添加 名称 字段来修改边缘的跟踪对象来实现此目的 但这不起作用 而是将 名称 放在节点上 trace3 Sc
  • 鼠标移动旋转div

    我有以下代码来旋转 div 通过同一 div 右上角图像上的 mousedown 事件 我希望 div 旋转直到鼠标向上 从逻辑上讲 我相信代码很好 但点击后它就可以工作 当我单击其他项目时 旋转会停止 而不是鼠标松开 我认为在鼠标按下后拖
  • 使用curl和php从url读取xml数据

    我想从 URL 读取 XML 数据 我的网址如下 这是我的代码 Url http www arrowcast net fids mco fids asp sort city city number airline adi A if func
  • jQuery 选择器和反斜杠

    我有一个 dom 元素 其中包含完全限定名称作为 id 属性的一部分 div My Div div 让 jQuery 通过 ID 选择元素似乎是不可能的 这是我的实验 var e1 domain element div var e2 dom
  • 在数据库 mysql 中存储和检索同义词的最佳方法

    我正在制作一个同义词列表 我将其存储在数据库中并在进行全文搜索之前检索它 当用户输入 word1 我需要在同义词表中查找这个词 因此 如果找到该单词 我将选择该单词的所有同义词 并在下一个查询的全文搜索中使用它 我将在其中构造查询 例如 M
  • ggplot:仅在满足某些条件时才绘制图层

    有没有过滤的方法within ggplot本身 也就是说 说我想这样做 p lt ggplot iris aes x Sepal Width y Sepal Length species geom point size 4 shape 4
  • 扩展 Scala 集合

    我想要一个在尝试覆盖现有键的值时抛出的映射 我试过 trait Unoverwriteable A B extends scala collection Map A B case class KeyAlreadyExistsExceptio
  • 如何在 yacc 中将 yylval 与字符串一起使用

    我想传递令牌的实际字符串 如果我有一个名为 ID 的令牌 那么我希望我的 yacc 文件真正知道 ID 的名称 我想我必须使用 yylval 将字符串从 Flex 文件传递 到 yacc 文件 我怎么做 通过 yylval 返回字符串或任何
  • Castle DynamicProxy:代理接口时如何代理等于?

    我需要使用 Castle DynamicProxy 通过向 ProxyGenerator CreateInterfaceProxyWithTarget 提供接口实例来代理接口 我还需要确保对 Equals GetHashCode 和 ToS