Avatar billede superdude Nybegynder
09. september 2008 - 22:45 Der er 9 kommentarer og
1 løsning

Reflection problem i ASP.NET

Hej Eksperter

Jeg har en webapplikation der kører i .NET 3.5 hvor jeg smider en dll fra et andet projekt i /bin folderen. Fra mit website kan jeg så finde og loade dll'en via reflection - jeg bruger AppDomain.CurrentDomain.GetAssemblies(). Dette virker fint, indtil sitet recycles. Efter en recycle returnerer AppDomain.CurrentDomain.GetAssemblies() ikke alle de assemblies som efter en build.

Hvis jeg ændrer noget i min kode og sitet compiler virker alt fint - indtil næste recycle. Jeg går ud fra det er noget cache der spiller ind, men er der en måde hvorpå jeg kan få fat i min assembly ud over AppDomain.CurrentDomain.GetAssemblies()?
Det skal nævnes at på serveren har jeg standard-website-adgang; det vil sige ikke adgang til noget uden for mit site-space. Derfor kan jeg ikke loade fra GAC o.s.v.

Er der en måde at undgå at min assembly bliver cachet?
Hvad skal der til før jeg kan fange den med AppDomain.CurrentDomain.GetAssemblies() - også efter en recycle?
Avatar billede superdude Nybegynder
09. september 2008 - 22:47 #1
Derfor kan jeg ikke loade fra GAC == derfor kan jeg ikke smide dll'en i GAC
Avatar billede superdude Nybegynder
09. september 2008 - 23:03 #2
Jeg kan loade assembly'en explicit via AppDomain.CurrentDomain.Load() men på den måde loader jeg jo lystigt assempblies ind (efter hver recycle) uden at de nogensinde bliver unloaded..?
Avatar billede arne_v Ekspert
10. september 2008 - 07:16 #3
Jeg er ikke sikker paa at jeg forstaar problemet.

Et eller andet sted i din kode skal du bruge et objekt af en type som du loader fra
en assembly.

Hvis du ikke har det objekt saa loader du.

Hvis du har det objekt saa sker der ikke en load.

Der bliver unloaded automatisk ved restart.

Hvis du vil unloade eksplicit er du noedt til at bruge et separat app domain.
Avatar billede superdude Nybegynder
10. september 2008 - 19:17 #4
Hej Arne

Jeg beklager min uklare formulering af spørgsmålet, som blev skrevet midt i debug/test frustrationer. Jeg skal prøve at forklare mig tydeligere.

Inden jeg kaster mig ud i mit spørgsmål igen vil jeg lige redegøre for to begreber som er centrale i spørgsmålet.
Disse begreber er ikke nødvendigvis korrekte, men jeg forklarer her hvad jeg mener de dækker over, for at undgå at blive misforstået:

Recompile - den "genstart" af sitet der automatisk sker når der er sket ændringer i koden.
Recycle - den "genstart" af sitet der sker når sitet har været lukket ned uden der er ændret i koden (f.eks IIS genstart)

Okay, så til sagens kerne:
Fra mit website loader jeg en type fra en assembly der findes i /bin folderen. Jeg loader ikke typen eksplicit, men fisker den ud af AppDomain.CurrentDomain.GetAssemblies().
Dette virker fint for mig, men kun efter en recompile af sitet. Næste gang sitet har recyclet virker det ikke længere. Årsagen til dette er at AppDomain.CurrentDomain.GetAssemblies() returnerer forskelligt efter henholdsvis en recompile og en recycle. I mit eksempel returneres 30 assemblies efter en recompile men kun 20 efter en recycle. Min assembly fra /bin folderen er blandt de 10 assemblies der forsvinder efter en recycle.

Mit basale spørgsmål er - hvorfor returnerer AppDomain.CurrentDomain.GetAssemblies() forskelligt?

Jeg har en mistanke om at .NET måske cache'r de 10 assemblies, for selvom der "mangler" 10 assemblies efter en recycle kører sitet videre uden fejl.
Problemet er bare at jeg ikke længere har en reference til min assembly. Jeg omgår midlertidigt dette problem ved at loade assemblyen eksplicit via AppDomain.CurrentDomain.Load() men jeg har en dårlig mavefornemmelse med dette. Jeg er meget grøn hvad angår reflection så mine bange anelser skyldes mest at jeg ikke helt kan gennemskue konsekvenserne, men jeg frygter at ende med at have den samme assembly loaded mange gange, og gentagne gange bruge resourcer på at loade en assembly der måske allerede er loadet.

Jeg håber at denne beskrivelse af mit problem er lettere at forstå og at du kan kaste lys over mystikken.

/superdude
Avatar billede arne_v Ekspert
21. september 2008 - 21:36 #5
Tilsyneladende loades assemblies naar de compiles.

Men det kan du naturligvis ikke basere dig paa.

Load explicit.

Og hvis den alleered er loadet faar du *ikke* 2 versioner ved et Load kald.
Avatar billede arne_v Ekspert
21. september 2008 - 21:38 #6
Du behover vel heller ikke at bruge AppDomain.CurrentDomain ?

En ganske "almindelig" Assembly.Load er vel OK ?
Avatar billede superdude Nybegynder
21. september 2008 - 22:05 #7
Som sagt er jeg ikke nogen Reflection-haj. Troede at AppDomain.CurrentDomain var bedst for at få loadet assembly'en ind i det eksisterende domain.

Anyway - det virker i hvert fald nu. Min eneste hage var bare om assemblies blev loadet flere gange ved gentagne kald til Load, men det mener du ikke de gør - og det er jo perfekt.

Tak for din hjælp - smid venligst et svar så du kan få points.
Avatar billede arne_v Ekspert
21. september 2008 - 22:38 #8
svar
Avatar billede arne_v Ekspert
21. september 2008 - 22:42 #9
http://msdn.microsoft.com/en-us/library/36az8x58.aspx

If a version of the requested assembly is already loaded, this method returns the loaded assembly
Avatar billede superdude Nybegynder
22. september 2008 - 18:46 #10
Super - takker.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester