Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET: Unable to cast object to interface it implements

I have a class (TabControlH60) that both inherits from a base class (UserControl) and implements an interface (IFrameworkClient). I instantiate the object using the .NET Activator class. With the returned instance, I can cast to the UserControl base class, but not to the interface. The exception I get is below the code snipet. How do I cast to the interface?

object obj = Activator.CreateInstance(objType);
Type[] interfaces = obj.GetType().GetInterfaces(); // contains IFrameworkClient

m_Client = (UserControl)obj;                 // base class cast works
IFrameworkClient fc = (IFrameworkClient)obj; // interface cast fails

// Note: The (IFrameworkClient)obj cast works fine in the debugger Watch window.
{"Unable to cast object of type 'FPG.H60.AFF.TabControlH60' to type 
    'FPG.AFF.Interfaces.IFrameworkClient'."}
like image 653
user193327 Avatar asked Oct 20 '09 19:10

user193327


2 Answers

I hat the same problems with a library of mine providing "plugin"-functionality... I got it finally working...

Here was my problem: I had one main assembly using plugins, one assembly with the plugin (Plugin.dll) AND (important) another assembly providing the plugin-functionality (Library.dll).

The Plugin.dll referenced the main assembly (in order to be able to extend it) and the Library.dll with the plugin-func. - it's binaries got to a directory "./Plugins" relative to the main assembly.

The main assembly also referenced the plugin-func. assembly in order to use the "PluginManager" is wrote. This "PluginManager" gets a path and loads all *.dll files via reflection in order to analyze if there is a "IPlugin"-interface (which comes from Library.dll too).

Everytime I called the PluginManager to load the plugins it could not cast them to "IPlugin" although they implemented it.

I nearly got mad - but then I found out the whole problem. By compiling the plugin there was not only the "Plugin.dll" but the "Library.dll" written to the "./Plugins" directory. By accidentally loading the "Library.dll" every time with my PluginManager I now had two types of "IPlugin" - one in the actual "Library.dll" that is used from the main assembly and one that was loaded through my PluginManager - and those were incompatible!

Attention - if you just do not load "./Plugins/Library.dll" you nevertheless encounter the problem - because if you load "Plugin.dll" which references "Library.dll" then it just uses the one in the same directory... TILT...!! My PluginManager now just deletes "Library.dll" where it find it.

The clue is: Be sure that you do not access two assemblies in different contexts!

like image 131
Andi Avatar answered Oct 29 '22 07:10

Andi


The most likely cause here is that IFrameworkClient is from a different assembly in the two cases, and is thus a different .NET type. Even if it is the same code, it can be a different type.

Check the AssemblyQualifiedName. Note also that if you are loading this assembly with reflection you can get a different type even with the same AssemblyQualifiedName, thanks to the load-context.

like image 13
Marc Gravell Avatar answered Oct 29 '22 08:10

Marc Gravell