我有一個winforms項目,它允許未來的開發人員爲appplication創建插件。 Winforms應用程序包含開發人員在創建插件時需要引用的所有接口和類。因此,當我創建插件時,我會引用主應用程序的dll。
當主應用程序初始化時,我創建一個單獨的域來加載所有的插件DLL。我這樣做的原因是,我可以使用appDomain.unload調用來隨意刪除插件,然後重新加載剩餘的插件。 當我在VS2008中啓動調試時,我的應用程序初始化,它加載第一個插件,但我得到一個警告,我需要加載插件引用的dll,我用它來引用主應用程序的接口。
現在我的問題是在將dll加載到子域之前,我可以使用主應用程序的接口來創建插件的實例以供插件用作參考?如果是的話,我該怎麼做?任何幫助表示讚賞。
這是我的應用程序的PluginManager,它加載了app.config文件中找到的插件。我只保留了我需要幫助的方法和類的構造函數。 在這個類中,我正在讀取一個app.cinfig文件,並將customConfigSection的內容放入一個customConfig集合中。當調用loadAssemblies時,我循環訪問集合並將這些集合添加到在構造函數中創建的子域。作爲插件加載程序集
using System;
using MyApp.Data;
using MyApp.Interfaces;
using MyApp.Variables;
using System.Reflection;
namespace MyApp.Core
{
/// <summary>
/// This object helps the application manage its scalable and extended components
/// called plugins.
/// </summary>
public class PlugInManager
{
public PlugInManager()
{
//appDomain setup
pluginDomainSetup = new AppDomainSetup();
pluginDomainSetup.ApplicationBase = pluginDomainLocation;
pluginDomainSetup.DisallowCodeDownload = true;
string pluginApplicationName = string.Format(MAOIE.Variables.Constants.PLUGIN_APPLICATION_NAME);
//appDomain creation
pluginDomain = AppDomain.CreateDomain(pluginApplicationName, null, pluginDomainSetup);
//Loads the values located in the config file
LoadPluginConfiguration();
//Load any existing plugins in the directories
LoadAssemblies();
}
private void LoadAssemblies()
{
//I"m thinking I should add this the referenced libraries to the subdomain here.
//AppDomain.Unload(this.pluginDomain);
string reference = GetReferencePath();
reference += Variables.Constants.MAOIE_CORE_DLL;
//Iterate through the items found in the app.config file.
foreach (PluginSetting item in this.PluginConfigSettings.PluginItems)
{
string file = GetPluginPath();
file += item.PluginFileName;
switch (item.PluginType)
{
case Constants.PluginType.pluginTypeA:
pluginDomain.CreateInstanceFrom(file, item.PluginAssemblyType);
IPluginTypeA ia = (IPluginTypeA)Activator.CreateInstance(pluginDomain, item.PluginFileName, item.PluginAssemblyType);
Plugable<IPluginTypeA> pia = new Plugable<IPluginTypeA>();
pia.ConcreteClass = ia;
pia.Core = false;
//collection used throughout the application
this.aerodynamicAnalyzers.Add(pia);
return;
case Constants.PluginType.pluginTypeB:
pluginDomain.CreateInstanceFrom(file, item.PluginAssemblyType);
IPluginTypeB ib = (IPluginTypeB)Activator.CreateInstance(pluginDomain, item.PluginFileName, item.PluginAssemblyType);
Plugable<IPluginTypeB> pib = new Plugable<IPluginTypeB>();
piB.ConcreteClass = ib;
pim.Core = false;
//collection used throughout the application
this.missionAnalyzers.Add(pib);
return;
case Constants.PluginType.pluginTypeC:
pluginDomain.CreateInstanceFrom(file, item.PluginAssemblyType);
IPluginTypeC ic = (IPluginTypeC)Activator.CreateInstance(pluginDomain, item.PluginFileName, item.PluginAssemblyType);
Plugable<IPluginTypeC> pic = new Plugable<IPluginTypeC>();
pic.ConcreteClass = ic;
pic.Core = false;
//collection used throughout the application
this.pluginTypeCs.Add(pio);
return;
case Constants.PluginType.pluginTypeD:
pluginDomain.CreateInstanceFrom(file, item.PluginAssemblyType);
IPluginTypeD id = (IPluginTypeD)Activator.CreateInstance(pluginDomain, item.PluginFileName, item.PluginAssemblyType);
Plugable<IPluginTypeD> piw = new Plugable<IPluginTypeD>();
pid.ConcreteClass = id;
pid.Core = false;
//collection used throughout the application
this.pluginTypeDs.Add(pid);
return;
}
}
}
}
//end PlugInManager
}
//end namespace MyApp.Core
這個下一個班級是一個單獨的班級在一個單獨的項目。我正在插入一個空插件來測試我的pluginManager的LoadAssemblies方法。我將由Visual Studio複製的MyApp.Core.dll引用添加到此項目的bin目錄中。我需要這個以實現在主應用程序中找到的接口。
這個類只是getters和setters加上一個空方法。
///////////////////////////////////////////////////////////
// testPluginA.cs
// used as an empty class to test the import of plugins into the main application.
///////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using MyApp.Core;
namespace testPluginA
{
public class testPluginA : MyApp.Interfaces.IPluginTypeA
{
public testPluginA()
{
}
private string name = "testPluginA";
private string desc = "Test Plugin A 1";
/// <summary>
/// The description of the plugin.
/// </summary>
public string Description { get{return this.desc;} }
/// <summary>
/// The display name of the plugin.
/// </summary>
public string FriendlyName { get{return this.name;} }
/// <summary>
///
/// </summary>
/// <param name="mp"></param>
public void Optimize(MyApp.Data.Car car)
{
//does nothing
}
不確定你的問題到底是什麼。在Visual Studio中調試時會出現問題嗎?或者它實際上是編譯應用程序的問題?或者在運行它? – 2009-08-11 19:54:46
問題在於運行應用程序。當我的第一個插件加載時,我得到一個運行時錯誤,指出我的插件沒有加載MyApp.Core。代碼行失敗的地方是加載我的程序集,它使用MyApp.Core作爲參考。該引用是在我構建的模擬插件項目中進行的。 – gsirianni 2009-08-11 20:12:35