Interagir avec les pages ASP.NET avant l'Init.

Publié par Fabrice Michellonet sous le(s) label(s) , le 21 avril 2010

Au cours du développement de Claymore, pour la partie ASP.NET plus précisément, j'ai eu besoin de trouver un hook me donnant la possibilité d'interagir avec les pages avant les events que l'on trouve sur l'objet Page.

J'ai tout d'abord pensé tripatouiller dans le fichier Global.asax... sans finalement avoir trouvé ce que je souhaitais. Par contre, en fouillant un peu du côté des HttpModule je suis arrivé à la solution suivante :

using System;
using System.Reflection;
using System.Web;
using System.Web.UI;

namespace Claymore.Web
{
    /// <summary>
    /// 
    /// </summary>
    public class ClaymoreHttpModule : IHttpModule
    {
        #region Fields

        private HttpApplication _application;

        #endregion

        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// </summary>
        /// <param name="context"> </param>An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application
        public void Init(HttpApplication context)
        {
            if(context == null)
                throw  new ArgumentNullException("context");

            _application = context;

            context.PostMapRequestHandler += onPostMapRequestHandler;
        }


        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose(){}

        /// <summary>
        /// Handle PostMapRequest event.
        /// </summary>
        /// <param name="sender"> </param>The sender.
        /// <param name="e"> </param>The <see cref="System.EventArgs"/> instance containing the event data.
        private void onPostMapRequestHandler(object sender, EventArgs e)
        {
            Page pageHandler;
            if ((pageHandler = _application.Context.Handler as Page) != null)
                pageHandler.PreInit += HandlePreInit;
        }

        /// <summary>
        /// Handles the pre init event.
        /// </summary>
        /// <param name="sender"> </param>The sender.
        /// <param name="e"> </param>The <see cref="System.EventArgs"/> instance containing the event data.
        protected virtual void HandlePreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;
            if (page != null){
                // Et voila, on a un pointeur sur une page, et l'on peut interagir avec elle avant l'événement Init.
                // Ajouter du code ici.
            }
        }
    }
}

L'un d'entre vous connaîtrait-il une solution équivalente à base de HttpHandler ou autre?

2 commentaires:

Mind a dit… @ 22 avril 2010 à 10:35

T'as besoin de passer avant PreInit aussi ? Sinon tu peux surchager OnPreInit().

Fabrice Michellonet a dit… @ 22 avril 2010 à 11:37

Dans le cas de ce dev (Pattern MVP pour ASP.NET), j'avais besoin d'un point d'accroche commun à toutes les pages, afin de pouvoir lier le presenter à la vue (aspx) correspondant à l'URL saisie dans le navigateur.
La surcharge d'OnPreInit() est techniquement suffisante car cet handler est le tout premier à être appelé au niveau de la page.
Cependant, ce ne serait pas très acceptable et sexy pour l'utilisateur du Framework Claymore car ça l'obligerait, à bien penser à chaque nouvelle page à surcharger la méthode, et ajoute la ligne de code qui va bien pour faire la liaison vue <-> presenter.
Qui plus est, si tu dois faire toi même (par code) la liaison entre une vue et un presenter, tu réintroduit un couplage (indirect cette fois-ci) entre les deux, ainsi qu'un couplage fort vis à vis d'un Framework.
Dans la solution présentée au contraire, je peux effectuer cette liaison de façon générique en amont du code écrit par le développeur; je lui retire par la même occasion la tâche d'avoir à se rappeler qu'il faut surcharger telle out telle méthode, et la vue (aspx) reste totalement agnostique du Framework MVP sous-jacent.

Enregistrer un commentaire