TL;DR
I had two separate copies of my interface. See this answer on the duplicate, or my update at the bottom of this question for a breakdown of the cause.
Summary
I'm loading types from assemblies using reflection:
foreach (string assemblyPath in assemblyPaths) {
Assembly assembly = Assembly.LoadFrom(assemblyPath);
if (assembly.GetTypes().Any(a => typeof(IChannel).IsAssignableFrom(a))) {
DoSomethingCool();
}
}
When I debug this code, I stop at the logical evaluation with a breakpoint, and check the answer in the immediate window, which evaluates to true
:
When I continue execution of my code, the block for the if
statement never executes, which leads me to assume that it evaluates to false
when that line executes. However, I think something wonky is going on that I'm just not seeing.
- I've tried restarting Visual Studio and my computer, just-in-case it was a software issue.
- I've tried reversing the logic to
a.IsAssignableFrom(typeof(IChannel))
1. - I've also reviewed the results of
.GetTypes()
and the type I'm looking for is there. - I performed the same check, on the type I'm looking for (
.GetTypes()[0]
), and it evaluated totrue
as expected.
1: This evaluates to false
in the immediate window and doesn't enter the block, as I'd expect.
Question
What are other reasons that could cause this inconsistency while debugging?
Answer
The cause of my issue was the fact that IChannel
was declared in a library that the executing assembly contained a reference to, but the loaded assembly also contained a reference to that assembly. However, the loaded assembly had it's own local copy of the library containing the definition for IChannel
.
I eventually found the answer, through this question, to which this answer, was the most helpful (in my case), particularly this excerpt:
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!
I'm leaving this question up because finding this answer would've been a much faster process if there was a result on the web for my question title. I was actually grasping at straws and found the question that answered mine through some additional steps:
- I changed my
.Any
predicate to check for.GetInterface("IChannel") != null
. - I created an instance of the desired type using
Activator
. - I tried to cast the instance back to
IChannel
.
To demonstrate the above:
var type = assembly.GetTypes().First(f => f.GetInterface("IChannel") != null);
var instance = (IChannel)Activator.CreateInstance(type);
There may be syntax issues with the snippet above, please do your due diligence before performing a copypasta. I've long since removed this snippet from my code as it was just for testing purposes.