asp - asp.net - aspcode.it

COMMUNITY - Login
 Username:
 
 Password:
 
Voglio registrarmi!
Password dimenticata?
 Utenti on-line: 0
 Ospiti on-line: 11255
ASPCode.it - Store

  > > Articoli

La gestione degli Eventi in ASP.NET

Data di pubblicazione: 20/10/2003        Voto della community: 4,11 (Votanti: 3)


Quando programmiamo i web form ASP.NET stiamo in realtà già usando gli eventi (ad esempio quando scriviamo del codice in risposta al click di un controllo button). Gli eventi sono infatti un aspetto centrale del modello di programmazione ASP.NET. Non tutti gli eventi sono generati dall'utente finale: anche le modifiche ad un file, cambiamenti dell'orario e il completamento dell'esecuzione di un programma sono esempi di eventi in risposta ai quali possiamo programmare. Inoltre, possiamo generare - se lo desideriamo - dei nostri eventi personali.

Il modello ASP.NET nasconde al programmatore alcuni aspetti della grande complessità del VB.NET, come fa l'IDE di VS.NET, sicché l'articolo si propone di gettare uno sguardo all'interno di quello che è disponibile nel .NET Framework. Prima di occuparci delle specifiche dell'implementazione, daremo uno sguardo ad alcune questioni riguardanti la gestione degli eventi, presentati nel contesto .NET.

Concetti sulla Gestione degli Eventi

Event arguments

Gli Event arguments specificano i dati associati ad un evento. Quando un evento è generato, gli Event arguments sono passati agli event handler che, con questi dati, hanno sufficienti informazioni per gestire l'evento. Gli Event arguments sono di tipo EventArgs, o di uno dei suoi tipi derivati.

Event Handlers

Un event handler è un metodo che esegue azioni personalizzate in risposta  alla notifica di un evento fornita dall'evento di una classe. Questo metodo deve riportare nella definizione esattamente lo stesso tipo di parametri dei valori generati dall'evento. Per convenzione, un event handler non restituisce valori e riceve due parametri. Il primo specifica l'oggetto nel quale si è verificato l'evento (il publisher). Il secondo contiene gli eveng arguments come descritti più sopra.

Delegati

Un delegato è una speciale classe che consente la creazione di oggetti capaci di referenziare metodi con una particolare signature (cioé numero e tipo di parametri del metodo). Ad esempio:

Public Delegate Sub EventHandler(ByVal sender As Object, ByVal e As EventArgs) (1)

Qui EventHandler è un delegato: un oggetto capace di contenere il riferimento ad un qualsiasi metodo che non restituisce valori e che accetta due argomenti, uno di tipo Object ed un altro di tipo EventArgs.

Perché i delegati sono importanti nella gestione degli eventi? ASP.NET usa i delegati per "attaccare" codice agli eventi, come vedremo tra poco.

Eventi

Ritorniamo ora ad esaminare gli eventi per inquadrare i termini sopra definiti. Un evento consente a degli oggetti di informare altri oggetti che è accaduto qualcosa a cui forse reagire. Gli eventi in VB.NET sono basati sul modello publisher-subscriber. La classe che implementa un evento è chiamata publisher dell'evento. Una classe subscriber può sottoscrivere ovvero prenotarsi per un evento pubblicato, registrando un appropriato event handler con l'evento pubblicato. In seguito, quando un evento è generato, il publisher notifica tutti gli oggetti registrati circa l'evento, invocando gli event handler registrati.

Ad esempio, la classe Page notifica gli altri oggetti che una pagina sta per generare il suo contenuto usando l'evento PreRender. La definizione del'evento PreRender nella classe Page è:

Public Event PreRender As EventHandler (2)

Questo definisce l'evento PreRender come del tipo EventHandler dove EventHandler, come definito sopra nella (1), è un Delegato. Il tipo Delegato determina la signature degli event handlers che possono essere registrati con un evento.

Si registra un event handler con un evento incapsulando l'event handler in un oggetto delegato e aggiungendo il delegato all'evento, ad esempio: potremmo scrivere un codice del genere in una pagina ASP.NET:

AddHandler Me.PreRender, AddressOf Me.Page_PreRender (3) 

Qui, la keyword Me sta ad indicare l'oggetto Page. Viene passato all'evento un riferimento all'indirizzo del metodo (AddressOf...). Prima, la precedente istruzione (2) incapsula il riferimento al metodo (il metodo Page_PreRender) in un oggetto delegato di un tipo compatibile e l'istruzione AddHandler attacca poi questo delegato ad un evento.

L'evento gestisce internamente una lista dei delegati registrati presso di esso. Come esiste l'istruzione AddHandler, esiste RemoveHandler che può essere usata per scollegare un handler da un evento. Quando un evento è generato, la relativa lista di delegati viene esaminata per invocare gli event handler incapsulati nei delegati.

I Metodi che generano gli eventi

Ogni classe che pubblica un evento fornisce anche un metodo protected, virtual che genera l'evento. Quando si verifica un qualcosa la classe invoca questo suo metodo. Il compito di questo metodo è di notificare tutti i sottoscrittori circa l'evento.

I metodi che generano gli eventi sono identificati da un'apposita convenzione - la parola 'On' seguita dal nome dell'evento, ad esempio OnPrePrender.


Riassunto del processo

Ora che abbiamo effettuato una prima analisi abbastanza dettagliata, riassumiamo i processi di publishing e subscribing di un evento.

Pubblicazione di un Evento

Per pubblicare e lanciare un evento, un publisher deve:

1. definire un tipo delegato che specifica la signature dell'event handler.
2. definire un evento basato sul delegato definito in 1
3. definire un metodo protected virtual che lancia l'evento
4. invocare il metodo definito in 3 quando si verifica l'evento

Sottoscrizione di un Evento

Per sottoscrivere e gestire un evento, un subscriber deve:
1. implementare un event handler con la signature specificata dall'oggetto delegato dell'evento
2. creare un oggetto delegato all'evento a cui si riferisce l'event handler
3. attaccare l'event handler all'evento

La gestione degli eventi in ASP.NET

Ora che abbiamo esaminato alcuni dei concetti generali possiamo occuparci dell'applicazione dell'event handling in ASP.NET attraverso la disamina di tre tecniche per gestire gli eventi in ASP.NET:

1. Con l'overriding del metodo virtual, protected della classe base
2. Attaccando un delegato all'evento (come presentato sopra)
3. Attraverso l'AutoEventWireUp della classe Page

Nel seguito speriamo di rinforzare anche le idee presentate sopra.

Overriding del metodo virtual protected della classe base

Saprete che una web form di ASP.NET eredita dalla classe Page e pertanto include un set di eventi e metodi (virtual protected)  per lanciare tali eventi. Per esempio, OnInit() è il metodo della classe Page che genera l'evento Init. Quando una pagina ASP.NET è dapprima creata e inizializzata, invoca automaticamente il metodo OnInit() che a sua volta lancia l'evento Init corrispondente all'oggetto Page recentemente inizializzato e passa all'evento Init ogni dato richiesto relativo all'evento.

Poiché la pagina è derivata dalla classe Page, possiamo effettuare l'"override" del metodo protected della classe base che genera l'evento in questo modo:

Protected Overrides Sub OnInit(e as EventArgs)
  Response.Write("OnInit Event method fired!")
  MyBase.OnInit(e)
End Sub


Notare la chiamata MyBase.OnInit(e) che assicura che sia chiamato anche il metodo base oltre alle funzionalità che vogliamo presentare.

Ricordiamo che questa tecnica di gestione degli eventi può essere usata solo nelle classi che derivano dalla classe che pubblica l'evento. Se vogliamo sottoscrivere eventi da una classe che non deriva dalla classe che pubblica gli eventi, dobbiamo usare la tecnica descritta di seguito che gestisce gli eventi attaccando i delegati.

Attaccando un delegato all'evento

Questo metodo fornisce maggiore flessibilità perché:

- I delegati consentono di attaccare uno stesso event handler a diversi eventi. Questa tecnica elimina il codice extra quando bisogna intraprendere azioni simili in risposta a diversi eventi.

- I delegati consentono di attaccare e staccare dinamicamente event handler da ciascun evento. Si possono anche associare eventi multipli ad uno stesso evento.

- La classe subscriber non deve necessariamente derivare dalla classe che pubblica l'evento.

Questo è il metodo preferito da VS.NET, dove la porzione di codice successiva per attaccare il delegato è automatica. Ecco un codice ASP.NET "a mano" relativamente semplice:

<%@ Page Language="VB" %>
<script runat="server">

  ' Insert page code here
  Protected Sub CustomLoadEvent(sender as Object, e as EventArgs)
    Response.Write("Message from load event handler!")
  End Sub

  Protected Overrides Sub OnInit(e as EventArgs)
    AddHandler Me.Load, AddressOf Me.CustomLoadEvent
    MyBase.OnInit(e)
  End Sub

</script>
<html>
<head>
</head>
<body>
<form runat="server">
  <!-- Insert content here -->
</form>
</body>
</html>

Non confondiamoci per l'uso del metodo OnInit, è solo una locazione conveniente per definire l'event handler. Nello specifico:


AddHandler Me.Load, AddressOf Me.CustomLoadEvent


1. Load è il nome dell'evento
2. AddHandler è l'istruzione che collega l'evento
3. CustomLoadEvent è il nome dell'event handler

Ecco cosa accade:
L'evento Init è lanciato quando una pagina ASP.NET è inizializzata. Questa è solo una locazione conveniente per definire l'event handler. Un event handler è attaccato all'evento page load. Quando parte l'evento Page Load sono invocati i corrispondenti event handler. Un event handler può essere collegato all'evento load solo attraverso il suo oggetto delegato. Allora, dove sono le definizioni del delegato e dell'evento? Beh, cosa che puo' leggermente confondere, questi sono nascosti poiché sono già disponibili come parte della classe Page come segue:

Public Delegate Sub EventHandler(sender as object, e as EventArgs)
Public Event Load As EventHandler

Qui la signature del metodo event handler CustomLoadEvent corrisponde ai criteri del delegato EventHandler e percio' puo' essere memorizzato un riferimento a CustomLoadEvent in una istanza di un delegato di tipo EventHandler.

Quando abbiamo un istanza del genere del delegato EventHandler, possiamo attaccarlo all'evento con la keyword AddHandler. Quando è generato l'evento load sarà invocato il metodo CustomLoadEvent attraverso il suo riferimento conservato dall'oggetto delegato.

Confusi? La materia puo' confondere ma se dimentichiamo la terminologia e ciò che fa il framework dietro le scene, potreste semplicemente accettare la seguente sintassi:

AddHandler Me.Load, AddressOf Me.CustomLoadEvent

cioé semplicemente aggiungere un event handler all'evento Load che provocherà l'esecuzione della sub CustomLoadEvent quando parte l'evento Load.

Attraverso l'AutoEventWireUp della classe Page

AutoEventWireUp consente di utilizzare specifici nomi per gli event handler della classe Page. Il nome deve essere della forma Page_NomeEvento, ad esempio Page_Init. L'attributo AutoEventWireUp deve essere settato a true, che è il valore di default in ASP.NET ma sarà settato su false in VS.NET.

Perciò il codice seguente non produrrà alcun output:


<%@ Page Language="VB" AutoEventWireUp="false"%>
<script runat="server">

Protected Sub Page_Load(o as object, e as EventArgs)
  Response.Write("Message from load event handler!")
End Sub

</script>
<html>
<head>
</head>
<body>
<form runat="server">
  <!-- Insert content here -->
</form>
</body>
</html>

ma se settiamo l'AutoEventWireUp="true" che è il default, la Sub Page_Load sarà eseguita, che è probabilmente il modo in cui quanti di voi non utenti di VS.NET hanno sviluppato da tempo.


Riferimenti

ASP.NET: Tips, Tutorial and Code
Scott Mitchell et al.
Sams

Developing and implementing web applications with VB.Net and VS.Net
Mike Gunderloy
Que


Si ringrazia www.dotnetjohn.com per la gentile concessione dell'articolo (Event Handling in ASP.NET, lingua inglese)




Utenti connessi: 11255