2008-10-03 15 views
6

Próbuję załadować zespoły w osobnej domenie aplikacji, ale używam w bardzo dziwny problem. Oto niektóre kodu:Ładowanie konfekcjonowane w oddzielnych AppDomain, coraz InvalidCastException

public static void LoadAssembly(string assemblyPath) 
    { 

     string pathToDll = Assembly.GetCallingAssembly().CodeBase; 
     AppDomainSetup domainSetup = new AppDomainSetup 
     { 
      PrivateBinPath = pathToDll 
     }; 

     AppDomain newDomain = AppDomain.CreateDomain("AssemblyLoader",null,domainSetup); 


     AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
      pathToDll, 
      typeof(AssemblyLoader).FullName); 

    } 

AssemblyLoader jest inna klasa w tym samym zespole, jak ten jeden, i to dziedziczy MarshalByRef, jednak z jakiegoś dziwnego powodu, otrzymuję wyjątek rzucania za każdym razem próbuję uruchomić to. Nawet utworzyłem ścieżkę do biblioteki DLL zamiast używać GetCallingAssembly(). CodeBase wciąż otrzymuję ten wyjątek.

Rozumiem, że ciężko jest odpowiedzieć na takie pytanie, nie widząc tego i mając więcej informacji, ale być może ktoś znalazł się w podobnej sytuacji i znał zwykłe "gotyki" i na co powinienem zwracać uwagę.

EDIT: Powodem nie chcę, aby załadować je bezpośrednio, ponieważ jest to tylko część kodu. Ostatecznym celem jest, aby ta klasa miała metodę, która ładuje zespoły, pobiera ich GUID i inne informacje o nich i przechowuje je w bazie danych dla projektu, nad którym pracuję. Dlatego jeśli załaduję ten zestaw w osobnej domenie aplikacji, będę mógł załadować tam również inne, a następnie zwolnić domenę aplikacji. Nie ma sensu ładowanie wszystkich tych zestawów na czas trwania aplikacji, jeśli tylko potrzebuję tych danych.

+0

Jeśli klasa AssemblyLoader jest w tym samym zespole, jak ten jeden, dlaczego starasz się załadować go z newDomain? Dlaczego po prostu nie utworzyć instancji bezpośrednio? –

+1

To sposób pośredniego ładowania wtyczek. Jeśli wystąpienie ładowarka jest w głównej aplikacji domeny, należy utworzyć wersję w domenie zagranicznych aplikacji i poprosić go, aby załadować wtyczki, które Cię interesują. Zapobiega swoje wtyczki od potrzebują wiedzieć, czy są one w stanie być obsługiwane przez osobną domenę aplikacji. (tj. wywodzi się z MarshalByRefObject) Utrzymuje to elastyczność projektowania (np. Utwórz klasę podstawową wtyczki, która zapewnia wszystkie funkcje współdzielone dla wtyczek). –

Odpowiedz

0

Nie wierzę konfiguracja PrivateBinPath jest konieczne, za to, że nie trzeba używać ścieżki do biblioteki DLL, ale raczej w pełni kwalifikowana nazwa zespole dla pierwszego parametru; spróbuj:

AssemblyLoader loader = (AssemblyLoader)newDomain.CreateInstanceFromAndUnwrap(
     typeof(AssemblyLoader).Assembly.FullName, 
     typeof(AssemblyLoader).FullName); 
+1

Zła odpowiedź. Pierwszym parametrem CreateInstanceFromAndUnwrap() jest ścieżka i nazwa pliku, a nie nazwa zespołu.Jednak CreateInstanceAndUnwrap() to nazwa assemblera, ale to nie pomaga pytającemu, ponieważ po prostu rozwiąże on tę samą ścieżkę i nazwę pliku. – Timwi

+0

http://msdn.microsoft.com/en-us/library/y7h7t2a2.aspx – TheXenocide

2

(EDIT: po przeczytaniu danego wyjątku, zmieniając całkowicie odpowiedź)

Wydaje się, że problem jest wywołanie CreateInstanceFromAndUnwrap, który używa semantykę LoadFrom o 'pathToDll'. Suzanne Cook detailed the possible sticking point na swoim blogu, gdzie twoja oryginalna AppDomain próbuje wywołać Load ("SomeAssembly, [...]") w przeciwieństwie do LoadFrom ("pathToDll") podczas próby rozwiązania danego typu.

Jej rady było zahaczyć zdarzenie AssemblyResolve na bieżącej domeny do zrobienia poprawnego LoadFrom w celu uzyskania typu. Trochę celowanego Google'a wywołuje a possible solution to the problem na podstawie sugestii Suzanne.

+0

Nie, tutaj jest to, co mówi: Nie można rzutować przezroczyste proxy do typu „CompanyNamespaceTakenOut.AssemblyLoader – BFree

+0

aktualizowane w celu odzwierciedlenia tego. – user7116

0

Wyjazd this article.

Używając kodu w tym artykule mam przekrój obiektu app-domeny. Wyjaśniłem trochę rzeczy generycznymi i mam trzy zjazdy. (tj. 1 określający interfejs, 1 definiujący implementację wtyczki i główny program, który mówi ogólne, co załadować.) Oryginalny kod artykułu jest łatwy do naśladowania.

Powiązane problemy