首页 > 解决方案 > Fody NuGet 包如何在编译过程结束时合并程序集?

问题描述

最近我遇到了一个用于修改 .NET 程序集的 NuGet 包,特别是,有一个用于 Fody 包的 Costura NuGet“插件”,它在 C# 编译器完成后合并程序集。

我找不到对 .csproj 文件的任何修改(除了 NuGet 导入),它显示了在构建程序集后执行的任务。

我想知道 Fody 如何能够在构建后运行代码而无需在任何地方进行任何明显的配置更改。

标签: c#fodyfody-costura

解决方案


Fody将此.targets文件添加到您的项目中。如果您有一个经典的 NET 框架项目,您会看到它已添加到 .csproj 文件中。如果您有一个 netstandard 项目(新项目格式),它会在构建过程中直接从 nuget 包中自动获取,因此您不会在项目中看到它(但您会在 \obj\ 文件夹中看到它,稍微重命名) .

简化:该目标在“AfterCompile”目标之后执行。它搜索 Weavers.xml 文件。对于它在列表中找到的每个编织器(例如 Costura),它调用编织器的程序集。编织者使用基于 Mono/Cecil 的 Fody 基础架构来处理您的程序集的 IL、后期构建和重写 IL。

在 Costura 的情况下(再次简化),它将每个参考程序集转换为嵌入式资源。然后它将一个模块初始化器添加到您的程序集中。模块初始化程序(在 C#9 之前您无法用纯 C# 编写的东西)保证在调用程序集中的任何代码之前运行 - 将其视为静态构造函数,但对于程序集。

它添加到模块初始化程序的代码将一个附加AssemblyResolveEventAppDomain. 此处理程序将使用清单资源流来满足 Costura 通过Assembly.Load使用流中的字节调用嵌入的程序集的分辨率。然后它从处理程序返回该Assembly对象,从而满足程序集的分辨率。或者,Costura 可以将 DLL 提取到磁盘上的临时位置,然后使用该路径来满足解析(有时需要取决于所涉及的 DLL)。

Fody和Costura文档详细解释了这是如何工作的


推荐阅读