Checking for implementation of an interface

G

Guest

I have an application that accepts plugins. It allows the user to choose
which plugins they want to run from a list of available plugins. My problem
is that I need to build that list of plugins by checking the assemblies in
the plugins folder to see if they implement the plugin interface. If I load
each assembly and check it, then I have all those assemblies in memory until
the application gets shutdown, even though the user may only want to use a
few of them.

My idea was to load them all into a separate appdomain to check them and
build my list, and then unload that domain. Then I could just load the
plugins that the user chooses. My problem is that I don't know how to check
the assembly to see if it implements the plugin interface once its loaded
into the separate appdomain. Can anyone point me to an article on this, or
some sample code? Thanks!
 
J

Jon Skeet [C# MVP]

Bagger said:
I have an application that accepts plugins. It allows the user to choose
which plugins they want to run from a list of available plugins. My problem
is that I need to build that list of plugins by checking the assemblies in
the plugins folder to see if they implement the plugin interface. If I load
each assembly and check it, then I have all those assemblies in memory until
the application gets shutdown, even though the user may only want to use a
few of them.

My idea was to load them all into a separate appdomain to check them and
build my list, and then unload that domain. Then I could just load the
plugins that the user chooses. My problem is that I don't know how to check
the assembly to see if it implements the plugin interface once its loaded
into the separate appdomain. Can anyone point me to an article on this, or
some sample code? Thanks!

I suspect the easiest way to find some sample code is to download the
NUnit sources - NUnit *definitely* loads the test assemblies into a
different AppDomain, and then uses them.

I suspect you'll need to load one of your own assemblies into the new
AppDomain as well, and ask that to do the searching for you. That way
you don't need to worry nearly so much about marshalling :)
 
G

Guest

Jon Skeet said:
I suspect the easiest way to find some sample code is to download the
NUnit sources - NUnit *definitely* loads the test assemblies into a
different AppDomain, and then uses them.

I suspect you'll need to load one of your own assemblies into the new
AppDomain as well, and ask that to do the searching for you. That way
you don't need to worry nearly so much about marshalling :)

Thanks for the help :) I've been hunting around for info on this, and I've
read in a couple places that I would need to use a proxy. Is that what you
were referring to when you said I'd need to load one of my own assemblies
into the new appdomain? This is my first foray into this kind of stuff, so
I'm trying to learn as quick as possible :)
 
M

mdb

I have an application that accepts plugins. It allows the user to
choose which plugins they want to run from a list of available
plugins. My problem is that I need to build that list of plugins by
checking the assemblies in the plugins folder to see if they implement
the plugin interface. If I load each assembly and check it, then I
have all those assemblies in memory until the application gets
shutdown, even though the user may only want to use a few of them.

You can prevent that by loading the assembly's raw byte[] data instead of
using Assembly.LoadFrom()... in other words,

byte[] aData;
FileStream fs = File.OpenRead(...);
aData = new byte[fs.Length];
fs.Read(aData, 0, aData.Length);
fs.Close();
Assembly a = Assembly.Load(aData);

(this is from memory so it might not exactly correct.)
My idea was to load them all into a separate appdomain to check them
and build my list, and then unload that domain. Then I could just
load the plugins that the user chooses. My problem is that I don't
know how to check the assembly to see if it implements the plugin
interface once its loaded into the separate appdomain. Can anyone
point me to an article on this, or some sample code? Thanks!

I'm not sure if this is the most efficient way to do it, but it works...
Load your assembly into 'Assembly a'...

Assembly a;
Type[] t = a.GetTypes();
for(int i=0; i<t.Length; i++)
{
object o = null;
IPlugin PluginObj = null;
Type[] interfaces = t.GetInterfaces();
for(int j=0; j<interfaces.Length; j++)
{
if (interfaces[j] == typeof(IPlugin))
{
try
{
o = a.CreateInstance(t.FullName);
PluginObj = (IPlugin)o;
....

Also, if you load the Assembly as in your first question and you want to
use it as a plugin... I'm not sure how GarbageCollection would handle
things after you're finished with Assembly a, so you might need to either
(a) Keep a reference to the 'Assembly a' variable, or (b) just reload the
assembly again with LoadFrom(...).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top