如何拦截 .Net 中第三方库对非虚拟方法的调用?

2024-05-13

我认为我需要的是 .net 人们称之为“透明动态代理”的东西,但到目前为止我所看到的所有实现(Castle DynamicProxy、Spring.NET AOP 等)都要求我至少执行以下操作之一:

  1. 将拦截的方法声明为虚拟方法
  2. 包装类并创建包装器的实例而不是包装类
  3. 更改继承或实现接口

显然,如果调用者和被调用者都是非虚拟的并且来自第三方闭源库(这种情况),我无能为力。

如果 C# 是像 Python 这样的动态语言,我会这样做:

foo = ThirdyPartyLibA.Foo()
def interceptor(self, *args, **kwargs):
    do_something_before(self, *args, **kwargs)
    result = ThirdyPartyLibB.Bar.intercepted(self, *args, **kwargs)
    do_something_after(self, result, *args, **kwargs)
    return result
foo.bar.intercepted = interceptor # bar is an instance of ThirdyPartyLibB.Bar
foo.do_its_job() # Foo.do_its_job calls Bar.intercepted

我需要这个来改变 ThirdyPartyLibA.Foo 在与 ThirdyPartyLibB.Bar 交互时的不良行为。我确切地知道导致此行为的原因,以及如何更改 Foo 或 Bar 来修复此错误,这要归功于反汇编器。

一些(不太可能行得通的)想法:

  • 反汇编 ThirdyPartyLibA,更改代码并生成兼容的程序集(不太可能工作,因为它是强名称程序集)
  • 编辑二进制文件以使 Foo 的有缺陷的方法成为虚拟的,并更改它保持有效程序集所需的任何内容,以便我可以使用动态代理(不太可能工作,也因为与上面的想法相同的原因)
  • 找到一个适合的透明动态代理实现(我认为没有基于此论坛线程的实现:http://www.pcreview.co.uk/forums/overriding-non-virtual-methods-using-il-and-reflection-emit-t2605695.html http://www.pcreview.co.uk/forums/overriding-non-virtual-methods-using-il-and-reflection-emit-t2605695.html)
  • 联系创建该库的公司(他们不再支持该产品)
  • 停止使用该库或使用替代方案(不可能,因为它是我们所依赖的 RAD IDE 运行时的一部分,因为有大量使用 IDE 自己的语言编写的代码)
  • 控制对有问题的方法的调用以避免错误(我们已经这样做了,但并没有完全解决问题)

你还有其他想法吗?

PS:抱歉我的英语不好。另外,对不起我的Python。这段代码在这里只是为了说明我需要什么,不要把它当作一个食谱,因为它很糟糕。


可能的解决方案1:

包装库并使用 ReSharper 等工具查找库的所有用法并替换为包装类。您还可以利用这个机会清理第三方库可能很糟糕的界面。

可能的解决方案2:

While TypeMock http://www.typemock.com/通常用作测试工具,它允许您模拟一切。因为它会将自身注入为代码分析器,所以您可以模拟的内容包括类的私有成员和静态成员。作为奖励,任何重写的方法都不需要是虚拟的,因此您可以通过这种方式拦截调用。

我的推荐

我建议您使用解决方案 1。包装器非常容易理解,并且它将为您提供真正改进代码的好机会。我什至建议您将第三方库包装为一般规则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何拦截 .Net 中第三方库对非虚拟方法的调用? 的相关文章

  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • .NET 中是否有内置函数可以对密码进行哈希处理?

    我看到这个问题加密 散列数据库中的纯文本密码 https stackoverflow com questions 287517 encrypting hashing plain text passwords in database 我知道我
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐

  • 谷歌表格根据今天的日期隐藏行

    在 Google Sheets 中 当 A 列中的日期等于或早于今天的日期时 我需要一个脚本来自动隐藏工作表 1 中的行 因此 如果今天是 2018 年 8 月 29 日 单元格 A3 中的日期是 2018 年 8 月 28 日 则第 3
  • 单元测试内存泄漏

    我有一个应用程序存在大量内存泄漏 例如 如果打开一个视图并关闭它 10 次 我的内存消耗会增加 因为视图没有完全清理 这些是我的内存泄漏 从测试驱动的角度来看 我想编写一个测试来证明我的泄漏 并 在修复泄漏之后 断言我修复了它 这样我的代码
  • php循环中的ajax在按钮单击时执行操作

    所以我有一个 php 循环 我使用 jquery 滑动切换来隐藏 显示带有 sql 结果的表 目前该表仅使用 php 加载 但由于发生了很多事情 导致了一些加载问题 我需要使用滑动切换 btn 来触发 ajax 因此它仅在按下按钮时请求当前
  • 24位整数

    为了检查一些银行帐号 我想对帐号进行模 97 但是很多帐号太大而无法输入 UInt64 如何对 24 位整数进行运算 Thanks 示例代码 无法转换 Convert ToUInt64 756842356987456214536254 97
  • 如何使用 ui-router 中的 ui-sref 将参数传递给控制器

    我需要传递和接收两个参数到我想要转换到的状态ui srefui router 的 例如使用下面的链接将状态转换为home with foo and bar参数 a Go to home state with foo and bar para
  • ICollection 和 IReadOnlyCollection 的扩展方法

    我想写一个扩展方法 例如 IsEmpty 对于 ICollection 和 IReadonlyCollection 接口 public static bool IsEmpty
  • Java 套接字 - 读和写

    问题 客户端没有收到任何消息 这是客户端和服务器的完整代码 CLIENT public class Client extends Socket public Client String hostName int port throws Un
  • 从 C# 调用非托管 dll。拿2

    我编写了一个 C 程序 它调用一个 C DLL 将命令行参数回显到文件中 当使用 rundll32 命令调用 c 时 它显示命令行参数没有问题 但是当从 c 内部调用它时 它不会显示 我问了这个问题 https stackoverflow
  • 加密 mongodb 中的密码字段

    我有以下代码 它插入userName and password进入数据库 但密码以纯文本格式存储 我的意思是 当我查看数据库时 我可以看到插入的密码 我想存储password in encrypted format MongoClient
  • 在启用滚动的情况下扩展堆栈视图内的 UITextView

    我正在尝试使用自动布局和 Stackview 来实现一些目标 我有一个垂直 Stackview 其中包含 UIView UITextView 和 UIView 如下所示 我已经在这里查看了以前的答案 但找不到一个干净的解决方案来实现此目的
  • 如何在React中处理多个路由器

    假设我们有一个网络应用程序 它通常有很多视图 例如索引页面 管理面板 帮助页面 联系人等 我在主index js 中使用react router dom 来处理它们 它工作得很好 但是现在我在开发管理面板时遇到了问题 它是 index js
  • WPF 和 WCF 应用程序的用户身份验证/授权的“最佳实践”是什么?

    假设我有一个 NET 富客户端 WPF 应用程序 它将同时部署在 3 个不同的场景中 客户端和服务器代码在单个进程中运行 客户端代码在 Intranet 计算机上运行 并通过 WCF 与运行应用程序 域 基础设施代码的服务器计算机进行通信
  • 对象映射器 - YAMLFactory - 由于缺少 _createContentReference 方法而出现异常

    我正在使用最新的 2 13 0 版本的 jackson 当我尝试解析 YAML 文件时 出现此异常 java lang NoSuchMethodError com fasterxml jackson core io ContentRefer
  • 在 UICollectionView 下面插入子视图

    当我在 UICollectionView 下方添加子视图时 有时子视图会显示在 UICollectionView 单元格上方 这是子视图插入代码 self collectionView insertSubview self garmentV
  • 有没有办法分析 WCF 应用程序的性能?

    我们正在尝试测量我们的系统的性能 该系统是一个使用 WCF 调用的 NET 3 5 应用程序 问题是到目前为止 我们无法分析这些调用中的方法 编写了一个 winforms 客户端应用程序来测试我们的系统 我们尝试使用ANTS 4 Profi
  • 如何在 Grails Geb/Spock 测试用例中获取 sessionFactory?

    我想我需要在 GebSpec 测试中刷新 hibernate 会话 所以我想获取 sessionFactory 看起来应该被注入 但是当我做这样的事情时 class MySpec extends GebSpec def sessionFac
  • Flask-Mail - 基于 Flask-Cookiecutter 异步发送电子邮件

    我的烧瓶项目基于烧瓶饼干切割机 https github com sloria cookiecutter flask我需要异步发送电子邮件 发送电子邮件的功能由以下配置米格尔的教程 https blog miguelgrinberg com
  • Puppeteer 无法在 VPS (DigitalOcean) 上工作

    我在水滴中数字海洋 https www digitalocean com 我收到这个错误 node 5549 UnhandledPromiseRejectionWarning TimeoutError Navigation Timeout
  • AngularJS:ng-show 与 display:none

    我有一个用例 我必须使用 CSS 默认隐藏 HTML 元素 如下所示 HTML div class item div CSS item display none 但是 我需要在页面加载后使用 ng show 切换元素的可见性 如下所示 di
  • 如何拦截 .Net 中第三方库对非虚拟方法的调用?

    我认为我需要的是 net 人们称之为 透明动态代理 的东西 但到目前为止我所看到的所有实现 Castle DynamicProxy Spring NET AOP 等 都要求我至少执行以下操作之一 将拦截的方法声明为虚拟方法 包装类并创建包装