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"
Related
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.
Since version 3.0, .NET installs a bunch of different 'reference assemblies' under C:\Program Files\Reference Assemblies\Microsoft...., to support different profiles (say .NET 3.5 client profile, Silverlight profile). Each of these is a proper .NET assembly that contains only metadata - no IL code - and each assembly is marked with the ReferenceAssemblyAttribute. The metadata is restricted to those types and member available under the applicable profile - that's how intellisense shows a restricted set of types and members. The reference assemblies are not used at runtime.
I learnt a bit about it from this blog post.
I'd like to create and use such a reference assembly for my library.
How do I create a metadata-only assembly - is there some compiler flag or ildasm post-processor?
Are there attributes that control which types are exported to different 'profiles'?
How does the reference assembly resolution at runtime - if I had the reference assembly present in my application directory instead of the 'real' assembly, and not in the GAC at all, would probing continue and my AssemblyResolve event fire so that I can supply the actual assembly at runtime?
Any ideas or pointers to where I could learn more about this would be greatly appreciated.
Update: Looking around a bit, I see the .NET 3.0 'reference assemblies' do seem to have some code, and the Reference Assembly attribute was only added in .NET 4.0. So the behaviour might have changed a bit with the new runtime.
Why? For my Excel-DNA ( http://exceldna.codeplex.com ) add-in library, I create single-file .xll add-in by packing the referenced assemblies into the .xll file as resources. The packed assemblies include the user's add-in code, as well as the Excel-DNA managed library (which might be referenced by the user's assembly).
It sounds rather complicated, but works wonderfully well most of the time - the add-in is a single small file, so no installation of distribution issues. I run into (not unexpected) problems because of different versions - if there is an old version of the Excel-DNA managed library as a file, the runtime will load that instead of the packed one (I never get a chance to interfere with the loading).
I hope to make a reference assembly for my Excel-DNA managed part that users can point to when compiling their add-ins. But if they mistakenly have a version of this assembly at runtime, the runtime should fail to load it, and give me a chance to load the real assembly from resources.
To create a reference assembly, you would add this line to your AssemblyInfo.cs file:
[assembly: ReferenceAssembly]
To load others, you can reference them as usual from your VisualStudio project references, or dynamically at runtime using:
Assembly.ReflectionOnlyLoad()
or
Assembly.ReflectionOnlyLoadFrom()
If you have added a reference to a metadata/reference assembly using VisualStudio, then intellisense and building your project will work just fine, however if you try to execute your application against one, you will get an error:
System.BadImageFormatException: Cannot load a reference assembly for execution.
So the expectation is that at runtime you would substitute in a real assembly that has the same metadata signature.
If you have loaded an assembly dynamically with Assembly.ReflectionOnlyLoad() then you can only do all the reflection operations against it (read the types, methods, properties, attributes, etc, but can not dynamically invoke any of them).
I am curious as to what your use case is for creating a metadata-only assembly. I've never had to do that before, and would love to know if you have found some interesting use for them...
If you are still interested in this possibility, I've made a fork of the il-repack project based on Mono.Cecil which accepts a "/meta" command line argument to generate a metadata only assembly for the public and protected types.
https://github.com/KarimLUCCIN/il-repack/tree/xna
(I tried it on the full XNA Framework and its working afaik ...)
Yes, this is new for .NET 4.0. I'm fairly sure this was done to avoid the nasty versioning problems in the .NET 2.0 service packs. Best example is the WaitHandle.WaitOne(int) overload, added and documented in SP2. A popular overload because it avoids having to guess at the proper value for *exitContext" in the WaitOne(int, bool) overload. Problem is, the program bombs when it is run on a version of 2.0 that's older than SP2. Not a happy diagnostic either. Isolating the reference assemblies ensures that this can't happen again.
I think those reference assemblies were created by starting from a copy of the compiled assemblies (like it was done in previous versions) and running them through a tool that strips the IL from the assembly. That tool is however not available to us, nothing in the bin/netfx 4.0 tools Windows 7.1 SDK subdirectory that could do this. Not exactly a tool that gets used often so it is probably not production quality :)
You might have luck with the Cecil Library (from Mono); I think the implementation allows ILMerge functionality, it might just as well write metadata only assemblies.
I have scanned the code base (documentation is sparse), but haven't found any obvious clues yet...
YYMV
I have a semi-large C# .exe project in visual studio 2010 Ultimate, and I would like to convert it to a DLL class library. Is there an easy way to do this that doesn't involve creating a new class library project? Thanks beforehand.
Project > Properties > Application tab, change Output type to "Class Library".
For the record, this isn't actually necessary. An EXE project works fine as an assembly reference. Assuming classes were declared public, something you might have to fix anyway to make them work in a library.
In .NET, an .exe and a .dll are both legal as references. This is because in .NET, there exists two type of assemblies:
process assemblies - known in public as executables, or exe
library assemblies - known in public as dll
An assembly in .NET holds many modules, that in turn holds one or more classes (the guideline is one class per module). These modules is turned into IL code at compile time and JIT'd at runtime.
The important part for both types of assemblies is that each assembly holds meta data like
modules
methods
types
there exists in an assembly. And because of that the runtime, and compiler, can easily determine how to fx call a certain method in a process assembly.
I think, without being an expert on the subject, that the major difference between process assemblies and library assemblies is that process assemblies holds some extra code, telling the runtime how to load, and what to load.
Go into My Project in your solution, select the Application tab, and change the Application type to Class Library.
right click on project and goto its properties and look for the Configuration type in Configuration Properties then change it to .lib from .exe ... this changes the application type from executable to library
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
I am trying to sign an assembly with a strong name by following the guide from here: http://msdn.microsoft.com/en-us/library/xc31ft41.aspx
The key instruction is:
al /out:<assembly name> <module name> /keyfile:<file name>
And it says
module name is the name of the code module used to create the assembly
I don't understand what this means. In the literal sense I would interpret the above as some component of csc.exe (i.e., it created the assembly) but obviously this is nonsensical in this context.
So firstly what does this refer to, and secondly (in order to aid my meta-learning) how would one go about reasoning what it is? I get the impression given the terseness of the documentation that it should be obvious or intuitive to me, but it currently is not.
I tried specifying some random names (e.g. blah.blah) but get this error:
ALINK: error AL1047: Error importing file
'c:\path\to\proj\bin\Debug\blah.blah' -- The system cannot find
the file specified.
Edit: Upon further reading I get the impression the module name is the name of the code, but I have not had any luck specifying the .cs files either - I am told Database file is corrupt and may not be usable.
An assembly is made up of modules (.netmodule files), which are produced by compiling sources (.cs files). The assembly linker is responsible for packaging modules into assemblies. So if you have two source files class1.cs and class2.cs:
csc /t:module class1.cs
csc /t:module class2.cs
al /out:assembly.dll /t:library class1.netmodule class2.netmodule
For the best treatment of how the CLR deals with modules, manifests and assemblies, see Richter.
In VS2010, click on Project Properties -> Signing Tab -> Check Sign this assembly.
Provide or create Strong name key.
See if you can find what you're looking for with this link. If not, I might help for further research. As for now, I don't have much spare time, but that may change within the next hour.
Sign assembly with strong name using al /out command