【发布时间】:2014-07-25 18:39:02
【问题描述】:
我在尝试编写插件处理程序时遇到了一些问题。
我有一个主应用程序“AppA”,它引用了“AssemblyX”。
AppA 还加载了许多实现“IPlugin”接口的插件程序集。但是,这些插件也可能引用“AssemblyX”,甚至可能是旧版本。
所以最初的问题是通过 Assembly.LoadFrom() 加载插件时与 AssemblyX 发生冲突。
在这里进行了一些研究后,我尝试将插件加载到新的 AppDomain 中。这本身并没有解决问题。接下来我创建了一个继承自 MarshalByRefObject 的 ProxyDomain 类。仍然没有喜悦。
最后我让插件本身继承自 MarshalByRefObject,这确实取得了更大的成功,但是当我尝试将 List 绑定到 ListView 时,它抱怨“System.MarshalByRefObject'不包含名为'SomeProperty'的属性” .
请有人看一下我的代码,看看是否可以进行任何更改:
public partial class WebForm1 : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
AssemblyX x = new AssemblyX();
x.GetStuff("a", "b");
lstConfig.DataSource = PluginLoader.Load(Path.Combine(PluginLoader.GetPluginFolderPath(), "ExamplePlugins.dll"));
lstConfig.DataBind();
}
}
public class PluginLoader
{
public static List<IPlugin> Load(string file)
{
var plugins = new List<IPlugin>();
ProxyDomain pd = new ProxyDomain();
Assembly ass = pd.GetAssembly(file);
try
{
AppDomainSetup adSetup = new AppDomainSetup();
string fileName = Path.GetFileName(file);
string path = file.Replace(fileName, "");
adSetup.ApplicationBase = path;
AppDomain crmAppDomain = AppDomain.CreateDomain("ProxyDomain", null, adSetup);
foreach (Type t in ass.GetTypes())
{
Type hasInterface = t.GetInterface(typeof(IPlugin).FullName, true);
if (hasInterface != null && !t.IsInterface)
{
IPlugin plugin = (IPlugin)crmAppDomain.CreateInstanceAndUnwrap(ass.FullName, t.FullName);
plugins.Add(plugin);
}
}
}
catch (Exception ex)
{
}
return plugins;
}
public class ProxyDomain : MarshalByRefObject
{
public Assembly GetAssembly(string assemblyPath)
{
try
{
return Assembly.LoadFrom(assemblyPath);
}
catch (Exception ex)
{
throw ex;
}
}
}
public interface IPlugin
{
string SomeProperty { get; set; }
void DoSomething();
}
[Serializable]
public class ExamplePlugin : MarshalByRefObject, IPlugin
{
public string SomeValue
{
get
{
AssemblyX x = new AssemblyX(); // Referencing a previouus version of AssemblyX
return x.GetStuff("c");
}
set
{
}
}
public void DoSomething() { }
}
注意:PluginExamples.dll 可能包含多个插件类。
【问题讨论】:
-
你试试 System.Addins 命名空间的东西吗? MAF 可以解决许多关于版本控制的问题(如果它们不能简单地使用适当的清单文件解决)...
标签: c# loading .net-assembly appdomain marshalbyrefobject