You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现自定义Reactive属性?WPF中IL织入构建阶段问题求助

解决自定义IL织入的程序集锁定问题与正确实现方式

问题本质

你遇到的程序集锁定问题是必然的:CLR会锁定已加载到进程中的程序集文件,运行时尝试写入当前正在执行的程序集(Assembly.GetExecutingAssembly().Location)根本不可能成功。ReactiveUI的[Reactive]属性之所以能正常工作,是因为它的IL织入逻辑是在编译构建阶段完成的,而非运行时。

正确的实现路径

所有IL织入操作都应该放在编译构建流程中,以下是两种可行方案:

方案一:基于Fody框架实现(推荐)

Fody已经封装了构建阶段IL织入的所有细节,不用自己处理MSBuild任务和文件替换逻辑:

  • 创建Fody Addin项目:定义你的自定义属性(比如[MyReactive]),然后编写继承自BaseModuleWeaver的Weaver类。
  • 在Weaver类中用Mono.Cecil处理程序集:查找继承指定基类的类型,扫描带自定义属性的属性,自动生成私有字段、属性的get/set逻辑,并添加PropertyChanged事件触发代码。
  • 在目标WPF项目中引用你的Fody Addin:Fody会在编译完成后自动执行织入操作,直接修改输出目录中的程序集文件——此时程序集还未被加载,完全不会有锁定问题。

方案二:自定义MSBuild任务(不依赖Fody)

如果不想用Fody,可以自己写MSBuild任务嵌入到构建流程:

  • 创建一个类库项目,继承Microsoft.Build.Utilities.Task,在Execute方法中编写Mono.Cecil的IL处理逻辑。
  • 处理目标为编译输出的程序集(比如$(OutputPath)$(AssemblyName).dll),而非当前执行的程序集——构建阶段输出的程序集还未被CLR加载,不会被锁定。
  • 在WPF项目的csproj文件中添加任务引用,将任务绑定到AfterBuild目标,确保编译完成后立即执行IL织入。

关键注意事项

  • 永远不要尝试在运行时修改当前正在执行的程序集,这是CLR的核心机制限制,没有绕过的方法。
  • 无论是Fody还是自定义MSBuild任务,核心都是在程序集被加载前完成IL修改,避免文件锁定。
  • 测试时要确保每次构建都清理旧的输出文件,防止织入逻辑被缓存的旧程序集覆盖。

内容的提问来源于stack exchange,提问作者crackanddie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 18:45:17