The only reason I can think of is that the type implements an IPlugin
with the same namespace but from a different assembly. The typeof(IPlugin).FullName
would then match between your plugin loader and the plugin, but the implemented type still does not equal the expected type.
The first example does match the exact same type, in the second example you're matching by the FullName
which only includes the namespace, not the assembly a type is loaded from.
To determine whether this is the case, try log the following value:
bool matches = typeof(IPlugin).IsAssignableFrom(type);
string expected = typeof(IPlugin).AssemblyQualifiedName;
string actual = type.GetInterface(typeof(IPlugin).FullName).AssemblyQualifiedName;
typeof(IPlugin).IsAssignableFrom(type)
is probably what you were looking for in the first place.