Problems with CreateInstance after dynamically loading Assembly

D

David Elliott

I am trying to load an assembly and execute a method from a class.
I have listed 3 parts to the code.
1) The Driver to load and execute
2) The Interface
3) The assembly

I have a valid referece to the assembly. When I try to create an instance
of the class, it returns a null value.

Any help would be appreciated.

As a side note, if someone created their own IPlugIn and was wanting to use
it in my application, Is there a way to acertain their class which is equivalent
to my MainEntry? At the time that they create their assembly, they wouldn't
necessarily know to name their class MainEntry.

Thanks,
Dave
(e-mail address removed)


===================================================
IPlugIn plugin = null;
Assembly assembly = null;

assembly = Assembly.LoadFrom(assemblyName);
plugin = (IPlugIn)assembly.CreateInstance("IPlugIn.MainEntry");

===================================================

namespace Plugin
{
/// <summary>
/// Summary description for IPlugIn.
/// </summary>
public interface IPlugIn
{
string PluginName{get;}
void ExecutePlugin();
}
}
===================================================
public class MainEntry : IPlugIn
{
private int m_pluginID = 1;
private string m_pluginName = "Plugin #1";


public string PluginName {get {return m_pluginName;}}
public int PluginID {get {return m_pluginID;} set {m_pluginID = value;}}

public void ExecutePlugin()
{
MessageBox.Show("ExecutePlugin has executed", "ExecutePlugin()");
}
}

===================================================
 
J

Jon Skeet

David Elliott said:
I am trying to load an assembly and execute a method from a class.
I have listed 3 parts to the code.
1) The Driver to load and execute
2) The Interface
3) The assembly

I have a valid referece to the assembly. When I try to create an instance
of the class, it returns a null value.

Any help would be appreciated.

You're using the wrong classname - in the code you've posted, the
classname is just MainEntry, but you're asking for IPlugIn.MainEntry.
As a side note, if someone created their own IPlugIn and was wanting to use
it in my application, Is there a way to acertain their class which is
equivalent to my MainEntry? At the time that they create their assembly,
they wouldn't necessarily know to name their class MainEntry.

What do you mean by "equivalent to"? You *can* tell whether or not a
type implements an interface, presumably IPlugIn in this case - that's
usually the best way to go.
 
D

David Elliott

I tried again with the change from IPlugIn.MainEntry to MainEntry. After executing the
plugin = (IPlugIn)assembly.CreateInstance("MainEntry");
the result was plugin = null.

As far as the second question. If I name my class MainEntry and you named yours MyEntry
how would I know in the application. The difference would be
assembly.CreateInstance("MainEntry")
assembly.CreateInstance("MyEntry")

Thanks,
Dave
 
J

Jon Skeet

David Elliott said:
I tried again with the change from IPlugIn.MainEntry to MainEntry.
After executing the
plugin = (IPlugIn)assembly.CreateInstance("MainEntry");
the result was plugin = null.

Could you post a short but complete program that demonstrates this
then? (It's easiest to make it a console app rather than a GUI one.)

Here's a short but complete program based on your code which *does*
work:

Test.cs:
using System;
using System.Reflection;
using Plugin;

public class Test
{
static void Main()
{
IPlugIn plugin = null;
Assembly assembly = null;

assembly = Assembly.LoadFrom("mainentry.dll");
plugin = (IPlugIn)assembly.CreateInstance("MainEntry");
Console.WriteLine (plugin);
plugin.ExecutePlugin();
}
}

IPlugin.cs:
namespace Plugin
{
/// <summary>
/// Summary description for IPlugIn.
/// </summary>
public interface IPlugIn
{
string PluginName{get;}
void ExecutePlugin();
}
}

MainEntry.cs:
using Plugin;
using System;

public class MainEntry : IPlugIn
{
public string PluginName {get {return "hello";}}

public void ExecutePlugin()
{
Console.WriteLine("ExecutePlugin has executed");
}
}

Compiling:
csc /target:library /out:iplugin.dll IPlugin.cs
csc /r:iplugin.dll Test.cs
csc /target:library /out:mainentry.dll /r:iplugin.dll MainEntry.cs

Output:
MainEntry
ExecutePlugin has executed
As far as the second question. If I name my class MainEntry and
you named yours MyEntry how would I know in the application.
The difference would be
assembly.CreateInstance("MainEntry")
assembly.CreateInstance("MyEntry")

You would use assembly.GetTypes and check each type in the assembly to
see whether or not it implemented the interface.
 
D

David Elliott

I started to do this before you asked for a new project. Cut and pasted code and poof
everything magically worked. I copied the source in my original project, deleted the file,
created a new one with the same code and works now.

Don't know what happened.

Thanks for all your help.
Dave
 

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