我正在开发一个使用插件的程序。所有插件都是从KrotAPI.IKrotAPI接口继承的类。该接口存储在krotapi.cs文件中,这对于主机的csproj和每个插件的* .csproj都是通用的。如何从DLL接口访问类?
使用此代码
dynamic LoadPlugin(Assembly asm)
{
foreach (Type type in asm.GetTypes())
{
if (type.GetInterface("KrotAPI.IKrotPlugin") != null)
{
PluginType = type;
dynamic inst = Activator.CreateInstance(type);
KrotAPI.IKrotPlugin inst2 = inst as KrotAPI.IKrotPlugin;
if (inst2 == null) return inst;
Console.WriteLine("Link to API is set up.");
return inst2;
}
}
throw new Exception("There are no valid plugin(s) in the DLL.");
}
的inst2
主机信息加载插件永远是空的,我被迫使用慢速和马车动态调用。如何使它像inst
,但与KrotAPI.IKrotPlugin
类型?
关于几乎相同的主题的第二个问题。 一些插件函数返回KrotAPI.FindData类型的结果(这是一个结构,存储在上面的krotapi.cs文件中)。但我不能访问它:
dynamic fd = new KrotAPI.FindData();
if (NextItemInfo != null) //NextItemInfo is an instance of that struct
fd = NextItemInfo;
listBox1.Items.Add(fd.FileName);
在最后一排.NET框架抛出此异常:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException “System.ValueType”不包含定义“文件名”
然而FileName字段在结构硬编码,肯定不是一个空,或
0123同时结合动态操作
如果我KrotAPI.FindData fd2 = (KrotAPI.FindData) fd; listBox1.Items.Add(fd2.FileName);
替换最后一行出现
Microsoft.CSharp.RuntimeBinder.RuntimeBinderInternalCompilerException 一个意外的异常。
WTF?
谢谢!当我选择第一种方式时可能会出现什么麻烦,并且一些插件会比主机exe更旧或更新?目前,我看到它更好,因为不需要在每个插件的目录中放置一个KrotAPI.dll文件,并且当插件目录中没有Krot.exe时,所有插件仍然可以正常工作(正如我假设的那样,插件正在使用已经加载到内存中的程序集)。 –
程序集版本号是程序集标识的一部分,该标识随后成为界面标识的一部分。这意味着如果更新主机程序集的版本号,则该程序集定义的接口不再是插件程序集使用的接口。这可以通过绑定重定向来缓解。 –
你不需要每个插件目录中的API程序集。如果你使用的是默认的AppDomain,你可以强制主机应用程序在加载任何插件之前加载API程序集,然后每个插件只使用已经加载的API程序集。你可以用多种方法强制装配装配(我通常使用空的静态方法)。如果你在单独的AppDomain中隔离你的每个插件,这是一个更多的工作,但你仍然可以让所有的插件使用一个中央API程序集。 –