views:

460

answers:

2

I'm trying to load an assembly without locking the file. These assemblies could be third party assemblies so we don't necessarily have access to the code and one or two of them make use of Assembly.Location to read files from their directory, files they might depend on.

I'm aware you can do this via Shadow Copying but it's a real pain getting it to work properly and several users on certain forums have recommended loading the assembly into a byte array and using the Assembly.Load(Byte[]) overload. This works great until one of those assemblies tries to access a file in its parent directory because Assembly.Location returns an empty string and Assembly.Codebase returns the location of the application loading the assembly.

Is there anything I can do to somehow set the Codebase or Location properties of the assembly I'm loading? In the MSDN documentation for Codebase and Location they're defined as overridable properties - does that mean I can override them from the hosting application?

+1  A: 

Can you use AppDomainSetup.ApplicationBase ? Or do you need to define that path for every assembly you load?

EDIT: using a filename is easy to define a codebase:

AssemblyName assemblyRef = new AssemblyName();
assemblyRef.CodeBase = assemblyFile;
Assembly assembly = Assembly.Load(assemblyRef);

Maybe you could use AppDomain.AssemblyLoad or Assembly.ModuleResolve events, but I doubt.

Rubens Farias
Each loaded assembly would be loaded from a different path, so each will need a different location or codebase property.
Andy E
The problem is that using the filename would lock the assembly dll and stop it from being able to be deleted (or more importantly, overwritten) by the filesystem.
Andy E
consider this article I created on CodeProject: http://www.codeproject.com/KB/WCF/generic_wcf_host.aspx ; that Console Hoster doesn't lock up your assemblies
Rubens Farias
A: 

use::

var assembly = Assembly.ReflectionOnlyLoad(System.IO.File.ReadAllBytes(yourFullfileNamePath));

But you would still have to do this in a different AppDomain.

Sentient