使用System.Addin与内存中生成的程序集

时间:2012-01-09 17:42:49

标签: .net reflection dynamic add-in maf

我有一个应用程序,我必须为用户提供即时可扩展性。您可以将其视为一种计算引擎,具有大量数据和一些数学/数值算法。我提供了一些静态字段(数据)和方法(计算),用户可以使用它们构建一个应该返回double的有效C#表达式。

用户在文本框中键入有效表达式,我应该提供结果。我目前所做的是按照http://blogs.msdn.com/b/abhinaba/archive/2006/02/09/528416.aspx中的步骤将表达式注入内存中生成的程序集的静态方法。然后我使用反射调用特定方法并返回结果。

这很好,除了生成的程序集在应用程序的生命周期中不断累积的事实。当我所有的都是客户端应用程序时,这是可以的,但现在我正在进入基于服务器的应用程序,我不想不时重置服务。

在搜索如何卸载程序集时,我找到了System.Addin命名空间。它完全符合我的要求:在不同的AppDomain上加载程序集,我可以放弃它。它甚至封装了所有的反射。

我现在唯一的问题是AddInStore需要一个文件路径,但是所有的程序集都是在内存中生成的,方法是将CompileParameters的GenerateInMemory属性设置为true。是否绝对有必要将我的程序集写入磁盘?或者是否可以将在运行时编译的程序集直接用作加载项?

祝你好运, 卡洛斯

2 个答案:

答案 0 :(得分:0)

我不明白你正在使用AddInStore(卸载程序集?),但你可以卸载appdomain(你说你可以创建动态加载的程序集):

            AppDomain.Unload(yourAppDomain);

或者你可能面临更大的问题!

答案 1 :(得分:0)

也许DynamicMethod正是您所寻找的。

如果没有,那么你可以查看IronPython。它很容易添加到您的应用程序中,也非常强大。当然这比编译的C#代码慢,但我不确定它是否比编译+反射慢。

当然你可以做MZN提到的事情。你可以:

  1. 将您的编译器类更改为从MarshalByRefObj派生。这是CLR创建代理对象所必需的。你将不得不检查一下.Net Remoting。不过太多了。
  2. 创建自己的AppDomain,
  3. 最后调用CreateInstanceFromAndUnwrap的一个重载,在新的AppDomain上加载你的编译器类,并在其上创建一个编译器实例。它将返回给您代理对象。然后使用代理对象执行actuall编译。已编译的程序集将加载到新的AppDomain上。当您决定不再需要此程序集或已达到最大编译程序集数时,可以进行MZN提及的调用并卸载AppDomain和所有已加载的程序集。然后从一个新的AppDomain重复整个事情。
  4. 我认为最简单的方法是使用IronPython。

    在他们的时刻,我正在开发一个基于MAF的应用程序,其中包括现场编译C#代码(使用System.CodeDom)。它与你的类似,但在我的情况下,编译只在升级后进行。所以我加载了许多“脚本”程序集没有问题。我也在文件系统上构建程序集。

    问候并祝你好运,

    帕诺斯