16

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

Here's the debugging code:

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

And here is its output:

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?

Steven
  • 166,672
  • 24
  • 332
  • 435
Brian Ortiz
  • 1,821
  • 1
  • 20
  • 47

4 Answers4

21

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.

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Jorgen Thelin
  • 1,066
  • 9
  • 23
  • 2
    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 Sep 02 '10 at 17:32
  • I have a similar (if not the same) issue. I noticed that despite being in different app domains, `Assembly.Load*` functions succeed in checking type equality but `Assembly.ReflectionOnlyLoad*` functions fail. I'd appreciate if you could check out my question: http://stackoverflow.com/q/40292593/975724 – Nicholas Miller Oct 28 '16 at 14:27
  • 1
    You helped me find the problem. My plugin has a type loaded from a plugin directory. I am comparing it to a type from the same dll loaded from Temporary ASP.NET Files. I don't know how to solve this yet, though. I need make the Temporary ASP.NET Files version go away. – Rhyous Feb 25 '17 at 01:03
3

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) ;
Anton Tykhyy
  • 19,370
  • 5
  • 54
  • 56
Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
  • Both are identical, same version. – Brian Ortiz Sep 02 '10 at 02:20
  • 1
    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 Sep 02 '10 at 02:30
  • *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 Sep 02 '10 at 02:39
0

This is how you should compare the types:

C# Object Type Comparison

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

Community
  • 1
  • 1
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
0

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

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794