18

Mam niestandardowy dostawca członkostwa/ról, którego używam w moich kontrolerach MVC, który również chcę mieć dostęp do ASP.NET MVC, więc mogę używać AuthorizationFilters itp. Ponieważ tak wiele osób wdrożyło niestandardowych dostawców, wyobrażam sobie, że wiele osób to zrobiło, ale nie wymyśliłem tego ani nie znalazłem wpisów, które rozwiązałyby konkretnie ten problem. This post to swego rodzaju odwrotna strona mojego pytania. W moim przypadku mój niestandardowy dostawca działa dobrze z moimi kontrolerami i chcę, aby MVC również z niego korzystał.Jak zintegrować dostawcę członkostwa IoC z ASP.NET MVC

Mój dostawca jest zaimplementowany z projektem wtrysku IoC/zależności. Dostawca udostępnia dodatkową funkcjonalność poza podstawowym API członkostwa/ról. W moich kontrolerach używam Castle Windsor do tworzenia instancji. Kod wygląda podobnie do:

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); 
    } 

To wszystko działa świetnie w moim kodu C#, ale chcę podłączyć mój dostawcę do MVC użyć [Autoryzacja] filtry z nim:

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

wiem, że Zwykły sposób poinformowania programu ASP.NET o niestandardowym członkostwie lub dostawcy ról znajduje się w pliku web.config, jak poniżej, ale jeśli to zrobię, ASP.NET po prostu spróbuje wywołać domyślny konstruktor, który nie będzie działał. Każda pomoc doceniona.

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

Odpowiedz

24

Najprostszym sposobem, aby uzyskać to do pracy jest użycie standardowego mechanizmu ASP.NET dotyczącą <membership> w web.config. Po prostu pozwól, aby używał domyślnego konstruktora , ale możesz zastąpić Inicjuj() i pociągnij zależności tam. Użyj this jako odniesienia.

Osobiście, ze względu na takie rzeczy, wolę unikać modelu dostawcy, więc używam podejścia podobnego do tych described in the MonoRail docs. IMHO jest mniej nadęty i bardziej elastyczny. Ostatecznie chodzi tylko o ustawienie HttpContext.User z odpowiednią implementacją IPrincipal, która jest używana przez AuthorizeAttribute.

Niedawno blogged about a solution to do proper IoC with MembershipProviders.

+1

Dzięki za to. Podczas gdy twoja pierwsza metoda działa dobrze, jak powiedziałeś, tworzenie niestandardowych klas IPrincipal/IIdentity zapewnia większą elastyczność. Na przykład jest to krótka ścieżka do tworzenia różnych rodzajów autoryzacji użytkowników/ról, niż zapewnia to Uwierzytelnianie za pomocą formularzy. – keithm

+2

Wygląda na to, że projekt Webdotnet obecnie przenosi swoje repozytorium do mercurial, link jest zepsuty :-( –

+0

Projekt webdotnet do góry :-) –

Powiązane problemy