C# .NET 模块与程序集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9271805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 06:39:20  来源:igfitidea点击:

.NET Module vs Assembly

c#.net

提问by mike01010

I've been trying to wrap my head around the 'right' answer to this? there are a couple of topics on stackoverflow that covers this, but that conflicts somewhat with msdn documentation.

我一直在试图围绕这个“正确”的答案?stackoverflow 上有几个主题涵盖了这一点,但这与 msdn 文档有些冲突。

for example, note the diagram in the 2nd answer to his question: What is a Managed Module (compared to an Assembly)?

例如,请注意他的问题的第二个答案中的图表:什么是托管模块(与程序集相比)?

Now look at the msdn diagram: http://msdn.microsoft.com/en-us/library/zst29sk2(VS.100).aspx

现在看msdn图:http: //msdn.microsoft.com/en-us/library/zst29sk2(VS.100) .aspx

the msdn diagram implies that a single-file assembly does not comprise of a module, but rather of a manifest, il code, type metadata, etc. This is different than many other articles i've read which states that a single file assembly has one module.

msdn 图暗示单文件程序集不包含模块,而是包含清单、IL 代码、类型元数据等。这与我读过的许多其他文章不同,这些文章指出单个文件程序集具有一个模块。

What is the answer? If the answer is 'both', then is the module a separate phyical file that is linked via the assembly manifest?

答案是什么?如果答案是“两者”,那么该模块是否是通过程序集清单链接的单独物理文件?

采纳答案by Hans Passant

Every assembly has at least one module. It is an implementation detail that's highly invisible. But you can see it when you use Reflection.Emit. From the sample code for the AssemblyBuilder class:

每个组件至少有一个模块。这是一个高度不可见的实现细节。但是当你使用 Reflection.Emit 时你可以看到它。从AssemblyBuilder 类的示例代码中:

AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
AssemblyBuilder ab = 
    AppDomain.CurrentDomain.DefineDynamicAssembly(
        aName, 
        AssemblyBuilderAccess.RunAndSave);

// For a single-module assembly, the module name is usually
// the assembly name plus an extension.
ModuleBuilder mb = 
    ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");

TypeBuilder tb = mb.DefineType(
    "MyDynamicType", 
     TypeAttributes.Public);

Note the use of the ModuleBuilder class, types are added to a module. That an assembly can contain multiple modules is pretty irrelevant, the build environment doesn't support it. Not just the IDE, MSBuild doesn't support it either. You'd have to write a build script yourself to use al.exe, the assembly linker. There are no good reasons to do this that I can think of, all .NET compilers already know how to generate a single module assembly directly. Al.exe is a typical bootstrapping tool, possibly used to build mscorlib.dll.

注意 ModuleBuilder 类的使用,类型被添加到模块中。一个程序集可以包含多个模块是无关紧要的,构建环境不支持它。不仅仅是 IDE,MSBuild 也不支持它。您必须自己编写构建脚本才能使用al.exe,即程序集链接器。我想不出这样做的充分理由,所有 .NET 编译器都已经知道如何直接生成单个模块程序集。Al.exe 是典型的引导工具,可能用于构建 mscorlib.dll。

回答by GGulati

A module is a logical collection of code within an Assembly. You can have multiple modules inside an Assembly, and each module can be written in different .NET languages (VS, as far as I'm aware, doesn't support creation of multi-module assemblies).

Assemblies contain modules. Modules contain classes. Classes contain functions.

模块是程序集中代码的逻辑集合。你可以在一个程序集中有多个模块,每个模块可以用不同的 .NET 语言编写(VS,据我所知,不支持创建多模块程序集)。

程序集包含模块。模块包含类。类包含函数。

From: What is a module in .NET?

来自:.NET 中的模块是什么?

Really From: Bing search ".NET module vs assembly"

真的来自:Bing 搜索“.NET 模块 vs 程序集”

回答by Deepak Mishra

In .net the difference between an assembly and module is that a module does not contain the manifest.

在 .net 中,程序集和模块之间的区别在于模块不包含清单

//Copied from CLR via C#

What is manifest?

什么是显化?

The manifest is another set of metadata tables that basically contain the names of the files that are part of the assembly. They also describe the assembly's version, culture, publisher, publicly exported types, and all of the files that comprise the assembly.

清单是另一组元数据表,主要包含作为程序集一部分的文件的名称。它们还描述了程序集的版本、文化、发布者、公开导出的类型以及组成程序集的所有文件。

The CLR operates on assemblies; that is, the CLR always loads the file that contains the manifest metadata tables first and then uses the manifest to get the names of the other files/modules that are in the assembly.

CLR 对程序集进行操作;也就是说,CLR 总是首先加载包含清单元数据表的文件,然后使用清单来获取程序集中其他文件/模块的名称。

How to Combinine Modules to Form an Assembly?

如何组合模块以形成程序集?

Using C# compiler

使用 C# 编译器

To understand how to build a multifile/multimodule assembly, let's assume that we have two source code files:

要了解如何构建多文件/多模块程序集,让我们假设我们有两个源代码文件:

■■ RUT.cs, which contains rarely used types

■■ RUT.cs,包含很少使用的类型

■■ FUT.cs, which contains frequently used types

■■ FUT.cs,包含常用类型

Let's compile the rarely used types into their own module so that users of the assembly won't need to deploy this module if they never access the rarely used types.

让我们将很少使用的类型编译到他们自己的模块中,这样如果程序集的用户从不访问很少使用的类型,他们就不需要部署这个模块。

csc /t:module RUT.cs

This line causes the C# compiler to create a RUT.netmodule file. This file is a standard DLL PE file, but, by itself, the CLR can't load it. Next let's compile the frequently used types into their own module. We'll make this module the keeper of the assembly's manifest because the types are used so often. In fact, because this module will now represent the entire assembly, I'll change the name of the output file to MultiFileLibrary.dll instead of calling it FUT.dll.

此行导致 C# 编译器创建 RUT.netmodule 文件。该文件是一个标准的 DLL PE 文件,但 CLR 无法加载它本身。接下来让我们将常用的类型编译到它们自己的模块中。我们将让这个模块成为程序集清单的管理员,因为这些类型被经常使用。事实上,因为这个模块现在将代表整个程序集,所以我将输出文件的名称更改为 MultiFileLibrary.dll,而不是将其命名为 FUT.dll。

csc /out:MultiFileLibrary.dll /t:library /addmodule:RUT.netmodule FUT.cs

This line tells the C# compiler to compile the FUT.cs file to produce the MultiFileLibrary.dll file. Because /t:library is specified, a DLL PE file containing the manifest metadata tables is emitted into the MultiFileLibrary.dll file. The /addmodule:RUT.netmodule switch tells the compiler that RUT.netmodule is a file that should be considered part of the assembly. Specifically, the /addmoduleswitch tells the compiler to add the file to the FileDef manifest metadata table and to add RUT.netmodule's publicly exported types to the ExportedTypesDef manifest metadata table.

该行告诉 C# 编译器编译 FUT.cs 文件以生成 MultiFileLibrary.dll 文件。由于指定了 /t:library,一个包含清单元数据表的 DLL PE 文件被发送到 MultiFileLibrary.dll 文件中。该/addmodule:RUT.netmodule开关告诉编译器RUT.netmodule是应该被认为是组件的一部分的文件。具体来说,该/addmodule开关告诉编译器将文件添加到 FileDef 清单元数据表,并将 RUT.netmodule 的公开导出类型添加到 ExportedTypesDef 清单元数据表。

After the compiler has finished all of its processing, the two files shown in Figure 2-1 are created. The module on the right contains the manifest.

编译器完成所有处理后,将创建图 2-1 所示的两个文件。右侧的模块包含清单。

enter image description here

在此处输入图片说明

Using the Assembly Linker

使用程序集链接器

The AL.exe utility can produce an EXE or a DLL PE file that contains only a manifest describing the types in other modules. To understand how AL.exe works, let's change the way the MultiFileLibrary.dll assembly is built.

AL.exe 实用程序可以生成仅包含描述其他模块中类型的清单的 EXE 或 DLL PE 文件。要了解 AL.exe 的工作原理,让我们更改 MultiFileLibrary.dll 程序集的构建方式。

csc /t:module RUT.cs
csc /t:module FUT.cs
al /out: MultiFileLibrary.dll /t:library FUT.netmodule RUT.netmodule

Figure 2-3 shows the files that result from executing these statements.

图 2-3 显示了执行这些语句所产生的文件。

enter image description here

在此处输入图片说明

I would suggest you to read CHAPTER 2: Building, Packaging, Deploying, and Administering Applications and Typesfrom CLR via C# by Jeffrey Richterto understand the concept in detail.

我建议您阅读第 2 章:通过 C#CLR构建、打包、部署和管理应用程序和类型Jeffrey Richter以详细了解该概念。