【问题标题】:Reloading dynamic code / reloading type重载动态代码/重载类型
【发布时间】:2013-01-24 03:11:34
【问题描述】:

我在当前项目中遇到了一些问题,如果有人能给我一些见解或建议,我将不胜感激。

我的项目是一项服务,它正在执行用户脚本。脚本是用 C# 编写的,我使用 CodeDomProvider 在运行时构建程序集。程序集包含单个类。

public Script : ScriptBase
{
    public override void Run(){}
}

允许用户更改脚本,如果我检测到更改。我重建创建 ScriptBase 子项的新实例的内容。我知道带有脚本 S1 的原始程序集 A1 仍然加载在当前的 AppDomain 中,但这是我愿意付出的代价。这种情况下没有任何问题。

我想为用户定义的库添加一项功能(在运行时也可编辑)。所以现在的问题是我有一个脚本 S1,它正在使用库 L1。如果用户更改 L1,我显然必须重建所有脚本。问题来了:

build L1 with type T1
build S1 --depends--> L1
(use S1)
build L2 with type T1
build S2 --depends--> L2 = crashes type T1 is defined in L1 and L2
(use S1) //It passes through if I didn't use S1 for the first time

我有以下问题

  1. 我的第一个场景是如何工作的。 IE。我一遍又一遍地构建和加载相同类型的程序集,一切正常

    2.如果我在构建 S1 后不使用它,我可以构建 S2,即使当我检查模块时,我可以看到所有程序集 L1、S1、L2、S2 都已加载。显然,如果我加载程序集,但我不以某种方式使用它,则“已加载程序集,但未加载类型”。到底发生了什么?

    3.您对我的问题有什么建议?看起来最合乎逻辑的是使用临时 AppDomain,但我没有任何经验,它看起来很复杂,如果有更简单的解决方案,我宁愿使用它。

谢谢

【问题讨论】:

  • 我认为这里的主要答案是:要么查看 AppDomain 的使用(当你掌握它时,它真的没那么糟糕),或者查看任何现有的脚本主机; IronPython、IronRuby、ecmascript 和 Lua 拥有相当不错的托管脚本主机 IIRC

标签: c# .net dynamic reflection .net-assembly


【解决方案1】:

我认为 AppDomain 是最好的选择。正如 Marc 所说,一旦你知道自己在做什么,它们真的没有那么糟糕,它只是找到我发现问题的信息。

现在,无耻的插件:我为 StackOverflow 上的另一个问题创建了这个存储库,以帮助反射加载程序集,它应该涵盖设置 AppDomain 并与它进行跨边界通信的基础知识:Plugin Demo

从您的问题来看,您可以放心地忽略 Shadow Copying 部分,而只使用 Host 项目的 Scanner/communication 部分。

【讨论】:

  • 好吧,我期望从答案中,有人还会解释什么决定何时从程序集中加载类型。无论如何,你的例子非常有帮助,我非常感谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多