Reputation: 1735
This might look like a duplicate but it isn't, its actually a different question!
The scenario is this: I have a web app that iterates through all the dlls dynamically loaded into the system to access a method from it and get data. These dlls are added by users from the website.
Pseudo code would be something like this:
pulic void GetNews(){
foreach(var i in ListOfDllPaths){
Assembly dll = Assembly.Load( File.ReadAllBytes(i));
SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
if.DoMethod();
}
}
Now the problem is that on each call to GetNews() the same dlls are loaded all over again, having the same dlls loaded multiple times. I could use Assembly.LoadFrom or LoadFile, to avoid this problem, but then i would lock the file which i don't want to, because i want to be able to delete it.
Another option would be to use a new app domain to load them, call the method and unload them, but then i would also have to load the interface dll in that domain which i really don't know the path to it in the web app. Not to mention moving data from one app domain to the other is a pain and too hard to accomplish.
One third option would be to use a shadow copy, but then i wouldn't be able to delete the shadow copy same results.
Options? Basically what i need is, load the dll, use it, unload it, move on.
Upvotes: 0
Views: 874
Reputation: 7452
If you need to really unload it you have no choice but to use a seperate app domain (see How to unload an assembly from the primary AppDomain? for example)
If you need only load each assembly once, but don't care about unloading old ones you need to manage keeping track of which assemblies are loaded yourself. Any easy way to do this would be to take a hash of each file before you load it. Something Like:
Dictonary<string,bool> loadedAssemblies = new Dictonary<string,bool>();
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
var hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
if(loadedAssemblies.ContainsKey(hash)) continue;
loadedAssemblies[hash] = true;
Assembly dll = Assembly.Load( File.ReadAllBytes(i));
SomeInterface if = CreateInstance(dll); //This methods does all the validation and such
if.DoMethod();
}
If you want to version items another approach would be to add some metadata to your interface.
Upvotes: 3