Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I am trying to use CreateInstance and I keep getting an <undefined value> returned from CreateInstance. It doesn't through an exception though and I thought if it didn't find the interface that it was supposed to do that. So I guess my question is how do I make sure that I am passing createInstance the correct interface name.

 

public object CreateInstance(string dllname,string strInterface)
{
  Assembly objDLL;
  object objPlugin;
  try
  {
//load dll
//C:\Projects\PrintRoutineXP\bin\PrintRoutineXP.dll
objDLL = Assembly.LoadFrom(dllname);
//create and return class instance
objPlugin = objDLL.CreateInstance(strInterface);
return objPlugin;
  }
  catch(Exception e)
  {
myLog.Log(string.Format("Error trying to create Instance of a      plugin. Name: {0} Error: {1}",dllname,e.Message));
return null;
  }
}

Posted
You cannot create an instance of an interface - only classes; in your case a class that implements the interface would be expected.

 

 

So if my code is setup like below would I pass

createInstance("testParser.TestParser");

namespace testParser
{
/// <summary>
/// Summary description for Class1.
/// </summary>
public class TestParser:Interface.IParser
{
            }
            .
            .
            .
}

Posted

I had the above code working, but it seems that I am doing something wrong and I'm not sure what the best way to debug it is.

 

I'm using Assembly.loadfrom and createInstance and am getting an instance of my test class back in object form which I return to another function where I'm trying to cast it to my Interface name with no luck it returns a undefined value.

 

The dll that is being loaded uses Interface.IParser as one of its base classes, but when I try to make it return as Interface.IParser objPlugin = <undefined value>.

 

If I change objPlugin to an object I get the instance of my testParser class, so its loading the dll it just can't find a way to cast it to Interface.IParser... how can I find out why that is happening

 

Interface.IParser objPlugin;
Interface.PluginServices parserService = new Interface.PluginServices();
objPlugin = parsserService.CreateInstance(_parser) as Interface.IParser;
return objPlugin.ParserName;

  • Administrators
Posted

If you step through the code does the CreateInstance method inside the DLL work every step of the way? If not which line within the DLL fails (probably on assembly.CreateInstance).

What is the value of _parser when you run the above code? Does it contain the name of a valid class?

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Posted

Below is the code for my CreateInstance function so _parse is a struct that contains the full location and name of the dll to load as well as the class name. This code functions correctly objPlugin just before return is = to an instance of the class contained in the dll{testParser.TestParser}. When I try to cast it to Interface.IPlugin in the function that takes the return from below it ends up being undefined

 

 

 

public object CreateInstance(AvailablePlugin Plugin)

{

Assembly objDLL;

object objPlugin;

try

{

//load dll

objDLL = Assembly.LoadFrom(Plugin.AssemblyPath);

//create and return class instance

objPlugin = objDLL.CreateInstance(Plugin.ClassName);

return objPlugin;

}

catch(Exception e)

{

myLog.Log(string.Format("Error trying to create Instance of a plugin. Name: {0} Error: {1}",Plugin.ClassName,e.Message));

return null;

}

}

Posted

Ok this makes no sense to me now. If you look at the code below you see where I was playing around and use myP to create and instance of testParser.dll... which works it returns the instance of the class contained in the dll cast to Interface.IParser.

 

And if you look further down in the code you see the call to parserFuncs.getParserName(parsers));

 

This calls the code that I have been describing earlier and it works too now, but if I comment out the line:

 

Interface.IParser mytest = myP.CreateInstance(pars) as Interface.IParser;

 

then the second call to CreateInstance that is contained in parserFuncs.getParserName(parsers) fails...

this makes no sense. why calling my CreateInstance earlier in the code works and makes the second call work too. They both create instances of the exact same class and call the same method within that class.

 

 

private void Form1_Load(object sender, System.EventArgs e)
{
DirectoryInfo myDirInfo = new DirectoryInfo (Application.StartupPath);
DirectoryInfo myparentDirInfo = myDirInfo.Parent;
parserFuncs = new Parser();
Interface.PluginServices myP = new Interface.PluginServices();
Interface.PluginServices.AvailablePlugin pars = new Interface.PluginServices.AvailablePlugin();
pars.AssemblyPath = "C:\\Projects\\testParser\\bin\\Debug\\testParser.dll";
pars.ClassName = "testParser.TestParser";
Interface.IParser mytest = myP.CreateInstance(pars) as Interface.IParser;
.
            .
            .
if(parserPath.Text != "")
{
	parsers = parserFuncs.getListofParsers(MakeValidPath(parserPath.Text));
	if (parsers != null)
	{
	        for(int i = 0; i< parsers.Length; i++)
		{
		parserComboBox.Items.Add(parserFuncs.getParserName(parsers[i]));
		}
	}
}
		
}

 

getParserName is

try
{
Interface.IParser objPlugin;
//object ob;
Interface.PluginServices parserService = new Interface.PluginServices();
//ob = parserService.CreateInstance(_parser);
objPlugin = parserService.CreateInstance(_parser) as Interface.IParser;
//objPlugin = ob as Interface.IParser;
//return ob.ToString();
return objPlugin.ParserName;
			
}
catch(Exception e)
{
myLog.Log(string.Format("Error getting parser name: {0}",e.Message));
return "";
}

Posted
Does the class objPlugin is set to implement the IPlugin interface?

Also wher eis the IPlugin interface defined (in a shared library etc)?

 

the Interface is defined in a shared library

 

The class I'm trying to implement is defined below where Interface.IParser is my interface that I have defined.

 

namespace testParser

{

public TestParser:genParser,Interface.IParser

{

}

}

Posted
I'm trying to look at what could be different here... the form_load is happening in one project and the getParserName in another(same solution though), but the references to the interface are(should) be the same because the Interface project is in my current solution and I'm referencing the project directly rather than just the created dll
Posted (edited)

Here is my code paired down... I hope you can make something out of it. I created a new solution so if you unzip the files to the desktop it should work.

 

If you run as is all it will do is pop up a message box that says TestParser. if you comment out the 9th line in the form load of testpluginform then the whole thing doesn't work... the problem is happening when I try to cast the object being returned to Interface.IParser...

 

Thank you very much

testparser.zip

Edited by PlausiblyDamp
Posted

any luck with this. It still doesn't make any sense. Any help with ideas about how to try to debug it or directions to take would be appreciated.

 

Thanks for your help

Posted
Only had time for a quick look - strange how it seems to work one way but not the other...

I could only see one declaration for the testParser class - it isn't declared anywhere else is it?

 

Nope that is it... just that one place.

  • 1 month later...
Posted

still having problems with this. It seems the problem is is not that createInstance fails but that I am returning the instance created and it is not able to be cast from testParser.TestParser which implements Interface.IParser to Interface.IParser.

 

objPlugin = parserService.CreateInstance(_parser) as Interface.IParser;

 

like I said abouve parserService.CreateInstance(_parser) returns and instance of testParser.TestParser which I'm then trying to cast to Interface.IParser. it says this cast is invalid, but I don't know why because testParser.TestParser implements Interface.IParser.

 

Any Help will be appreciated.

 

Thanks

  • 3 weeks later...
Posted

Well after a long time of looking around and just plain looking confused. This article explains the problem I was having.

 

http://www.gotdotnet.com/team/clr/LoadFromIsolation.aspx

 

Essentially what it was is that I referenced my Interface class at Design time and then I loaded my plugin dll at runtime from a different directory well the CLR differentiates between the two types of references especially since the one at run time was from a different directory then the exe and the statically referenced dll so they were seen as not being the same type even though they were based on the same class...

 

Assembly a = Assembly.LoadFrom(c:\\temp\\Regcode.dll); 

Object o = a.CreateInstance(Regcode.UtilClass);



Regcode.UtilClass x = (Regcode.UtilClass)o; //FAIL!



As you can infer from this cast failure, the CLR considers the two instances of Regcode.UtilClass to be completely different types. 

 

So to fix this I had to move the plugin to the same folder as the exe so that the CLR will know they are the same base class... So that is all for my poor explanation... The article explains it pretty well.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...