我正在開發一個使用插件的程序。所有插件都是從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程序集。 –