2010-07-26 5 views
3

J'essaie d'implémenter un objet utilisateur personnalisé dans ASP.NET MVC 2. J'ai vu une solution où vous pouvez faire un peu de magie dans Global.asax pour transformer Controller.User en un autre type, disons CustomUser. Mais Controller.User est toujours un IPrincipal, ce qui signifie que je dois le convertir en CustomUser chaque fois que je veux l'utiliser, et je n'aime pas ça du tout. Serait-il considéré comme erroné, ou une mauvaise pratique, d'avoir un contrôleur de base avec une méthode GetUser(), où GetUser() appelle un référentiel d'utilisateurs, et utilise Controller.User pour récupérer notre propre objet utilisateur personnalisé?Utilisateur personnalisé dans ASP.NET MVC 2

Ce que j'essaie de faire est juste d'ajouter quelques propriétés à l'objet utilisateur.

Répondre

1

serait-il considéré comme mauvais ou mauvaise méthode pratique, d'avoir aa contrôleur de base avec un GetUser(), où GetUser() appelle un référentiel d'utilisateurs, et utilise Controller.User pour aller chercher notre propre objet utilisateur personnalisé?

Je ne pense pas. C'est comme ça que je le fais. ;)

+0

Alors comment éviter la confusion de savoir s'il faut utiliser this.User ou this.GetUser()? :) –

+0

@Anders Ekdahl, Par le type de retour. – jfar

0

C'est la façon de le faire, mais vous voulez minimiser le montant que vous devez jeter l'objet utilisateur de minimiser la violation du Liskov principe de substitution: http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29

Au lieu de jeter chaque fois , n'y a-t-il pas quelque chose que vous pouvez enterrer dans un ActionFilter?

+0

Vous dites "C'est la façon de le faire", mais de quelle façon voulez-vous dire? :) On dirait que vous voulez injecter l'utilisateur personnalisé dans le Controller.User. Je suis d'accord sur le fait que cela semble être la meilleure solution, mais je n'arrive pas à comprendre comment éviter ces lancers embêtants. –

+0

Oups, j'aurais dû être plus clair, je voulais dire en utilisant la classe de base et une méthode GetUser comme vous l'avez mentionné. Mon point de vue était de minimiser le besoin de lancer, par ex. Si vous lancez toujours les rôles des utilisateurs, vous pouvez le faire dans un filtre d'action et masquer le jeûne que vous utilisez un objet personnalisé. Si vous avez vraiment besoin de l'objet utilisateur personnalisé partout, envisagez de créer un IUserService qui renvoie l'utilisateur personnalisé et de le faire injecter par votre conteneur IoC (vous pouvez le déclarer sur un BaseController). De cette façon, le code est testable et vous n'avez aucun cast – amarsuperstar

+0

Eh bien, je n'ai aucun cast avec un GetUser() dans un contrôleur de base. Les conversions sont uniquement nécessaires lorsque vous voulez un objet personnalisé dans Controller.User, car cela est tapé à IPrincipal. À l'heure actuelle, j'ai un contrôleur de base, qui a un IdentityLoader qui est défini après l'IoC construit le contrôleur.Le contrôleur de base a une méthode GetIdentity(), qui appelle simplement IdentityLoader.Load() si elle n'a pas déjà été appelée. –

1

Voici ce que je ferais:

Dans Global.asax.cs

protected void Application_PostAuthorizeRequest() 
{ 
    if (HttpContext.Current.User != null && HttpContext.Current.User.Identity != null && !string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name)) 
    { 
     HttpContext.Current.Items["User"] = userRepo.FetchByUsername(HttpContext.Current.User.Identity.Name); 
    } 
} 

public static CustomUser CurrentUser 
{ 
    get 
    { 
     return HttpContext.Current.Items["User"] as CustomUser; 
    } 
} 

alors vous avez une statique à portée de main avec l'utilisateur actuel en elle. C'est une façon sale mais efficace de le faire.

Bien sûr, vraiment, je voudrais ajouter l'utilisateur dans mon conteneur IOC et l'injecter dans mes contrôleurs via un ControllerFactory activé par IOC. C'est la chose 'correcte' à faire. Quoi que vous fassiez, n'utilisez pas de classe de base! Utiliser une statique est probablement plus facile à maintenir à long terme que de créer une énorme classe de base avec toutes les choses «pratiques» dont vous avez besoin.

+0

Pour moi, un appel statique est pire qu'une classe de base. Je suis d'accord avec vous sur le fait que je n'aime pas les énormes classes de base, mais tous nos contrôleurs doivent interagir avec l'utilisateur actuel. La classe de base recevrait simplement un UserLoader injecté à partir de l'IoC, et la méthode GetUser() ne ferait qu'appeler cet appel au chargeur. –

+0

Un jour, vous aurez besoin d'un autre service dans la plupart des contrôleurs, mais pas tous. Ensuite, un peu de wag va l'ajouter à la classe de base de toute façon et lo! La classe de base des monstres est née! Si vous voulez le faire correctement, utilisez un ControllerFactory. http://code.google.com/p/autofac/wiki/MvcIntegration – mcintyre321

+0

J'utilise déjà une fabrique de contrôleurs et j'utilise StructureMap pour injecter des dépendances. Je n'aime pas injecter l'objet utilisateur, mais je pourrais très bien injecter le UserLoader. Mais alors tous mes contrôleurs dépendent de la classe UserLoader, de la classe User et du fait que UserLoader.Load() prend un objet Controller. Au lieu de cela, mes contrôleurs dépendent uniquement de this.GetUser() renvoyant un utilisateur. –