Understanding .Net Assemblies and References E-mail
Article Index
Understanding .Net Assemblies and References
Assembly Name, Identity, & References
Binding Redirects, config Files, & Loading
The GAC
codeBase Path & Probing
All Pages
An introduction to the nuances of .Net assemblies and references for anyone who's be bewildered by their intricacies. Originally published on Jan 6, 2006.

Assembly Manifest

Every .Net assembly contains a manifest that contains descriptive information about the assembly, including the assembly identity information (name, etc, see below), what files make up the assembly, what types or functionality can be called from a different assembly, and what other assemblies it depends upon. You can view the assembly manifest by opening it with the ildasm tool. Run ildasm.exe from the .Net Command Line.

The assembly manifest doesn’t store the paths used when you add a reference through the IDE – it only stores information about the assemblies being referenced.

Before I continue, here are a number of .Net references for further reading.

IDE References

In order to write code that uses the functionality of a different component, the development environment needs to know what that component is capable of doing and how to call its functionality. In Visual Studio, you make your application aware of other components by “adding references” to them. When a reference to an assembly is added, the IDE will inspect the manifest of the referenced assembly to see what it can do and how it should be used. You can add File, Project, COM, .Net, Web, and dynamic references to Visual Studio projects. I’ll discuss File and Project references in more detail, and the others below, plus a bit about VB6 references as they relate to .Net.

In this context, references are for the IDE and build process, not for application execution.

Project References: When you use a project reference (preferred, if at all possible), then you’re telling a project that it depends upon the output of another project in the same solution. When the solution builds, the IDE builds the dependencies first, then finds the output DLLs in the output paths associated with the current configuration. (If you’re in Debug configuration, it’ll find that output file in the referenced project’s Debug bin, and if you’re in Release configuration, it’ll find it in its Release bin.) Once found, the file is copied into the obj directory of the application, then to the bin directory when the build is complete. (The obj directory is basically a temporary working folder that the IDE uses during builds.) This is all pretty handy, and that’s why it’s preferred.

If a dependency can’t be built, the IDE will (by default) keep going down its list of builds and you’ll probably get an error when the referencing assembly tries to build and the file can’t be found. Project references can only be exchanged among projects in the same solution. (Projects, by the way, are perfectly happy existing in more than one solution at a time.)

File References: When you use a file reference, you actually specify the exact path that the IDE will use to find the referenced assembly so it can examine its manifest and learn how it works. If the referenced file is not in the GAC and not a framework component, then the Copy Local property of the reference will default to True, meaning that during build, the IDE will follow the reference path, fetch the file, and copy it into the obj and bin directories so it can be found and used at run time (see below). This can have unfortunate side effects, though, if more than one version of the same file name is referenced along the dependency chain. (The file system knows nothing about assembly names or assembly versions and only considers file names when copying a file from one place to another.) For this reason, it’s a good idea to disable "Copy Local" in these cases. For example, if

  • MyApp references MyUtilDll (v 2), and
  • MyApp references MyBllDll (v 2), and
  • MyUtilDll (v 2) references MyBllDll (v 1)
...then Copy Local will do more harm than good because one of the MyBllDll DLLs will get copied over another when the solution is built.

Other reference types: Here’s a brief overview of the other types of references:

  • COM – A reference is made to a COM interop component that’s installed in the registry.
  • .Net – A reference is made to a specific subset of GAC assemblies whose locations have been listed in the system registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders. Otherwise, like a file reference.
  • Web – A proxy class is generated from information in the WSDL and is added to the project. No other files are required.
  • Dynamic – A reference is made at run-time using a method like Assembly.Load(), which causes the referenced assembly to be loaded on the fly.

VB6 References: Because VB6 knew nothing about .Net when it was born, it wouldn’t know what to do with an Assembly if it were given one. Because of this, Microsoft created a way for .Net assemblies to masquerade as COM objects and a tool that generates a type library from an assembly (tlbexp.exe). A type library is the ActiveX equivalent of an assembly manifest – it contains lots of interface information but no code. Once the functionality of an ActiveX object is discovered using a type library, it’s up to the consuming application to actually find the file that contains the code. It does this by way of the system registry. First it looks up the fully qualified name of the class being instantiated (e.g. MyCompany.MyTechnology.MyClass) in H_KEY_CLASSES_ROOT. It finds that class’ ID (CLSID, a GUID), and then looks up that class ID in H_KEY_CLASSES_ROOT/CLSID. From there it inspects that key’s InprocServer32 key.

The default value of this key contains the path of the application that will be run. In the case of .Net assemblies, this is always mscoree.dll, which serves as a shim, managing the differences between .Net and COM. The other properties of this key tell mscoree.dll how to find the actual .Net assembly that should be treated as a COM component. This may (but not necessarily) include a codebase path to the assembly.



Last Updated ( Saturday, 26 July 2008 20:32 )
 

Google Tools

Gmail Docs Code Finance Maps Calendar