Assembly.CodeBase vs. Assembly.Location

The CodeBase is a URL to the place where the file was found, while the Location is the path from where it was actually loaded. For example, if the assembly was downloaded from the internet, its CodeBase may start with “http://”, but its Location may start with “C:\”. If the file was shadow copied, the…

7

Determining an Image’s CLR Version

To get it programmatically, from managed code, use Assembly.ImageRuntimeVersion. From unmanaged, use mscoree.dll’s GetFileVersion(). (From the command line, starting in v2.0, ildasm.exe will show it if you double-click on “MANIFEST” and look for “Metadata version”.) Those will give you the CLR version that the image claims it wants. By default, it’s the version that the…

11

AppDomain.Load()

AppDomain.Load() is only meant to be called on AppDomain.CurrentDomain. (It’s meant for interop callers only. They need a non-static method, and Assembly.Load() is static.) If you call it on a different AppDomain, if the assembly successfully loads in the target appdomain, remoting will then try to load it in the calling appdomain, potentially causing a…

8

Switching to the Load Context

So, after checking out the binding context options, you’ve decided to switch your app to use the Load context. Now, you just need to figure out how to do it. Maybe it will be as simple as using Assembly.Load(assemblyDisplayName) instead of Load(byte[]), etc.  That will work if the assembly is available in the GAC, the…

14

Executing Code in Another AppDomain

The easiest way to run code in another appdomain is to execute an assembly entrypoint using AppDomain.ExecuteAssembly() or (starting in v2.0) AppDomain.ExecuteAssemblyByName(). If you want to execute a method other than an assembly entrypoint, call AppDomain.CreateInstance() on a type which extends MarshalByRefObject. Then, call a method on that type which does the Assembly.Load() or whatever…

46

App.Config Files

By default, the application configuration file of the default appdomain (and other appdomains for v1.1 and later) is in the process exe’s directory and named the same as the process exe + “.config”. This is true even if that exe is unmanaged. Also, note that a web.config file is an app.config – ASP.NET sets that as…

37

Avoid Partial Binds

A partial bind is when only part of the assembly display name is given when loading an assembly. Assembly.LoadWithPartialName() also uses partial binding. First, it calls Assembly.Load(). But, if that fails to find the assembly, it will return the latest version of that assembly available in the GAC. But, avoid using any form of partial…

13

Using Type.GetType(typeName)

If no assembly is specified, Type.GetType() will only look in the calling assembly and then mscorlib.dll for the type. For it to look in any other assembly, you need to give the Type.AssemblyQualifiedName for the type. For example: Type.GetType(“System.Uri, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”); This is because part of the type identity is its assembly. We…

5

When to Change File/Assembly Versions

First of all, file versions and assembly versions need not coincide with each other. I recommend that file versions change with each build. But, don’t change assembly versions with each build just so that you can tell the difference between two versions of the same file; use the file version for that. Deciding when to…

28

Choosing a Binding Context

There are three ‘contexts’ for assembly binding: Load context In general, if the assembly was found by probing in the GAC, a host assembly store (if hosted), or the ApplicationBase / PrivateBinPaths of the AppDomain, the assembly will be loaded in the Load context. LoadFrom context In general, if the user provided Fusion a path…

41