Assembly with multiple managed modules - c#

I understand that an Assembly is made of 1 or more modules, and resource files if any.
If you compile a project in C#, then the compiler will simply turn the code into a managed module, and then throw that module into an assembly. Now my question is, when would an Assembly have more than 1 managed module?

Heres a good explanation of that Netmodule vs. Assembly.
In short, one would use multiple modules for these reasons:
Multi-language assemblies.
If the assembly is consist of source files with different programming languages, you have to compile files with the same programming languages into netmodules, then link them into assemblies.
Separately maintained source files.
If the assembly is maintained by multiple developers, it may make sense to separate the source files into small collections. Each collection is owned by an individual developer. Collections are compiled as netmodules, then linked to the final assembly.
Small download footprint.
If the assembly is hosted in an http site, CLR will only download the main module at the first time. The remaining modules will be downloaded on demand. You can separate the less frequently used code from the main line code, and compiled the less frequently used code as a netmodule. User will only download the netmodule when it is needed.
Link the same source files into multiple assemblies.
You may have some common code that is used in multiple assemblies. The common code is small enough that it is not worth to compile them into a separate assembly. To avoid compiling the same source files multiple times, you can compile them into a netmodule, then link it into different assemblies.

If you have a class in a Project namespace, and another class in a Project.Utilities namespace, there would be two modules:
Project
Project.Utilities
This seems to be the way that the .Net assembly is organised, classes -> modules -> assembly.
The compiler seems to name modules by the namespaces the classes are in.
You can see the module structure in existing assemblies by using ildasm or .Net Reflector

Related

Only compile certain parts of my program depending on the calling assembly

I have three assemblies. One assembly contains code that relies on the 'NETWORKING' COM service. This service is not available on some machines and I would like to only compile the code depending on the assembly that consume this assemblies.
I have two assemblies that rely on this shared assembly: One GUI and one CLI assembly.
I tried to use the #define preprocessor check, but this only works within the same assembly (right?).
The obvious yet time consuming choice would be to extract the code into a separate assembly.
I was wondering if there is another possibility. Just like defining symbols or something like. The CLI assembly would define the CLI keyword and the GUI assembly would define a keyword 'GUI'.
In the shared assembly I could then use something similiar to
#if CLI
using NETWORKLIST;
#endif
Is this somehow possible in Visual Studio / C#?
Assemblies are independent, so unless you're using the same "build" each time, the short answer would be "no, you can't do that". The most appropriate approach here is to move the relevant code to another assembly - which is probably less than 3 minutes work. Alternatively: just ignore it and accept that a few extra bytes of disk space are being used unnecessarily - it won't hurt.

C# Adding a reference to a class in another project without referencing the project

I have two projects:
ProjectMain (class library)
LibraryProject (class library)
ProjectMain is a class library that should only be compiled as a singular library, no referenced libraries. I require a static class reference from LibraryProject BUT I don't want the LibraryProject assembly to be compiled together with the ProjectMain assembly.
I've tried 'link references' in visual studio but this is no solution as the library assembly is always compiled with the main assembly.
There are clear standard solutions to this issue but I am severely limited by the existing implementation requirements. Only one DLL can be compiled without any of the dependent assemblies being in the execution folder, GAC, private path, reflection etc.
The exact limitations are as follows:
Assembly executed in a sandbox from a third party provider, it only supports adding a single assembly with no direct references/reflection etc (it's horrible but my hands are tied)
We would like to handle the code organisation as best possible which means following standard best practices, unfortunately, due to the above limitation that's proving difficult.
What I would like to know is if there is a way to reference a class within another project without also compiling/using that referenced classes assembly. Possibly a method where the compiler 'embeds' the referenced class at compile time.
If your sandbox does not allow loading other dlls in AppDomain, load it yourself by embedding it. You can use Costura.Fody for this purpose, it is easy to use/install, just reference it from nuget.
Of course, embedding it in every scenario is madness and often comes with completely obscure bugs, which often solvable only by enabling traces in regedit.
So, in your case I would create two projects:
MyDll.csproj //it is my original project, with perfect code design and etc. Lovely.
MyDll.Sandbox.csproj //this one is the same as MyDll.csproj, except it is compiled with additional Costura.Fody reference, into single dll (every reference is put inside)
This way you just need to maintenance that MyDll and MyDll.Sandbox files are the same.

Which DLL contains the code of the code behind of a SVC-file?

I am making a tool which scans the drives of the current computer for applications made by our company. If it encounters one of our services (the SVC-file) it should also obtain te version of the code. To do so, it should find out which DLL is holding the code behind of the SVC-file.
The SVC-file only contains the name of the namespace and class, not the name of the DLL. The BIN-folder contain multiple DLL's, so which one could it be...?
In this case we cannot assume that the assemblies have the same name as the (root) namespace, so that is not any help.
The only way I can think of is opening all DLL's in a seperate AppDomain and check all the containing namespaces + classes.
Does someone know a quicker way?
As suggested, the software is now scanning all assemblies which could belong to the SVC-file. Creating seperate AppDomains to reflect each individual DLL is very slow. So I was thinking: "How do other programs deal with this problem?", so I took a look at ILSpy.
ILSpy uses Mono.Cecil to reflect assemblies. It reads the assemblies on a binary level and does not create a seperate AppDamain. It even returns more information than normal reflection.
I downloaded this DLL and used it in my application and works perfectly.

.NET building process and linking

Building is the sequence composed of compiling and linking.
In .NET the source code is compiled into the assembly that contains Common Intermediate Language and type info. At run time the JIT compiler converts the CIL code into native code.
I do not understand, in .NET ,how and when the linking is occurring.
Can someone please explain the process ?
Thanks in advance
There's no linking in terms of C++.
I mean, there's no any intermediate "obj"/"lib" files, that can be distributed and linked with another "obj" files later. Reference to an assembly always has dynamic behavior (always dynamic-link library), as opposed to C++ static linking.
Something like linking is a creation of .netmodule. You can build .NET source code with compiler into .netmodule instead of assembly (look here, especially section "Differences Between C# Compiler and C++ Compiler Output"), and later you can link these modules together into a single assembly (see al.exe).
But this is uncommon practice - most of assemblies contains single module, and this work (source -> module -> assembly) has been done by compiler (e.g., csc.exe) behind the scenes. Also, I can't remember any product being redistributed as a set of .netmodule (not as a set of assemblies).

.NET Module vs Assembly

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.
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
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.
What is the answer? If the answer is 'both', then is the module a separate phyical file that is linked via the assembly manifest?
In .net the difference between an assembly and module is that a module
does not contain the manifest.
//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.
How to Combinine Modules to Form an Assembly?
Using C# compiler
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
■■ FUT.cs, which contains frequently used types
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.
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 /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.
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.
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.
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.
I would suggest you to read CHAPTER 2: Building, Packaging, Deploying, and Administering Applications and Types from CLR via C# by Jeffrey Richter to understand the concept in detail.
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:
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.
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.
From: What is a module in .NET?
Really From: Bing search ".NET module vs assembly"

Categories