2010-05-13 13 views
1

d'abord je veux dire que j'espère que cela ne ressemble pas je suis paresseux, mais j'ai du mal à comprendre un morceau de code du projet suivant .Asp.net Mvc - Kigg: Maintenir objet utilisateur dans HttpContext.Items entre les demandes

http://kigg.codeplex.com/

Je traversais le code source et j'ai remarqué quelque chose qui serait utile pour mon petit projet que je fais. Dans leur BaseController ils ont le code suivant:

private static readonly Type CurrentUserKey = typeof(IUser); 

public IUser CurrentUser 
{ 
    get 
    { 
     if (!string.IsNullOrEmpty(CurrentUserName)) 
     { 
      IUser user = HttpContext.Items[CurrentUserKey] as IUser; 

      if (user == null) 
      { 
       user = AccountRepository.FindByClaim(CurrentUserName); 

       if (user != null) 
       { 
        HttpContext.Items[CurrentUserKey] = user; 
       } 
      } 

      return user; 
     } 

     return null; 
    } 
} 

Ce n'est pas une copie exacte du code I ajusté un peu à mes besoins. Cette partie du code que je comprends encore. Ils stockent leur IUser dans HttpContext.Items. Je suppose qu'ils le font pour qu'ils n'aient pas besoin d'appeler la base de données chaque fois qu'ils ont besoin de l'objet Utilisateur.

La partie que je ne comprends pas est comment ils maintiennent cet objet entre les demandes. Si je comprends bien le HttpContext.Items est un stockage de cache par demande.

Donc, après plus de creuser j'ai trouvé le code suivant.

internal static IDictionary<UnityPerWebRequestLifetimeManager, object> GetInstances(HttpContextBase httpContext) 
{ 
    IDictionary<UnityPerWebRequestLifetimeManager, object> instances; 

    if (httpContext.Items.Contains(Key)) 
    { 
     instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key]; 
    } 
    else 
    { 
     lock (httpContext.Items) 
     { 
      if (httpContext.Items.Contains(Key)) 
      { 
       instances = (IDictionary<UnityPerWebRequestLifetimeManager, object>) httpContext.Items[Key]; 
      } 
      else 
      { 
       instances = new Dictionary<UnityPerWebRequestLifetimeManager, object>(); 
       httpContext.Items.Add(Key, instances); 
      } 
     } 
    } 

    return instances; 
} 

C'est la partie où de la magie se produit que je ne comprends pas. Je pense qu'ils utilisent Unity pour faire une injection de dépendance sur chaque demande? Dans mon projet j'utilise Ninject et je me demande comment je peux obtenir le même résultat.

Je suppose que InRequestScope dans Ninject est identique à UnityPerWebRequestLifetimeManager? Je me demande également quelle classe/méthode est-elle liée à quelle interface? Puisque les HttpContext.Items sont détruits à chaque requête, comment empêchent-ils de perdre leur objet utilisateur?

De toute façon, c'est une longue question, je suis reconnaissant pour toute poussée dans la bonne direction.

Répondre

0

Dans Ninject, vous choisissez votre extension spécifique à la technologie (Ninject.Web ou Ninject.Web.Mvc) et utilisez InRequestScope pour gérer les éléments dans le 'contexte .Items'. Ils seront éliminés à la fin de la demande et les nouveaux seront résolus au besoin pour les demandes subséquentes.

Ce code soit certainement wont autant ou aussi complexe que certaines des choses que vous citant l'OMI: D

+0

Lire des informations sur Kigg et l'unité et maintenant je ne sais pas c'est que dernier morceau de code ne . Je pense que je me trompe aussi à propos du fait qu'ils gardent l'objet Utilisateur entre les requêtes. Je suppose qu'ils stockent dans HttpContext.Items afin qu'ils doivent appeler la base de données qu'une seule fois pour chaque demande. – Pickels

+0

Les éléments ne se trouvent pas entre les demandes - seule la session peut le faire. Items est par exemple si vous effectuez un travail asynchrone et passez à un autre thread - c'est un endroit pour stocker des choses entre différentes phases de traitement d'une seule requête HTTP. (D'où ma comparaison InRequestScope aux articles) –