views:

111

answers:

5

I'm trying to debug some code that uses reflection to load plugins

Here's the debugging code and its output:

Type a = methodInfo.GetParameters()[0].ParameterType.BaseType;
Type b = typeof(MessageContext);
Debug.WriteLine(a.AssemblyQualifiedName);
Debug.WriteLine(b.AssemblyQualifiedName);
Debug.WriteLine(a.Equals(b));


OrtzIRC.Common.MessageContext, OrtzIRC.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
OrtzIRC.Common.MessageContext, OrtzIRC.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
False

I don't understand what would make these two types different?

A: 

This is how you should compare the types:

C# Object Type Comparison

I think your problem resides in the type hierarchy...

Leniel Macaferi
+3  A: 

This can happen if the two types are loaded from different versions of the assembly. .NET considers them different, unrelated types. Check

Debug.WriteLine (a.AssemblyQualifiedName) ;
Debug.WriteLine (b.AssemblyQualifiedName) ;
Yuriy Faktorovich
Both are identical, same version.
Brian Ortiz
Then it's probably assembly loader context: the `typeof()` assembly is loaded into the default context, but `Assembly.LoadFrom()` and friends load into the LoadFrom context. Again you get different types. The workaround is to check whether the assembly is already loaded into the appdomain before `LoadFrom()`'ing it.
Anton Tykhyy
*or* ensure that you load OrtzIRC.Common into the default context (`typeof(MessageContext)` should do) before you start loading plugins that refer to this assembly.
Anton Tykhyy
A: 

Try: Debug.Writeline(a.Equals(b));

Joel Coehoorn
Still returns false.
Brian Ortiz
A: 

Are a and b the same object reference?

Try:

Debug.WriteLine(typeof(a) == typeof(b));
dhirschl
I think you've misread his question, `a` and `b` are both of type `Type`. Your test is not useful for him.
Noon Silk
+3  A: 

The same class / type loaded by different app domains [.NET] or class loaders [Java] will not compare equal and are not assignable to/from each other directly.

You likely have two copies of the DLL containing that type - one loaded by the main program and one loaded by one of the Assembly.Load*(...) methods?

Try displaying / comparing the properties:
a.Assembly.Equals(b.Assembly)
and
a.Assembly.Location.Equals(b.Assembly.Location)

In general, you only want one copy of each DLL and have it loaded into a single app domain.

Jorgen Thelin
You're right, it was loading two copies of the same assembly. One of them was being copied to the plugins directory and so I guess the plugin was loading that one instead of the one already in the app domain. So I just deleted the assembly and turned off "Copy local" and it worked. Thanks!
Brian Ortiz
Great explanation! :D
Leniel Macaferi