2

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

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

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

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

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

最好的问候,卡洛斯

4

2 回答 2

0

也许DynamicMethod是您正在寻找的。

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

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

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

我认为最简单的方法是使用 IronPython。

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

问候和好运,

帕诺斯

于 2012-03-30T17:05:51.320 回答
0

我不明白您在使用 AddInStore 做什么(卸载程序集?),但您可以卸载 appdomain(您说您可以在其中创建动态加载的程序集):

            AppDomain.Unload(yourAppDomain);

或者,也许您正面临更大的问题!

于 2012-01-18T00:35:16.073 回答