2015-12-11 2 views
2

Это лучшее, что я могу сделать, чтобы получить минимальный, полный и проверяемый пример (Вы можете просто скопировать/вставить, чтобы проверить):CreateInstance из другого AppDomain работает на консоль приложении, но бросает MissingMethodException когда модульное тестирование

Рассмотрим эти два класса:

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); 
    } 
} 

Этот вопрос: CreateInstanceFromAndUnwrap будет броски MissingMethodException при запуске из модульного тестирования (блок Visual Studio), но отлично работать на консольном приложении.

Важно: Когда я удаляю параметр WorkerParam из конструктора, он отлично работает.

+0

Это проблему DLL ад, вы, вероятно, работаете ваше модульное тестирование с старой копией сборка, которая содержит типы Worker и WorkerParam. Старая версия, которая еще не имела конструктора с аргументом WorkerParam. –

+0

Я очищаю и перестраиваю решение, но это не решает проблему. Или мне нужно сделать что-то еще? –

+0

Если вы не знаете, откуда появилась DLL, используйте Fuslogvw.exe и запишите все привязки. –

ответ

2

Вы должны объявить о местонахождении ваших сборок, так как вы используете больше, чем просто тип работника:

 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);