2013-01-02 12 views
6

Załaduję wszystkie biblioteki DLL z określonego katalogu "rozszerzeń" w nowym AppDomain, aby uzyskać z nich informacje związane z odbiciem.Wyjątek od otrzymania odwołania do zestawu z innej aplikacji AppDomain

To co usiłuję:

stworzyłem nową bibliotekę AssemblyProxy w moim rozwiązanie, które ma tylko tę klasę:

public class AssemblyProxy : MarshalByRefObject 
{ 
    public Assembly LoadFile(string assemblyPath) 
    { 
     try 
     { 
     return Assembly.LoadFile(assemblyPath); 
     } 
     catch 
     { 
     return null; 
     } 
    } 
} 

I upewnić się, że biblioteka DLL jest obecny wewnątrz moich „rozszerzeń” informator. Następnie używam następującego kodu, aby załadować wszystkie zespoły z katalogu "extensions" do nowego AppDomain.

foreach(string extensionFile in Directory.GetFiles(ExtensionsDirectory, "*.dll")) 
{ 
     Type type = typeof(AssemblyProxy.AssemblyProxy); 
     var value = (AssemblyProxy.AssemblyProxy) Domain.CreateInstanceAndUnwrap(
      type.Assembly.FullName, 
      type.FullName); 

     var extensionAssembly = value.LoadFile(extensionFile); 

     types.AddRange(extensionAssembly.GetTypes()); 
} 

Niektóre biblioteki DLL są ładowane z powodzeniem, ale w niektórych bibliotek DLL jest wyjątek tak:

Could not load file or assembly 'Drivers, Version=2.3.0.77, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

EDIT: wyjątek nie zostanie zgłoszony w nowym AppDomain. Biblioteka DLL zostanie pomyślnie załadowana w nowej domenie AppDomain. Wyjątek zostanie zgłoszony, gdy odwołanie do zestawu zostanie zwrócone do głównej/wywołującej domeny aplikacji. Czy główna/wywołująca AppDomena próbuje załadować zespół samodzielnie po otrzymaniu odwołania?

Dzięki.

+4

czego spróbowałeś? –

+0

Czy ["ReflectionLoadOnly"] (http://msdn.microsoft.com/en-us/library/ms172331 (v = vs.100) .aspx) nie wystarcza do swoich (niezliczonych) celów? –

+0

Co jest nie tak z [CreateInstanceAndUnwrap] (http://msdn.microsoft.com/en-us/library/system.appdomain.createinstancefromandunwrap.aspx)? – Algirdas

Odpowiedz

2

Nie należy zwracać Assembly obiekt z nowym AppDomain bo to będzie działać tylko wtedy, gdy główny AppDomain ma dostęp do tych zespołów, które to nie ponieważ zespoły znajdują się w katalogu:

Jednym ze sposobów na uniknięcie tego, aby śledzić komentarz na leppie i:

  1. Tworzenie zserializowaną typ, który zawiera minimum informacji potrzebnych z obiektu Assembly.
  2. Dodaj ten typ do nowego zespołu, do którego mają dostęp oba elementy AppDomain. Najprostszy sposób to zrobić, dodając go do GAC.

Innym podejściem byłoby użycie Mono.Cecil zamiast System.Reflection. Mono.Cecil pozwoli ci sprawdzać złożenia bez ich ładowania. Dla bardzo prostego przykładu spojrzeć na drugą połowę z tego answer.

+0

Czy jesteś pewien, że coś jest nie tak z obiektem 'Assembly'? Ponieważ jeśli użyję 'ReflectionOnlyLoadFrom', to odwołanie do obiektu tego samego typu' Assembly' zostanie zwrócone. – user1004959

+0

@ user1004959 Jestem przekonany, że zwrócenie obiektu Assembly nie jest tym, co powinieneś zrobić. Być może określony zestaw został już załadowany do głównej AppDomain. Dodaj punkt przerwania w ostatnim wierszu foreach, uruchom program, a następnie użyj funkcji QuickWatch programu Visual Studio i oceń System.AppDomain.CurrentDomain.GetAssemblies(). Jeśli widzisz załadowany zespół, to był on w jakiś sposób załadowany do głównej AppDomain. Czy przypadkiem nie zapisałeś się do zdarzenia AssemblyResolve podczas eksperymentowania? –