Download the assembly without a lock file and save the correct binding context

I compare a formidable riddle. Here is my situation:

I am creating an application with a plugin. There is a base class of the plugin, which all plugins should be distributed. Inside the same assembly, I have a helper class that will serialize and deserialize the classes. This is a general class, and has been used everywhere. The structure looks like this:

MyApp.dll |_ App.cs |_ HelperCollection.cs |_ PluginBase.cs MyPlugin.dll |_MyPlugin.cs (this extends PluginBase) |_Foo.cs 

Problem

My problem is with downloading and locking assembly files. The requirement of the application is that plugins can be overwritten at any time. If so, they need to be reloaded. It seems like the best way to load the assembly so that it is not blocked (that is, I can overwrite it or demolish it while the application is still running):

 byte[] readAllBytes = File.ReadAllBytes("MyPlugin.dll"); Assembly assembly = Assembly.Load(readAllBytes); 

Downloading the plugin assembly is just fine, no problem. I get an exception when, from within MyPlugin.cs, which is in the plugin assembly, I tried to use HelperCollection for deserialization. An example might be something like this:

 // HelperCollection uses XmlSerializer under the covers List<Foo> settingCollection = HelperCollection<Foo>.Deserialize("mysettings.xml"); 

It explodes and throws an InvalidCastException , saying that it is "Unable to cast object of type 'List[Foo]' to 'List[Foo]'" . After much research, I finally found why . It is loaded into the LoadNeither context context .

When Foo loaded (from MyPlugin.dll) in the context of the LoadNeither binding, while the assembly containing the type conversion type (in my case MyApp.dll) is loaded into the default context. Therefore, although they have the same name, they are not considered the same type. This does this because I am using Assembly.Load(byte[]) .

Questions

How can I get around this? How can I,

  • Download the assembly, not lock the file, and
  • Provide the correct binding context so that I can create objects that are in the loaded assembly.

Sorry for the text wall, just wanted to get all the necessary information.

+7
source share
2 answers

Have you tried shadow copying ?

When you use shadow copy, .NET copies the assembly to the temp directory and loads it there (so this is a temporary file that is locked, not the original assembly), but all the binding rules are based on the original location of the file.

+6
source

Just an idea from the head:

How about having a plugin directory in which users can reset their plugins. Then in your application, you track this folder and copy the assemblies to the trash or something else. Then you load them in a โ€œnormalโ€ way that can block them.

When a user throws new plugins, you kill the plugin application domain and reboot it.

Just an idea.

+2
source

All Articles