What is the difference and advantage between having a single file assembly that is physically coded in multiple .cs files and a multi file assembly that has multiple .NetModules??
My prof says that the difference could be realized when these assemblies get loaded or during jitting. That not all .Netmodules of a multi file assembly will be loaded at once. But even he is not sure. Could anybody clarify me?
There is also an assembly type that groups its elements in multiple files, called a multi-file assembly. Visual Studio . NET IDE can only be used to create single-file assemblies, but Multifile assemblies can be created using command-line compilers.
Single file and Multi-file AssemblyA single file assembly contains all the necessary elements such as CIL code, header files and manifests in a single *.exe or *. dll package. A multi-file assembly, on the other hand, is a set of . NET modules that are deployed and versioned as a single unit.
There are several reasons you might want to create a multifile assembly: To combine modules written in different languages. This is the most common reason for creating a multifile assembly. To optimize downloading an application by putting seldom-used types in a module that is downloaded only when needed.
If you want to create multifile assemblies, you must use the command-line compilers or Visual Studio with Visual C++.
Lets assume that we have two .cs files called RUT.cs
, which contains rarely used types FUT.cs
, which contains frequently used types
Now 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
JeffTypes.dll instead of calling it FUT.dll:
csc /out:JeffTypes.dll /t:library /addmodule:RUT.netmodule FUT.cs
This line tells the C# compiler to compile the FUT.cs file to produce the JeffTypes.dll file. Because /t:library is specified, a DLL PE file containing the manifest metadata tables is emitted into the JeffTypes.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 /addmodule switch 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.
The RUT.netmodule file contains the IL code generated by compiling RUT.cs. This file also
contains metadata tables that describe the types, methods, fields, properties, events, and so
on that are defined by RUT.cs. The metadata tables also describe the types, methods, and
so on that are referenced by RUT.cs. The JeffTypes.dll is a separate file. Like RUT.netmodule,
this file includes the IL code generated by compiling FUT.cs and also includes similar definition
and reference metadata tables. However, JeffTypes.dll contains the additional manifest
metadata tables, making JeffTypes.dll an assembly. The additional manifest metadata tables
describe all of the files that make up the assembly (the JeffTypes.dll file itself and the
RUT.netmodule file). The manifest metadata tables also include all of the public types
exported from JeffTypes.dll and RUT.netmodule
Now if some clinet code refrencing to JeffTypes.dll is executing,
When a method is called for the first time, the
CLR detects the types that the method references as a parameter, a return value, or as a
local variable. The CLR then attempts to load the referenced assembly’s file that contains the
manifest. If the type being accessed is in this file, the CLR performs its internal bookkeeping,
allowing the type to be used. If the manifest indicates that the referenced type is in a different
file, the CLR attempts to load the necessary file, performs its internal bookkeeping, and
allows the type to be accessed. The CLR loads assembly files only when a method referencing
a type in an unloaded assembly is called.
This means that to run an application, all of the files
from a referenced assembly do not need to be present.
So, less used source classes could be compiled in NetModules and loaded when necessary, boosting performance and less Dll file sizes eases change management and deployment process.
Images and some of the quotes from jeffrey richter
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With