我得到了原因,结论是类实现的接口和你试图转换的接口存在于不同的
AssemblyLoadContext
s、 所以它失败了。
详细信息
The documentation of
LoadFile
说:
LoadFile不会将文件加载到加载自上下文中
这意味着
加载文件
将程序集加载到新上下文中,
the source code
也验证了这一点。
AssemblyLoadContext alc = new IndividualAssemblyLoadContext($"Assembly.LoadFile({normalizedPath})");
result = alc.LoadFromAssemblyPath(normalizedPath);
加载后
LibCore.dll
通过
加载文件
,共有2个
程序集加载上下文
s存在于程序中,它们都有一个接口
IPlugin
具有相同的名称和相同的程序集名称。所以代码
type.GetInterface(typeof(IPlugin).FullName)
甚至使用
AssemblyQualifiedName
无法区分不同的上下文。
使用以下代码进行验证。
// IndividualAssemblyLoadContext #2
Console.WriteLine(AssemblyLoadContext.GetLoadContext(iDesigner.Assembly));
// DefaultAssemblyLoadContext #0
Console.WriteLine(AssemblyLoadContext.GetLoadContext(typeof(IPlugin).Assembly));
解决方案1
使用
LoadFrom
而不是
加载文件
。
加载自
将程序集加载到“从上下文加载”中,以便可以共享接口。
pluginAssemblies.Add(Assembly.LoadFrom(file));
解决方案2
使用一个单独的核心库,例如,您可以有3个项目。
ConsoleCoreCore.exe
LibCore.dll
public interface IPlugin
public class Server
Lib1.dll
public class LibStandardPlugin : IPlugin
二者都
库1.dll
和
控制台核心.exe
提到
LibCore.dll
ConsoleCoreCore.exe -> LibCore.dll <- Lib1.dll
现在,如果您加载
库1.dll
从…起
LibCore.dll
通过
加载文件
,
库1.dll
将加载到一个单独的上下文中,但它
插件接口
接口仍然是
LibCore.dll
。
// IndividualAssemblyLoadContext #1
Console.WriteLine(AssemblyLoadContext.GetLoadContext(type.Assembly));
// DefaultAssemblyLoadContext #0
Console.WriteLine(AssemblyLoadContext.GetLoadContext(iDesigner.Assembly));
// DefaultAssemblyLoadContext #0
Console.WriteLine(AssemblyLoadContext.GetLoadContext(typeof(IPlugin).Assembly));