Hello!
Egy olyan feladatot kellene végrehajtanom, hogy ASP.NET alatt be kellene töltenem különböző plugineket. Ez eddig még meg is van, de nekem ezeket a plugineket menet közben el is kell tudnom engedni, mivel frissíteni is kell őket. Na itt jön a feketeleves. Ugyebár, ha a fő appdomainba töltöm be, akkor nem tudom elengedni, csak ha újraindul az alkalmazás, ha a fájlt felülírom, akkor újraindul a webapp (webdevben biztosan).
Utánaolvastam a dolgoknak, és jó lenne külön appdomaint készíteni és abba betölteni (mindegyiket egy újba, mert ha belehívtam a dll-be, nem megengedhető, hogy leálljon az egész alkalmazás, vagy maga a dllben futó kód!) Viszont már az elsőt sem tudom betölteni. Ezzel próbálkozok:
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = Server.MapPath("~") + "bin\\MeasurementDLLs";
AppDomain newDomain = AppDomain.CreateDomain(dll,null, domaininfo);
//newDomain.TypeResolve += ((s, a) =>
// {
// return System.Reflection.Assembly.LoadFrom(a.Name);
// });
newDomain.Load(File.ReadAllBytes(dll));
//System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(dll);
Ha megpróbálom betölteni, akkor File Not Found exception-t dob. Ha az eseményre feliratkozok, akkor a feliratkozáskor dob egy kivételt, pedig odáig már nem jutok el, hogy meg is próbáljam, hogy betöltsem a dll-t.
Jelenleg úgy épül fel a programom, hogy
- van egy dll, amiben benne van a webalkalmazásom. (betölti az IIS)
- van egy dll, amit a plugin íroi felé bocsájtok ki, hogy megfelelő interfészeket használják, melyek alapján a megfelelő osztályokat hasznlájam a plugin dllekből. Ez referálva van a webalkalmazásos dllben, ezért az IIS betölti a default appdomainbe.
- illetve van a harmadik, maga a plugin, amit szeretnék betölteni, de nem sikerül.
Ebben kérnék segítséget, hogy mit csinálok rosszul? Esetleg mit nem vettem észre.
Kerestem Google-n de pont ilyesmit nem találtam, a példakódok meg vagy nem fordultak le vagy ugyanúgy nem működött mint a sajátom.
- 7277 megtekintés
Hozzászólások
Írj pontos exceptiont... És nem szép dolog bájtokból betölteni az assemblyt. Hivatkozz rá fájlnévvel. Nézegess fusion logot (fuslogvw.exe az SDK-ban).
- A hozzászóláshoz be kell jelentkezni
Exception, ha nem vagyok az eseményre feliratkozva:
A(z) „ExamplePlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null” fájl vagy szerelvény, illetve annak egyik függősége nem tölthető be. A rendszer nem találja a megadott fájlt.
Exception amikor feliratkozok az eseményre:
A(z) „WEBAPP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null” fájl vagy szerelvény, illetve annak egyik függősége nem tölthető be. A rendszer nem találja a megadott fájlt.
Fontos, hogy a pluginekben nincs meghivatkozva a WEBAPP dll
Az appdomainnak hirtelenjében nem találtam meg azt a metódusát, hogy fájlnév alapján töltsön be. A DLL-eket egyelőre nem teszem a GAC-ba, és nem is nagyon szeretném.
- A hozzászóláshoz be kell jelentkezni
Rossz a path, vagy nincs joga a processznek onnan beolvasni assembly-t.
- A hozzászóláshoz be kell jelentkezni
Visual Studio, WebDev az én felhasználóm kontexusában fut. A projekt a saját dokumentumok mappámban van lementve, oda is fordul.
Biztos, hogy a kóddal van valami, de nem tudok rájönni, hogy mi az. Sajna a Google sem akar segíteni, pedig eddig puszipajtások voltunk :(
- A hozzászóláshoz be kell jelentkezni
Tehát jó helyre mutat a változó, és nem dob ilyenolyan securityexceptionöket meg ilyesmit.
- A hozzászóláshoz be kell jelentkezni
Nem dobál ilyesmi exceptiont.
Próbáltam használni a fusion viewertl de nem sok sikerrel. Semmit sem loggolt
- A hozzászóláshoz be kell jelentkezni
És a fusion log mit mond? Assembly betöltés hibára ez AZ eszköz.
Szerk: Ja látom, próbáltad, de nem loggolt semmit. Futtatsd adminként, és a beállításaiban kapcsold be, hogy naplózzon, akkor fog. Meg egy iisreset sem árt.
- A hozzászóláshoz be kell jelentkezni
- ha a \bin alá rakod a .dll-eket, mindig újra fog indulni az AppDomained ha változik (akkor is, ha sub-folderben vannak a cuccok)
- a FileNotFound exception alapján arra gondolnék, hogy itt még nincs semmi nagy mágia, egyszerűen rossz path-ről próbálod betölteni a .dll-t
- A hozzászóláshoz be kell jelentkezni
Jelenleg úgy van megoldva, hogy a WEBAPP a bin könyvtárba fordul, úgy ahogy a fejlesztőknek szóló PluginDev is. a bin\measurementDlls mappába fordul az egy szem kísérleti pluginom.
Amikor a pluginokat be akarom tölteni akkor légyegében végig szaladok a measurementDlls mappán így:
foreach (string dll in Directory.EnumerateFiles(Server.MapPath("~") + "bin\\MeasurementDLLs", "*.dll", SearchOption.TopDirectoryOnly))
így a dll változóban a teljes elérési útvonal benne lesz. Eddig úgy töltöttem be a dll-eket, és vettem ki belőlük a szükséges osztályokat, hogy
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(dll);
foreach (Type type in assembly.GetTypes())
{
//ellenőrzés, type eltárolása
}
Ez szépen is működik csak nem lehet unloadolni az így betöltött DLL-t
De akkor átteszem, hogy a bin könyvtárral legyen egy szinten a plugin mappa
Szerk: áttettem máshová, átírtam az új appdomain path-jait
domaininfo.ApplicationBase = Server.MapPath("~") + "MeasurementDLLs";
domaininfo.PrivateBinPath = Server.MapPath("~") + "MeasurementDLLs";
de a helyzet változatlan.
Szerk2: Mivel a plugin megreferálja a PluginDev dll-t ezért fordításkor a plugin mellé másolódik az is. De próbáltam azt is, hogy betöltöm a plugindevet előtte, de az sem volt neki elég. Továbbra is hiányolja a plugin dll-jét vagy annak valamilyen függőségét betöltéskor, akár byte[]-ként adom át, akár a nevével hivatkozok rá.
Illetve, ha megpróbálok feliratkozi az TypeResolve eseményre akkor a következő Exceptiont kapom:
[System.Runtime.Serialization.SerializationException]
{"Hiba történt a célmetódushoz való kötéskor, mert az aláírás vagy a biztonsági átlátszóság nem felel meg a delegált típusnak."}
Ennyire már nem ismerem a CLR-t, nem tudom, hogy most mit hiányolhat.
- A hozzászóláshoz be kell jelentkezni
Nekem így működik:
Három project:
- Website (referenciálja IMyInterface-t tartalmazó projectet)
- IMyInterface-t tartalmazó project
- Plugin1-et tartalmazó project, Plugin1 MarshalByRefObject-ből származik (referenciálja IMyInterface-t tartalmazó projectet)
var domain = AppDomain.CreateDomain("MyDomain");
var instance = (IMyInterface) domain.CreateInstanceFromAndUnwrap(@"C:\pathtodll\TestClass.dll", "MyPlugins.Plugin1");
- A hozzászóláshoz be kell jelentkezni
Uhh, ütős egy anyag. Köszi. Remélem, hogy ASP.NET alá is át lehet ültetni.
- A hozzászóláshoz be kell jelentkezni
Köszönöm, a példa lapján sikerült betöltenem, példányosítani, stb.
- A hozzászóláshoz be kell jelentkezni
Az appdomainek közötti kommunikáció nagyon ineffektív, annyira, hogy érdemes megbarátkozni az apppool recyclevel.
- A hozzászóláshoz be kell jelentkezni
Jelenleg ez egy kis egyetemi beadandó lenne, nem tervezem, hogy rendesen IIS alá telepítve fusson, így az Application Poolt nem igazán tudnám használni.
- A hozzászóláshoz be kell jelentkezni
nem ide, csak a belépés gomb ide irányított :(
- A hozzászóláshoz be kell jelentkezni