我对 .NET 中网络模块的用例很感兴趣。特别是,我一直在寻找更好的方法来分解 .NET 中的解决方案,但没有那么多程序集要部署。Netmodules是一个非常有趣的想法,但它们似乎破坏了调试,并且在 Visual Studio 中不受本机支持(尽管它们适用于 MSBuild)。我更喜欢依赖 .NET 原生的东西,所以 ILMerge,虽然有趣并不是我真正想要的。
对于我自己的一些项目,我也开始使用FAKE,它允许一些有趣的构建步骤,例如分离出测试文件。换句话说,编写自定义编译步骤不是问题。
我对 .NET 中网络模块的用例很感兴趣。特别是,我一直在寻找更好的方法来分解 .NET 中的解决方案,但没有那么多程序集要部署。Netmodules是一个非常有趣的想法,但它们似乎破坏了调试,并且在 Visual Studio 中不受本机支持(尽管它们适用于 MSBuild)。我更喜欢依赖 .NET 原生的东西,所以 ILMerge,虽然有趣并不是我真正想要的。
对于我自己的一些项目,我也开始使用FAKE,它允许一些有趣的构建步骤,例如分离出测试文件。换句话说,编写自定义编译步骤不是问题。
网络模块本身实际上毫无价值:它们的类型和代码不能被运行时环境加载和执行。您只能从程序集中加载类型和执行代码,因此您很可能最终会将几个网络模块组合成一个(多文件)程序集。那么让我们来看看这些的好处。
Jeffrey Richter 在他的《通过 C# 的 CLR 》 (第 44 页)一书中提到了多文件程序集的三种用途,其中两种是由于使用了网络模块:
“您可以在单独的文件中划分您的类型,从而允许增量下载文件 [...]。将类型划分为单独的文件还允许对您购买和安装的应用程序进行部分或分段打包和部署。”
至少微软的 CLI (.NET) 实现似乎是增量加载多文件程序集,而不是从一开始就完全加载。来自程序集的模块似乎仅在实际需要其中的类型时才从磁盘(或从网络?)加载。
“您可以创建由以不同编程语言实现的类型组成的程序集。[…]”
我不确定这是否真的会在实际场景中增加很多价值,(a) 因为 Visual Studio 不支持对网络模块的项目引用,(b) 因为您可以通过程序集获得相同的好处。
多程序集和多文件程序集方法之间有一个显着区别:默认情况下,一个程序集不能访问具有internal
/ Friend
(即程序集)可见性的另一个程序集的类型。如果您要编译为模块,然后将它们链接到单个多文件程序集,则从 C# 编译的模块可以访问internal
使用 VB.NET 编译的模块的类型(反之亦然)。
您将在下面找到一个简短的演示。
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 的汇编嵌入技术吗?我自己没有尝试过,但看起来很有希望。
缺乏回应让我认为评论和答案中提到的其他选项通常被认为比网络模块更好的方法。我认为这意味着没有人真正使用或知道网络模块有什么好的用途。