3

我正在尝试执行以下操作。应用 A 是“母应用”。它保持打开状态。App B 只是一个 .DLL,我在其中编写了一些派生自 App A 中指定的接口的类。

然后,从 App A 中,我将从 App B 中“导入”类并在其中运行方法。我希望能够动态更改 App B(更改代码并重新编译)并在 App A 中使用新代码。

我在 App B 中有一个后编译命令,它将新的 .DLL 复制到 App A 目录。应用 A 创建一个新的 AppDomain 并使用 ShadowCopying。我认为这就足够了,但是当我尝试重新编译和复制 App B 的新 .DLL 时,它说该文件正在使用中并且无法被覆盖。

这是我现在拥有的代码:

应用 A(代码中的 TestServer):

namespace TestServer
{
    public interface IRunnable
    {
        void Run();        
    }

    class Program
    {        
        static void Main(string[] args)
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationName = "DemoApp";
            setup.ApplicationBase = Environment.CurrentDirectory;
            setup.ShadowCopyDirectories = Environment.CurrentDirectory;
            setup.ShadowCopyFiles = "true";
            int _domain = 1;

            while (true)
            {
                string typeName = Console.ReadLine();

            AppDomain appDomain = AppDomain.CreateDomain("DemoDomain" + _domain, null, setup);

            IRunnable runner = appDomain.CreateInstanceFromAndUnwrap("TestClient.dll", typeName) as IRunnable;

            runner.Run();

            AppDomain.Unload(appDomain);
            _domain++;
            }
        }   
    }   
}

应用 B(代码中的 TestClient):

namespace TestClient
{    
    public class TestRunner : TestServer.IRunnable
    {
        public void Run()
        {
            Console.WriteLine("RUNNING");
        }
    }

    public class Bob : TestServer.IRunnable
    {
        public void Run()
        {
            Console.WriteLine("BOB");
        }
    }
}

我已经读过,如果您使用来自其他应用程序域的东西,这些应用程序域可以自动加载 .DLL 或类似的东西。在这种情况下,我担心使用接口会导致基础 AppDomain 加载 .DLL 从而将其锁定。

我该如何解决这个问题/是否有更好的设置?

注意:我已经更新了我的代码,它仍然产生相同的结果。

4

3 回答 3

3

您的代码仍在母 AppDomain 中运行,因为您将程序集和类型拉入其中。任何代码都应该在生成的域中运行。我已经展示了一种在我的网站上设置类似内容的方法:一种在不同 AppDomain 中启动代码的简单方法

我不是 100% 确定这一点,但这肯定是你必须采取的一步

更新

就那里提出的解决方案而言,您对跑步者的实例化将发生在 DomainLifetimeHook 的继承者中。显示的基础结构确保 Start 和 Stop 方法在由 AppDomainExpander 类创建的 AppDomain 中运行。该 Expander 是创建新域的类,因此您的域设置应该放在域的 Create 方法中。

于 2011-02-17T21:16:32.967 回答
0

主要问题是你在哪里做:

Type type = assm.GetType("TestClient." + typeName);

这发生在 App A 的主 AppDomain 中,结果是主 AppDomain 锁定了 App B 的程序集 .dll

flq 对他的博客文章的回答中的链接应该对您有用。

于 2011-02-17T21:17:39.680 回答
0

解包 ObjectHandle 后,必须将类型加载到主 appdomain 中。要正常工作,需要对未解包的 ObjectHandle 进行操作。

于 2011-02-17T23:53:32.423 回答