09. september 2008 - 22:45Der 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?
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..?
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.
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.
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.