Problem statement: Implement a plug-in system that allows the associated assemblies to be overwritten (avoid file locking). In .Net, specific assemblies may not be unloaded, only entire AppDomains may be unloaded.
I'm posting this because when I was trying to solve the problem, every solution made reference to using multiple AppDomains. Multiple AppDomains are very hard to implement correctly, even when architected at the start of a project.
Also, AppDomains didn't work for me because I needed to transfer Type across domains as a setting for Speech Server worfklow's InvokeWorkflow activity. Unfortunately, sending a type across domains causes the assembly to be injected into the local AppDomain.
Also, this is relevant to IIS. IIS has a Shadow Copy setting that allows an executing assembly to be overwritten while its loaded into memory. The problem is that (at least under XP, didnt test on production 2003 servers) when you programmatically load an assembly, the shadow copy doesnt work (because you are loading the DLL, not IIS).
It is now superseded by Windows Communication Foundation (WCF), which is part of the . NET Framework 3.0. Like its family members and similar technologies such as Common Object Request Broker Architecture (CORBA) and Java's remote method invocation (RMI), .
NET Framework libraries aren't available for use with . NET 5+ (and . NET Core), such as app domains, remoting, and code access security (CAS). If your libraries rely on one or more of the technologies listed on this page, consider the alternative approaches mentioned.
The AppDomain class implements a set of events that enable applications to respond when an assembly is loaded, when an application domain will be unloaded, or when an unhandled exception is thrown.
An application domain forms an isolation boundary for security, versioning, reliability, and unloading of managed code. A thread is the operating system construct used by the common language runtime to execute code.
The following code assumes you know the FullName of an assembly.
Assembly assembly = null;
foreach(Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
if (loadedAssembly.FullName == "foobar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
assembly = loadedAssembly;
if(assembly == null)
{
byte[] studybin = System.IO.File.ReadAllBytes(@"C:\pathToAssembly\foobar.dll");
assembly = Assembly.Load(studybin);
}
Note that if you are trying to find a specific assembly in a directory, you can run 'System.Reflection.AssemblyName.GetAssemblyName(path);' to see if the FullName matches what you are looking for. 'GetAssemblyName(path)' does NOT inject the assembly into your current AppDomain.
Also note that this solution is not appropriate for applications that must only rarely restart AND the assemblies change with high frequency. Every time an assembly is loaded, the memory footprint of you application will grow. There is no method to unload an assembly, thus the only option to shrink memory usage is to restart the application. However, this limitation is often preferable to the large performance, memory, and code complexity overhead of using multiple app domains. This limitation is also unavoidable if you wish to work with Type
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With