Application with plugin architecture

  • Thread starter Thread starter Jer
  • Start date Start date
J

Jer

Hi all,

I am trying to get plugins working in my application.

I am using the approach of writing an interface and then implementing that
interface in each plugin. I would like to be able to just have a plugin
directory, and on program launch scan that directory, load each dll in it
and decide whether it's a valid plugin dll.

So far I've gotten the directory scan fine, loaded each assembly in turn,
but when I try to cast an object that implemements the interface I get an
invalid cast exception. Any ideas?

Below are two different attempts at this... comments would be greatly
appreciated as I'm thinking I don't know how to read documentation at this
point. :-)

**** Attempt 1 *****
foreach (string file in pluginDlls)

{

try

{

System.Reflection.Assembly pluginAssembly = Assembly.LoadFrom(file);

Type[] typesInAssembly = pluginAssembly.GetTypes();

foreach (Type type in typesInAssembly)

{

if (type is Interfaces.IDBConnector)

{

// This is a valid DBConnector plugin!

// Grab information and load it.

Interfaces.IDBConnector connector =
(Interfaces.IDBConnector)pluginAssembly.CreateInstance(type.FullName);

this.availablePlugins.Add(connector);

// Do more now



**** Attempt 2 ******

System.Reflection.Assembly pluginAssembly = Assembly.LoadFrom(file);

Type[] typesInAssembly = pluginAssembly.GetTypes();

foreach (Type type in typesInAssembly)

{

object o = pluginAssembly.CreateInstance(type.FullName);

Interfaces.IDBConnector connector = null;

try

{

connector = (Interfaces.IDBConnector)o;

}

catch (InvalidCastException)

{

connector = null;

}


if (connector != null)

{

// This is a valid DBConnector plugin!

// Grab information and load it.

Now, Attempt 1 NEVER finds any types that match the line "if (type is
Interfaces.IDBConnector)" and Attempt 2 always throws an
InvalidCastException.

I look forward to hearing your ideas...



Jeremy Wiebe

jeremywiebe at mailblocks dot com
 
Hi Jer,

Please try replacing the line:

"if (type is Interfaces.IDBConnector)"

with the following line:

if(type is typeof(Interfaces.IDBConnector))
{
}

Hopefully that should sort out things.

Regards,
Aravind C
 
Thanks for the response.

Unfortunately, that doesn't appear to be valid C# syntax. I am using Visual
Studio .NET 2002 and that specific line of code results in a "Type expected"
syntax error.

This is an example of something that I have never seen a good explanation
for in any documentation I've read. That is... what is the best way to
check if an object supports a given interface?

is it: if (myObject is IMyInterface) {...}
or: if (myObject.GetType() == typeof(IMyInterface) {...}
or: if (???

Jeremy Wiebe

jeremywiebe at mailblocks dot com

Aravind C said:
Hi Jer,

Please try replacing the line:

"if (type is Interfaces.IDBConnector)"

with the following line:

if(type is typeof(Interfaces.IDBConnector))
{
}

Hopefully that should sort out things.

Regards,
Aravind C



Jer said:
Hi all,

I am trying to get plugins working in my application.

I am using the approach of writing an interface and then implementing that
interface in each plugin. I would like to be able to just have a plugin
directory, and on program launch scan that directory, load each dll in it
and decide whether it's a valid plugin dll.

So far I've gotten the directory scan fine, loaded each assembly in turn,
but when I try to cast an object that implemements the interface I get an
invalid cast exception. Any ideas?

Below are two different attempts at this... comments would be greatly
appreciated as I'm thinking I don't know how to read documentation at this
point. :-)

**** Attempt 1 *****
foreach (string file in pluginDlls)

{

try

{

System.Reflection.Assembly pluginAssembly = Assembly.LoadFrom(file);

Type[] typesInAssembly = pluginAssembly.GetTypes();

foreach (Type type in typesInAssembly)

{

if (type is Interfaces.IDBConnector)

{

// This is a valid DBConnector plugin!

// Grab information and load it.

Interfaces.IDBConnector connector =
(Interfaces.IDBConnector)pluginAssembly.CreateInstance(type.FullName);

this.availablePlugins.Add(connector);

// Do more now



**** Attempt 2 ******

System.Reflection.Assembly pluginAssembly = Assembly.LoadFrom(file);

Type[] typesInAssembly = pluginAssembly.GetTypes();

foreach (Type type in typesInAssembly)

{

object o = pluginAssembly.CreateInstance(type.FullName);

Interfaces.IDBConnector connector = null;

try

{

connector = (Interfaces.IDBConnector)o;

}

catch (InvalidCastException)

{

connector = null;

}


if (connector != null)

{

// This is a valid DBConnector plugin!

// Grab information and load it.

Now, Attempt 1 NEVER finds any types that match the line "if (type is
Interfaces.IDBConnector)" and Attempt 2 always throws an
InvalidCastException.

I look forward to hearing your ideas...



Jeremy Wiebe

jeremywiebe at mailblocks dot com
 
Hi Jeremy,
pls, try this:

foreach(Type type in typesInAssembly)
{
Type my_interface =
type.GetInterface("IDBConnector");
if (my_interface != null) //we've got it
.....

Or, if this not works, try to iterate type.GetInterfaces() to see what
exactly is stored for that class, and after that, change the string in
GetInterface("").

Please, post the results

Sunny
 
Forgot:

if (type is Interfaces.IDBConnector)

is not working, becouse "is" checksh the the type of first parameter,
i.e. here your variable type is Type, and Type is != IDBConnector, thats
why it shows false all the time.

Sunny
 
Back
Top