我对 .NET 中网络模块的用例感兴趣。特别是,我一直在寻找更好的方法来分解 .NET 中的解决方案,但没有那么多的程序集需要部署。 Netmodules是一个非常有趣的想法,但它们似乎会破坏调试并且在 Visual Studio 中不受本机支持(尽管它们适用于 MSBuild)。 我更喜欢依赖 .NET 原生的东西,所以 ILMerge,虽然有趣并不是我真正想要的。
对于我自己的一些项目,我也开始使用FAKE,它允许一些有趣的构建步骤,例如分离测试文件。换句话说,编写自定义编译步骤不是问题。
netmodule 本身几乎毫无价值:它们的类型和代码无法由运行时环境加载和执行。您只能从 assemblies 加载类型并执行代码,因此您最终很可能会将多个网络模块组合到一个(多文件)程序集中。那么让我们来看看这些的好处。
Jeffrey Richter 在他的书 CLR via C#(第 44 页)中提到了多文件程序集的三种用途,其中两种用途来自于网络模块的使用:
“您可以将类型划分为单独的文件,从而允许增量下载文件 [...]。将类型划分为单独的文件还允许对您购买和安装的应用程序进行部分或零碎的打包和部署。”
至少 Microsoft 的 CLI (.NET) 实现似乎是增量加载多文件程序集,而不是从一开始就加载完整的程序集。程序集中的模块仅在实际需要其中的类型时才会从磁盘(或从网络?)加载。
“您可以创建由以不同编程语言实现的类型组成的程序集。[…]”
我不确定这实际上会在现实场景中增加很多价值,(a) 因为 Visual Studio 不支持对网络模块的项目引用,(b) 因为您可以通过程序集获得相同的好处。
多程序集和多文件程序集方法之间有一个显着区别:默认情况下,一个程序集无法访问具有
internal
/Friend
(即程序集)可见性的另一程序集的类型。如果您编译为模块,然后将它们链接到单个多文件程序集中,则从 C# 编译的模块可以访问使用 VB.NET 编译的模块的 internal
类型(反之亦然)。
您将在下面找到对此的简短演示。
CsharpClass.cs:
internal class CsharpClass { }
VbClass.vb:
Friend Class VbClass : End Class
程序.cs:
public static class Program
{
public static void Main()
{
var vbClass = new VbClass();
var csharpClass = new CsharpClass();
}
}
为网络模块构建脚本:
csc.exe /t:module /out:CsharpClass.netmodule CsharpClass.cs
vbc.exe /t:module /out:VbClass.netmodule VbClass.vb
csc.exe /t:exe /out:Program.exe /addmodule:CsharpClass.netmodule /addmodule:VbClass.netmodule Program.cs
此构建将正常运行并执行,不会出现任何错误。
请注意,
.netmodule
文件扩展名并没有什么神奇之处;这只是一个约定,但输出文件是常规的 .NET DLL。
为程序集构建脚本:
csc.exe /t:library /out:CsharpClass.dll CsharpClass.cs
vbc.exe /t:library /out:VbClass.dll VbClass.vb
csc.exe /t:exe /out:Program.exe /r:CsharpClass.dll /r:VbClass.dll Program.cs
此构建将失败,因为:
Program.cs(5,27): error CS0122: 'VbClass' is inaccessible due to its protection level
Program.cs(5,23): error CS0143: The type 'VbClass' has no constructors defined
Program.cs(6,31): error CS0122: 'CsharpClass' is inaccessible due to its protection level
Program.cs(6,27): error CS0143: The type 'CsharpClass' has no constructors defined
你能使用Jeffrey Richter的汇编嵌入技术吗?我自己还没尝试过,但看起来很有希望。
缺乏回应让我认为评论和答案中提到的其他选项通常被认为是比 netmodules 更好的方法。我认为这意味着没有人真正使用或知道 netmodules 的任何好的用途。