You may want to use this when, for example, you want to keep a few libraries with some business logic on a remote file server on the network and have the ability to easily update these libraries without sending their copies to all users of an application. Or Maybe you may want to share a few libraries between several applications on a computer to quickly update the libraries in one place, but you can not use GAC for some reason.
How to implement
Every time the .NET runtime cannot find the necessary library in an application directory or GAC it raises a special event - AssemblyResolve - of the Application object. A developer can subscribe to this event to implement custom logic.
The first step is to place the libraries in a special directory and make the path to this directory available to every application which is using shared libraries from this directory. The most obvious way is to store the path to the directory in the Windows Registry. For example:
"SharedPath"="C:\\Program Files\\My Shared Libraries"
The second step is to implement the AssemblyResolve event handler in every application that is using shared assemblies. It is important to add a handler for AssemblyResolve before any shared library will be used or you will get an Exception.
You can subscribe to the event in the handler of the Load event of the startup form or at the beginning of the Main procedure.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
AddHandler (AppDomain.CurrentDomain.AssemblyResolve), AddressOf CurrentDomain_AssemblyResolve
The handler of the AssemblyResolve event should find the path to the required assembly, check for the assembly existence and load the assembly via the LoadAssembly function.
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
string asmName = args.Name.Split(',');
string sharedPath = Registry.GetValue("HKEY_CURRENT_USER\\SimpleSharedLib",
if(sharedPath == String.Empty) throw(new Exception("Path to shared libraries not found."));
string asmPath = Path.Combine(sharedPath, asmName + ".dll");
if (!File.Exists(asmPath)) throw (new Exception("Assembly " + asmName + " not found."));
return Assembly.LoadFile(asmPath, Assembly.GetExecutingAssembly().Evidence);
Public Shared Function CurrentDomain_AssemblyResolve(ByVal sender As Object, _
ByVal args As ResolveEventArgs) As System.Reflection.Assembly
Dim asmName As String(), asmPath As String, sharedPath As String
asmName = args.Name.Split(",")
sharedPath = Registry.GetValue("HKEY_CURRENT_USER\\SimpleSharedLib", _
If sharedPath = String.Empty Then Throw (New Exception("Path to shared libraies not found."))
asmPath = Path.Combine(sharedPath, asmName(0) & ".dll")
If Not File.Exists(asmPath) Then Throw (New Exception("Assembly not found."))
Return Assembly.LoadFile(asmPath, Assembly.GetExecutingAssembly().Evidence)
This code gets path to the directory containing shared libraries, the name of the assembly that the runtime is looking for. If the assembly file exists, the code loads the assembly. It is noteworthy that the assembly is loaded with the same security settings as executing application because of the second parameter of Assembly.LoadFile function.
Avoiding access problems
There is a problem with the code shown above if it is necessary to update a shared assembly file during execution of at least one application using the assembly. This is because the runtime locks loaded assemblies. To avoid this you can read the assembly file to a byte array and use an overload of the Load method that accepts an array of bytes.
byte asm = File.ReadAllBytes(asmPath);
asm = File.ReadAllBytes(asmPath)
You can develop and test as usual – create a reference to the required assembly and work with the library as you usually do. The event handler will do its job when you place your application in the production environment where will be no shared libraries in the application directory and the AssemblyResolve event will be raised by the runtime every time it cannot find an assembly. A working example is attached to this article.