来自另一个应用程序域的 CreateInstance 适用于控制台应用程序,但在单元测试时抛出 MissingMethodException

CreateInstance from another appdomain works on console application but throws MissingMethodException when unit testing

这是我为获得最小、完整和可验证的示例所能做的最好的(您可以 copy/paste 进行测试):

考虑这两个 类:

public class WorkerParam : MarshalByRefObject
{
    private readonly string s;

    public WorkerParam(string s)
    {
        this.s = s;
    }
}

public class Worker : MarshalByRefObject
{
    public WorkerParam T { get; }

    public Worker(WorkerParam t)
    {
        this.T = t;
    }
}

当 运行 来自控制台应用程序(4.5.2,AnyCPU)时效果很好:

class Program
{
    public static void Main()
    {
        Worker localWorker = new Worker(new WorkerParam("some string"));

        AppDomain ad = AppDomain.CreateDomain("New domain");

        Worker remoteWorker = (Worker)ad.CreateInstanceFromAndUnwrap(
            typeof(Worker).Assembly.Location,
            typeof(Worker).FullName,
            true,
            BindingFlags.Instance | BindingFlags.Public, null, new object[] { new WorkerParam("string") },
            CultureInfo.CurrentCulture, null);

        Console.ReadLine();
    }
}

相同的内容在单元测试时抛出 MissingMethodException(4.5.2,AnyCPU):

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Worker localWorker = new Worker(new WorkerParam("some string"));

        AppDomain ad = AppDomain.CreateDomain("New domain");

        // below line will throw MissingMethodException
        Worker remoteWorker = (Worker)ad.CreateInstanceFromAndUnwrap(
            typeof(Worker).Assembly.Location,
            typeof(Worker).FullName,
            true,
            BindingFlags.Instance | BindingFlags.Public, null, new object[] { new WorkerParam("string") },
            CultureInfo.CurrentCulture, null);
    }
}

问题是:当 运行 来自单元测试(Visual studio 单元)时 CreateInstanceFromAndUnwrap 将抛出 MissingMethodException 但在控制台应用程序上 运行 完美。

重要提示:当我从构造函数中删除参数 WorkerParam 时,它工作得很好。

您需要声明程序集的位置,因为您使用的不仅仅是 Worker 类型:

        AppDomainSetup domaininfo = new AppDomainSetup();
        domaininfo.ApplicationBase = System.Environment.CurrentDirectory;
        AppDomain ad = AppDomain.CreateDomain("New Domain", null, domaininfo);


        Worker remoteWorker = (Worker)ad.CreateInstanceFromAndUnwrap(
            typeof(Worker).Assembly.Location,
            typeof(Worker).FullName,
            true,
            BindingFlags.Instance | BindingFlags.Public,
            null,
            new object[] { new WorkerParam("string") },
            CultureInfo.CurrentCulture, null);