【问题标题】:Compile at runtime with referenced assemblies使用引用的程序集在运行时编译
【发布时间】:2016-12-16 11:09:04
【问题描述】:

我创建了一个函数来编译内存中的字符串中的 C# 代码并在运行时使用它。效果很好。

接下来我创建了一个小型类库(我们称之为 mynew.dll)并将其放在 c:\mylibraries\mynew.dll 中。

在我的代码中,我可以添加一个引用的程序集。我是这样做的:

CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters
{
    GenerateExecutable = false,
    GenerateInMemory = true
};

parameters.ReferencedAssemblies.Add(@"c:\mylibraries\mynew.dll");

CompilerResults results = provider.CompileAssemblyFromSource(parameters, mycode);

现在,在我的 C# 代码字符串 (mycode) 中有一个名为“Execute”的函数。当我在此函数中从 mynew.dll 声明命名空间和类时,我收到此错误:

无法加载文件或程序集 'MyNew, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' 或其依赖项之一。这 系统找不到指定的文件。

当我复制主应用程序的 bin/debug 文件夹中的 dll 时,它突然可以工作了,但我不想要这个。我希望在运行时编译的代码使用它,而不是主应用程序。

这是我在发布之前所做的:

  • 搜索 Stackoverflow
  • 使用谷歌
  • 试图将 dll 编译到磁盘而不是内存中。这行得通...现在的问题是 dll 被锁定在 IIS 中,如果不重新启动 IIS 服务器就无法删除它;没有选择,因为代码可以随时更改,并且我不想在人们在网站上时重新启动服务器。

有没有办法解决这个问题?

【问题讨论】:

  • “代码可以随时更改”意味着内存中的程序集也不适合您,除非您喜欢内存泄漏和大量加载“正确”程序集的杂耍。一旦加载,程序集就不能被卸载(不管它们的来源);只有卸载 AppDomain 才能做到这一点。您是否有任何特殊原因要编译程序集而不是使用表达式树动态生成代码?
  • 在dll中有很多逻辑。在这里考虑数据库处理或电子邮件处理库。编译后的代码并不总是相同的,有时需要数据库处理,有时需要电子邮件处理。也许这有点难以解释。我只想在运行时引用不在主应用程序的 bin 目录中的 dll
  • @Aly El-Haddad 这是示例数据。当然,我在需要的地方逃脱了我的字符串。但我为你改了
  • @dropshot32:好吧,但是为什么不简单地在应用程序外部编译这些程序集,然后从众所周知的目录中加载它们作为带有Assembly.LoadFile 和全名的插件呢?或者,如果您的站点是 ASP.NET,请将源代码作为 .cs 文件放入 App_Code 并让 ASP.NET 引擎负责编译? (是的,它可以做到这一点,尽管现在预编译代码更受欢迎。)

标签: c# dynamic-assemblies


【解决方案1】:

使用 Directory.GetFiles 在文件系统中找到你的程序集,使用 System.Reflection.Assembly.LoadFile 加载程序集,然后找到所需的类型。使用将由您的具体类实现的接口,以避免必须知道具体类型。

这个帖子应该有帮助:Finding objects that implement interface from loaded assembly -how to compare types?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    相关资源
    最近更新 更多