【发布时间】:2012-11-19 10:42:37
【问题描述】:
我们正在测试 MAF 插件以用作我们的插件框架。但我们陷入了一个基本问题。我们可以使用可序列化类型作为 IContract 参数吗?
合约和参数类型都定义在同一个程序集中:
public interface IHostContract : IContract
{
void SetCurrent(TheValue tagValue); // does not work
void SetCurrentSimple(double value); // works fine
}
[Serializable]
public sealed class TheValue
{
public int Id { get; set; }
public double Value { get; set; }
}
我们能够让一切正常运行。调用 SetCurrent 会导致异常: AppDomainUnloadedException:
The application domain in which the thread was running has been unloaded.
Server stack trace:
at System.Threading.Thread.InternalCrossContextCallback(Context ctx, IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, Object[] args)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatch(Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, SmuggledMethodReturnMessage& smuggledMrm)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.SyncProcessMessage(IMessage reqMsg)
Exception rethrown at [0]:
插件的加载和运行:
public void Run(string PluginFolder)
{
AddInStore.Rebuild(PluginFolder);
Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(Plugins.IPlugin), PluginFolder);
foreach (var token in tokens)
{
Console.WriteLine("Found addin: " + token.Name + " v" + token.Version);
try
{
var plugin = token.Activate<Plugins.IPlugin>(AddInSecurityLevel.FullTrust);
plugin.PluginHost = this;
plugin.Start();
plugin.Stop();
}
catch (Exception exception)
{
Console.WriteLine("Error starting plugin: " + exception.Message);
}
}
}
插件:
[System.AddIn.AddIn("Plugin1", Version = "1.0.0")]
public class Plugin1 : IPlugin
{
private int started;
public Plugin1()
{
Console.WriteLine("Plugin 1 created");
}
public void Start()
{
Console.WriteLine("Plugin 1 started: {0}", started);
started++;
var tagValue = new TheValue { Id = 1, Value = 4.32 };
PluginHost.SetCurrent(tagValue);
}
public void Stop()
{
Console.WriteLine("Plugin 1 stopped");
}
public IPluginHost PluginHost { get; set; }
}
【问题讨论】:
-
您应该仔细阅读以下由负责 System.AddIn 的团队成员撰写的博客条目blogs.msdn.com/b/clraddins/archive/2007/02/27/… TheValue 应该是合同程序集中的结构。顺便说一句,我已经广泛使用 System.AddIn 几年了,除了将主机暴露给加载项(如 Visual Studio、MS Office 等)外,我不推荐它。如果您想创建更复杂的设计,使用协作的插件或乐高设计,那么 MEF 或 Mono.AddIns 是更好的选择。
-
您能否通过添加加载和初始化加载项的代码来更新您的问题?
-
之所以使用MAF是因为我们认为我们需要隔离appdomains。我们必须支持同时运行同一个插件的新旧版本。我们还将看看 Mono Addins。更新了问题中的代码以包括加载。
-
如果我们使用struct,我们会得到同样的结果。
-
你在插件的Start方法中使用了IHostContract.SetCurrent? Start 中的工作是否同步?顺便说一句,如果没有加载一个加载项,这是不安全的。
标签: c# .net maf system.addin