18

J'ai un fournisseur d'appartenances/rôles personnalisé que j'utilise dans mes contrôleurs MVC que je veux aussi avoir accès à ASP.NET MVC, donc je peux utiliser AuthorizationFilters, etc. Puisque tant de gens ont mis en place des fournisseurs de services personnalisés, j'imagine que beaucoup de gens l'ont fait, mais je ne l'ai pas compris ou trouvé des messages qui traitent spécifiquement de ce problème. This post est une sorte de revers de ma question. Dans mon cas, mon fournisseur personnalisé fonctionne bien avec mes contrôleurs, et je veux que MVC l'utilise aussi.Comment intégrer le fournisseur d'appartenance à l'IoC avec ASP.NET MVC

Mon fournisseur est implémenté avec une conception d'injection IoC/dépendance. Le fournisseur expose des fonctionnalités supplémentaires au-delà de l'API d'appartenance/rôles de base. Dans mes contrôleurs, j'utilise Castle Windsor pour créer des instances. Le code ressemble à:

public class HomeController : Controller { 
    IMembershipService _membershipService; 
    public HomeController(IMembershipService membershipService) { 
     _membershipService= membershipService; 
    } 
} 

<castle> 
<components> 
    <component id="MembershipService" 
      service="IMembershipService, MyApp" 
      type="MembershipService, MyApp" lifestyle="PerWebRequest"> 
    <parameters> 
     <connectionString>#{defaultConnectionString}</connectionString> 
    </parameters> 
    </component> 
</components> 
</castle> 

public class WindsorControllerFactory : DefaultControllerFactory { 
    private WindsorContainer _container; 
    public WindsorControllerFactory() { 
     _container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 

     List<Type> controllerTypes = new List<Type>(); 
     foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) { 
      if (typeof(IController).IsAssignableFrom(t)) 
       controllerTypes.Add(t); 
     } 

     foreach (Type t in controllerTypes) { 
      // LifestyleType.Transient = new controller instance for each request 
      _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); 
     } 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     return (IController)_container.Resolve(controllerType); 
    } 

Tout cela fonctionne très bien dans mon code C#, mais je veux câbler mon fournisseur en MVC utiliser [Autorisez] filtres avec elle:

[Authorize (Users="user1, user2", Roles="role8")] 
public ViewResult MyResult(int x) { 
    // implement 
} 

Je sais que le La manière habituelle de dire à ASP.NET sur un membre ou un fournisseur de rôles personnalisé est dans le fichier web.config comme ci-dessous mais si je le fais, ASP.NET essayera juste d'appeler le constructeur par défaut, ce qui ne fonctionnera pas. Toute aide appréciée.

<membership> 
<providers> 
    <clear/> 
    <add name="MyMembershipProvider" type="MyMembershipProvider"> 
</providers> 
</membership> 

Répondre

24

La façon la plus simple d'obtenir ce travail est d'utiliser le mécanisme standard <membership> dans web.config ASP.NET. Vous laissez simplement utiliser le constructeur par défaut mais vous remplacez Initialize() et tirez les dépendances là. Utilisez this comme référence.

Personnellement, en raison de choses comme ça, je préfère éviter complètement le modèle de fournisseur, donc j'utilise une approche similaire à celles described in the MonoRail docs. À mon humble avis, il est moins gonflé et plus flexible. À la fin, il s'agit de définir HttpContext.User avec une implémentation correcte IPrincipal qui est ce que AuthorizeAttribute utilise.

Je récemment blogged about a solution to do proper IoC with MembershipProviders.

+1

Merci pour votre inscription. Bien que votre première méthode fonctionne correctement, comme vous l'avez dit, la création de classes IPrincipal/IIdentity personnalisées offre plus de flexibilité. Par exemple, il existe un court chemin pour créer différents types d'autorisation d'utilisateur/rôle que l'authentification par formulaires. – keithm

+2

On dirait que le projet webdotnet déplace actuellement son référentiel à mercurial, le lien est cassé :-( –

+0

webdotnet project up :-) –

Questions connexes