Newsgroup: it.lavoro.professioni.webmaster
Titolo: [ASP.NET] dubbio amletico sul life cycle di una classe istanziata in un modulo

ok il titolo è già assurdo di per se, spero che non lo sia altrettanto il
resto :-)
Sto riprogettando il mio portale in 
ASP.NET
 e XHTML (e gia solo per renderlo
XHTML compliant c'è un bel po' da sudare)
Il mio dubbio consiste in questo: sto progettando il sito in modo che si
possano generare menu dinamici in base all'area ma in modo object oriented
(attualmente gia lo fa ma trattandosi di ASP puro avevo semplicemente fatto
una sfilza di Case IDAreaXYZ, etc...
La soluzione che ho pensato è stata quella di crearmi una classe AreaSito
nella quale definire una Struct contenente i parametri che identificano
un'area, compreso di voci di menu, etc... e di leggerne i valori da un file
xml e, dato che gli ID area non sono lineari (nel senso che ci potrebbero
essere buchi) ho optato poi per creare una Collection piena di Struct
conteneti le mie specifiche di ogni singola area (quindi non ho usato Array)
ma questo è un dettaglio.
Il punto è questo: per ottimizzare la cosa, volevo ovviamente leggere il
file XML solo una volta dato che non cambierà (o per lo meno non sovente,
nel qual caso avrei comunque una pagina di amministrazione dalla quale
"rigenerare" il tutto) e per farlo ho pensato di lanciare l'inizializzazione
della classe durante l'Application_Start nel Global.asax.
Mentre sviluppavo, trascinato dall'abitudine di sviluppare applicativi
client/server più che siti WEB, ho dichiarato una variabile AreaSito in un
modulo globale, per aver accesso da qualsiasi pagina al mio oggetto, che
secondo la mia idea doveva essere per l'appunto condiviso da ogni utente.
In ASP ciò si poteva fare dichiarando nel global.asa l'oggetto che volevamo
condividere, ma in 
ASP.NET
, da quel che ho visto, si può ottenere lo stesso
effetto istanziando l'oggetto in un modulo globale, confermate questa
cosa???
Schematizzando, la mia situazione è quindi questa:
ho una classe AreaSito dichiarata pressappoco così
Public Class cAreeSito
   Public Structure structAreaSito
      Dim IDArea As Integer
      Dim NomeArea As String
      Dim VoceMenuArea As String
      Public Sub SetArea(ByVal ID_Area As Integer, ByVal sNomeArea As
String, ByVal sVoceMenuArea As String, ByVal bLinkPubblico As Boolean)
         IDArea = ID_Area
         NomeArea = sNomeArea
         VoceMenuArea = sVoceMenuArea
      End Sub
   End Structure
   Public collAreeSito As Collection
   Public Sub InizializzaAree()
      ...... qui inizializzo la classe caricando i dati dal file xml e
riempiendo la collection collAreeSito
   End Sub
End Class
in un modulo che ho chiamato IstanzeGlobali.vb, ho dichiarato:
Public AreaSito as New cAreeSito
nel global.asax invece c'è:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
   AreeSito.InizializzaAree() 'inizializzo la classe cAreeSito
End Sub
A questo punto, ricordandomi come funzionava ASP (anche se ignoravo/ignoro
come vengano considerati i moduli in 
ASP.NET
, anche se ora qualche idea ce
l'ho) mi sarei aspettato un errore dato che poi ho pensato: non è che
facendo così, dato che credo che il modulo sia visibile solo nel contesto
del singolo utente e quindi istanziato ad ogni esecuzione di una pagina, mi
verrà fuori un errore dicendo che la collection non è impostata? (ricordo
che la imposto solo nell'application_onstart)
E invece con mia sorpresa tutto ha funzionato benissimo, ho per scrupolo
inserito come debug una stringa nella pagina HTML che si vedeva solo se
veniva eseguito il metodo InizializzaAree e notavo che quella stringa
compariva solo per l'appunto quando restartava la mia applicazione, dunque
sono arrivato alla conclusione che ciò che si dichiara in un modulo, ha una
visibilità che dura per tutta la durata dell'applicazione, cosa molto comoda
in effetti, ma che non mi sarei aspettato. Sono giunto ad una giusta
conclusione o ho preso un abbaglio? (nel qual caso saprebbe più di bug però,
perchè debug alla mano la funzione di inizializzazione viene lanciata solo 1
volta all'avvio dell'app. e poi basta, quindi...)
Scusate per il post lunghetto ma volevo descrivere bene la situazione così
che magari possiate riprodurla (ovviamente dovete poi usare, in un webform,
l'oggetto dichiarato nel modulo globale per la prova del 9)
ciao
-- 
Fabio Angela (aka Red Angel)
cerchi consigli per un hosting? 
http://hosting.redangel.it
http://www.redangel.it
 - il portale sulla programmazione

Non conosco 
ASP.NET
 e parlo solo da un punto di vista 
VB.NET
. Secondo me, e
quello che vedo, la dichiarazione è globale quindi sarà disponibile in ogni
modulo della tua applicazione.
Non credo (ma non lo so esattamente) che in 
ASP.NET
 si possa utilizzare
l'istruzione Imports quindi ti danno la possibilità di gestire quello che
vuoi a livello di procedura all'interno del file global.asax
Soprattuto questo ti viene confermato dal tuo stesso debug.

 Soprattuto questo ti viene confermato dal tuo stesso debug.
Quello che sono arrivato a pensare è appunto che, avendo io istanziato degli
oggetti in un modulo globale, questi oggetti non vengano distrutti in quanto
non hanno scope di webform, ma sono appunto dichiarati in un modulo
se io avessi fatto qualcosa tipo
AreaSito = new cAreeSito
in un webform, quell'oggetto sarebbe stato distrutto al termine
dell'esecuzione della mia webform, mentre istanziandola nel mio modulo, il
suo life cycle dura per tutta la durata dell'applicazione
come diceva un personaggio dello Zelig
"vavava io non so, ma i fatti mi cosano!" :-)
Comunque io prendo per buona questa cosa che ho notato e che tra l'altro mi
risulta molto comoda perchè non devo scomodare le variabili application,
etc..., anche se non l'ho letta da nessuna parte, dopotutto come si dice, se
un esperimento porta risultati diversi dalla teoria, è la teoria ad essere
sbagliata :-D
L'unico dubbio che mi rimane a questo punto è come si comportano questi
oggetti in multithreading, cioè a fronte di diverse pagine nello stesso
momento, se gli oggetti che ho fatto, istanziati come globali, non danno
problemi di accesso.
Penso di no perchè le operazioni che fanno sono tutte di lettura in memoria
e non ho nessuna scrittura, vedrò quando testerò :-)
