Próbuję utworzyć aplikację z wtyczkami.FileNotFound przy ładowaniu złożenia z zależnością do innej domeny
Mam MainLib.dll, gdzie zrobiłem interfejs commnon (niech to będzie ICommon
) z 1 metodą. Następnie zrobiłem 2 .dlls (wtyczki), które odwołują się do MainLib.dll i implementują ICommon
w niektórych klasach. Ponadto usunąłem wszystkie odniesienia w tym pliku .dll z wyjątkiem System
.
Potem stworzyliśmy aplikację, która monitoruje folderu ".\\Plugins"
i ładuje wszystkie .dlls w newDomain
należy sprawdzić, czy typy w .dll wdrożyć ICommon
(tak, ta aplikacja również odwoływać się do MainLib.dll). Jeśli tak - dodaj nazwę .dll na jakiejś liście.
A teraz problem: przed Próbowałem załadować wtyczki - załadować MailLib.dll i system do newDomain ponieważ wszystkie wtyczki mają zależność ta .dlls. Ładują się poprawnie. Potem zacznę załadować wtyczki, a tu mam:
FileNotFoundException, nie można załadować pliku lub zestawu 'PluginWithException, Version = 1.0.0.0, Culture = neutral, TokenKluczaPublicznego = null' lub jeden z jego zależnościami. System nie może znaleźć określonego pliku.) Na łańcuchu Assembly loadedAssembly = domain.Load (Assembly.LoadFrom (asm) .FullName);
Zespół PluginWithException ma tylko 2 zależności - System i MainLib. Zanim spróbowałem załadować PluginWithException I sprawdził złożeń w nowej domenie, System i MainLib zostały załadowane do tej domeny. Więc nie widzę żadnych ploblemów z zależnością. Przeczytałem temat this i wypróbowałem rozwiązanie z ProxyDomain
, ale wyjątek jest taki sam.
Co robię źle?
Oto kod:
public static List<string> SearchPlugins(string[] names)
{
AppDomain domain = AppDomain.CreateDomain("tmpDomain");
domain.Load(Assembly.LoadFrom(@".\MainLib.dll").FullName);
domain.Load(@"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
MessageBox.Show(GetAssembies(domain)); // here I can see that System and MailLib exist in new domain
List<string> plugins = new List<string>();
foreach (string asm in names)
{
Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName); // here I have exception
var theClassTypes = from t in loadedAssembly.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
if (theClassTypes.Count() > 0)
{
plugins.Add(asm);
}
}
AppDomain.Unload(domain);
return plugins;
}
Dzięki! Twoja odpowiedź jest bardzo przydatna! Rozwiązanie z app.config działa, ale oboje wiemy, że nie jest to najlepszy sposób. Spróbowałem rozwiązania z ładowarką, uruchomiłem kod 'var plugins = loader.LoadPlugins ( Assembly.LoadFrom (Environment.CurrentDirectory + @" \ Plugins \ PluginWithOutException.dll "). FullName);' ale to nie pomogło :(Wyjątek jest taki sam :( –
Czy próbowałeś skonfigurować ścieżkę PrivateBinPath dla potomnej AppDomain podczas jej tworzenia, aby wiedział, jak szukać w folderze wtyczek dla złożeń? Var appDomainSetup = new AppDomainSetup {PrivateBinPath = "Plugins"}; var domain = AppDomain.CreateDomain ("tmpDomain", AppDomain.CurrentDomain.Evidence, appDomainSetup); ' –
Dziękuję! Próbowałem wcześniej rozwiązania z' PrivateBinPath', ale popełniłem błąd, teraz ładuje się i działa dobrze. ładowanie złożeń w nowych domenach, metoda wywołania interfejsu i rozładowywanie domen, sprawdziłem złożenia w bieżącej (domyślnej) domenie i niestety, były one załadowane w bieżącym (d efault). A rozwiązanie z app.config bez Loader ładuje również zespoły w domyślnej domenie. Czy to naprawdę możliwe, aby nie ładować tych złożeń w domyślnej domenie? –