2016-02-17 3 views
2

Мне бы хотелось вызвать метод crossappdomaindelegate с именем метода, которому нужен параметр.Как вызвать метод crossappdomaindelegate с параметрами

Пример:

myAppdomain.DoCallback(new CrossAppDomainDelegate(MyMethod)); 

private static void MyMethod(string myParam) 
{ 
    Console.Write("my param="+ myParam); 
} 

как я могу передать параметр в новом CrossAppDomainDelegate (MyMethod ....)?

Update: Просто, чтобы завершить ответ Маартен к моему конкретному случаю: я также добавьте ResolveHandler найти уже загруженные сборки. Просто, если у кого-то есть подобные проблемы.

_myNewAppDomain.AssemblyResolve += MyResolveEventHandler; 

     public static Assembly MyResolveEventHandler(Object sender, ResolveEventArgs args) 
     { 
      var dllName = args.Name.Split(',')[0]; 

      var currentAppdomain = (AppDomain) sender; 

      var file = currentAppdomain.GetAssemblies().FirstOrDefault(f => f.FullName.Split(',')[0] == dllName); 

      return file; 
     } 
+0

Вы не можете сделать это напрямую - делегат не предоставляет никаких параметров. Лично я обычно использую [this] (http://msdn.microsoft.com/en-us/library/3c4f1xde.aspx) и вызываю метод-экземпляр непосредственно в другом «AppDomain». Кроме того, см. [Здесь] (http://stackoverflow.com/questions/6242573/simplest-way-to-make-cross-appdomain-call) – Maarten

+0

спасибо за ваш ответ. Я также использую CreateInstanceAndUnwrap, но прежде чем я должен узнать точное имя класса сборки -> мне нужно сначала загрузить сборку (в другом приложении), чтобы узнать, какие типы там -> загрузили их через DoCallback. Или есть ли лучшие способы узнать имя класса сборки? возможно, вы можете поделиться некоторым кодом? Я знаю только, что они реализуют один из моих трех интерфейсов. best С уважением –

+0

Я добавил ответ с примера. – Maarten

ответ

1

Вот один из способов, чтобы получить типы в сборке в другом AppDomain.

Во-первых, определить некоторые фиктивные классы:

public class X1 { } 
public class X2 { } 
public class X3 { } 
public class X4 { } 
public class X5 { } 

Затем определяют конкретный класс для загрузки типов из сборки:

public class TypesProvider : MarshalByRefObject 
{ 
    public string[] RetrieveTypes() 
    { 
     return Assembly.GetExecutingAssembly().GetTypes().Select(x => x.FullName).ToArray(); 
    } 

    public string[] RetrieveTypesForAnotherAssembly(string assemblyFile) 
    { 
     return Assembly.LoadFile(assemblyFile).GetTypes().Select(x => x.FullName).ToArray(); 
    } 
} 

И использовать этот класс для извлечения типов из сборки:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var domain = AppDomain.CreateDomain("type-provider-appdomain"); 
     var typeProviderInstance = domain.CreateInstanceAndUnwrap(typeof(TypesProvider).Assembly.FullName, typeof(TypesProvider).FullName) as TypesProvider; 
     if (typeProviderInstance != null) 
     { 
      Console.WriteLine("Types for the executing assembly"); 
      var types = typeProviderInstance.RetrieveTypes(); 
      foreach (var type in types) 
      { 
       Console.WriteLine(type); 
      } 
      var assemblyFile = new FileInfo("EntityFramework.dll").FullName; 
      Console.WriteLine("Types for assembly " + assemblyFile); 
      types = typeProviderInstance.RetrieveTypesForAnotherAssembly(assemblyFile); 
      foreach (var type in types) 
      { 
       Console.WriteLine(type); 
      } 
     } 
     Console.ReadLine(); 
    } 
} 

Первое использование TypeProvider приведет к фиктивным классам

Types for the executing assembly 
SO_3543881.Program 
SO_3543881.TypesProvider 
SO_3543881.X1 
SO_3543881.X2 
SO_3543881.X3 
SO_3543881.X4 
SO_3543881.X5 

Второй вызов даст все типы из сборки EntityFramework (если вы поместили его в папку bin).

+0

спасибо Маартен. У меня также был класс «Прокси», как ваш TypeProvider, но всегда делал ошибку, чтобы вернуть сборку, а не только типы, которые всегда приводили к отсутствию зависимостей. Изменение моего кода на ваше предложение спасло меня :) Большое спасибо! –

Смежные вопросы