views:

36

answers:

2

I have an interesting challenge that I'm wondering if anyone here can give me some direction.

I'm writing a .Net windows forms application that runs on a network and uses an SQL Server to save and pull data.

I want to offer a mini "plugin" API, where developers can build their own assemblies and implement a specific interface (IDataManipulate). These assemblies then can be used by my application to call the interface functions and do something.

I can create assemblies using my API, copy the file to a folder in my local hard drive and configure my application to use Reflection to call a specific function from the implemented interface (IDataManipulate.Execute).


The problem:

Since the application will be installed in multiple workstations in the network, is impossible to copy the plugin dlls the users will create to each machine.

Solutions I tried:

Solution 1
Copy the API dll to a network share.

Problem:
Requires AllowPartiallyTrustedCallersAttribute, which requires .Net singing, which I can't force from my users.

Solution 2 (preferred)
Serialize the dll object, save it to the database, deserialize it and call IDataManipulate.Execute.

Problem:
After deserialization, I try cast it to a IDataManipulate object but returns an error looking for the actual dll file.

Solution 3
Save the dll bytes as byte[] to the database and recreate the dll at the local PC every time the user starts my application.

Problem:
Dll may have dependencies, which I don't know if I can detect.


Any suggestions will be greatly appreciated.

Thanks

+1  A: 

I've done "Solution 3" before. We stored the DLL files in a database table with a "last modified" timestamp. That way you could tell if the local file needed to be updated when the app started.

You can call Assembly.GetReferencedAssemblies to get the list of dependencies from an assembly. This assumes that the plugin DLL doesn't use reflection to dynamically load a random assembly, but that should be acceptable.

Another option is to use the AppDomain.AssemblyResolve event. Instead of downloading all of the plugin DLLs on startup, this event would let you only download the DLLs that are actually needed.

David
@David, had you try to implement Solution #2 ? Because it will ideal if I can avoid the DLL creation at runtime.
Stefanos Tses
If you use the AssemblyResolve event, you can return an assembly object that was loaded from any stream object. That would let you load it from the database and never have to save it to disk first.
David
A: 

You could copy them to a network share, then when your app starts up or you need to load the plugins you could compare the date against the one you hold locally, if it is newer then copy it over locally..

Richard Friend