来自另一个应用程序域的 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);
这是我为获得最小、完整和可验证的示例所能做的最好的(您可以 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);