3

我以这样一种方式构建了一个后端,将业务逻辑放置在运行时加载的 dll 中。使用 ShadowCopyFiles = true 和文件系统监控,我能够在不重新启动主机进程的情况下修改业务逻辑。

到现在为止还挺好...

让我们称主机 appdomain A,和其中一个孩子 B。

不幸的是,如果我在由 B 而不是 A 引用的程序集 C 中进行更改,则重新加载 B 时不会反映这些更改。我认为这是因为 A 加载 C 本身。我必须采取哪些步骤来防止 A 加载 C?

这是 A 用来加载 B 的代码:

        AppDomainSetup appDomainSetup = new AppDomainSetup();
        appDomainSetup.CachePath = ServiceDLLPath + @"\Shadow";
        appDomainSetup.ShadowCopyFiles = "true";

        ad = AppDomain.CreateDomain(assemblyName, null, appDomainSetup);
        ad.InitializeLifetimeService();
        try
        {
            service = (IService)ad.CreateInstanceFromAndUnwrap(assemblyName, 
                                  "AppName.Services." + typeName);
            service.Start();
        }
        catch (Exception e)
        {
            LogManager.Log("AppDomain load failed: " + e.Message);
            return false;
        }
4

3 回答 3

0

如果A引用C并且是“主机”,则在不停止并重新启动进程的情况下 A无法重新加载。C

一种可能性是制作一个非常薄的 shim AppDomain 来引导AAppDomain(并可以重新启动它),但重新启动该过程可能具有相同的性能配置文件。

另一种(看似更明智)的方法是 makeA并且它的依赖项独立于 所使用的依赖项C,并且对于重叠的程序集,只需使它们足够稳定,您就不需要经常更改它们。

于 2012-05-21T18:25:32.820 回答
0

好的,我通过创建一个“接口”程序集来解决它。

因此,如果此程序集称为 X,则链现在是:

A -> X <- B -> C

(原来:A -> B -> C)

我现在可以在 B 或 C 中进行更改,这会在 appDomain B 被 A 销毁并重新启动时反映出来。

编辑,应蒂姆的要求,提供更多细节。

appdomain A中的代码没有改变,你可以看到我的问题。唯一需要注意的是 IService 类型定义的位置:

 service = (IService)ad.CreateInstanceFromAndUnwrap(assemblyName, 
                              "AppName.Services." + typeName);

一旦将 IService 移至专门构建的程序集,我就能够删除 B 和 A 中的引用,这些引用最终以某种方式将 A 连接到 C。基本上 Chris 所说的一切都是正确的,只是路径并不总是很清楚.

于 2012-05-22T10:42:44.797 回答
0

阅读答案和评论,听起来您最好将业务逻辑包装到 WCF 服务中。您可以使用网络管道来最小化在同一台电脑上运行的开销。您还应该查看 MEF 以构建应用程序可扩展性。不幸的是,MEF 也并非旨在让您在不​​重新启动主机应用程序的情况下即时卸载和替换插件

于 2012-05-22T11:01:07.957 回答