如何将IoC成员资格提供商与ASP.NET MVC集成 [英] How to integrate IoC Membership provider with ASP.NET MVC

查看:189
本文介绍了如何将IoC成员资格提供商与ASP.NET MVC集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我在MVC控制器中使用的自定义成员资格/角色提供者,我也希望能够访问ASP.NET MVC,所以我可以使用AuthorizationFilters等。由于这么多人实现了自定义提供者,我想象许多人们已经做到了这一点,但是我没有想到这一点,或者发现了具体解决这个问题的帖子。 这篇文章是我问题的另一面。在我的情况下,我的自定义提供程序与我的控制器工作良好,我想让MVC也使用它。



我的提供者是使用IoC /依赖注入设计实现的。提供程序公开了超出基准成员资格/角色API的附加功能。在我的控制器中,我使用Castle Windsor创建实例。代码看起来类似于:

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

< castle>
< components>
< component id =MembershipService
service =IMembershipService,MyApp
type =MembershipService,MyApplifestyle =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)));

列表<类型> controllerTypes = new List< Type>();
foreach(类型t在Assembly.GetExecutingAssembly()。GetTypes()){
if(typeof(IController).IsAssignableFrom(t))
controllerTypes.Add(t);
}

foreach(在控制器类型中键入t){
// LifestyleType.Transient =每个请求的新控制器实例
_container.AddComponentLifeStyle(t.FullName,t ,LifestyleType.Transient);
}
}

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

这一切在我的C#代码中都很好,但是我想将我的提供者MVC使用[Authorize]过滤器:

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

我知道ASP.NET关于自定义成员资格或角色提供程序的通常方法是在web.config文件中如下,但如果我这样做,ASP.NET将只是尝试调用默认构造函数,不行任何帮助赞赏。

 < membership> 
< providers>
< clear />
< add name =MyMembershipProvidertype =MyMembershipProvider>
< / providers>
< / membership>


解决方案

让这个工作的最简单的方法是使用ASP.NET在web.config中的< membership> 的标准机制。您只需让它使用默认构造函数,但您将覆盖Initialize()和拉取的依赖关系。使用作为参考。



由于这样的事情,我更喜欢避免提供者模型,所以我使用类似于。 IMHO不那么blo肿,更灵活。最后,这只是关于设置 HttpContext.User 使用正确的 IPrincipal 实现AuthorizeAttribute使用什么。



我最近关于使用MembershipProviders做适当IoC的解决方案


I have a custom membership/roles provider that I use in my MVC controllers that I also want to have accessible to ASP.NET MVC, so I can use AuthorizationFilters, etc. Since so many people have implemented custom providers I imagine many people have done this but I haven't figured it out or found postings that address this problem specifically. This post is sort of a flip side of my question. In my case I have my custom provider working well with my controllers, and I want MVC to use it too.

My provider is implemented with a IoC/dependency injection design. The provider exposes additional functionality beyond the baseline membership/roles API. In my controllers, I use Castle Windsor to create instances. The code looks similar to:

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

This all works great in my C# code but I want to wire my provider into MVC to use [Authorize] filters with it:

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

I know that the usual way to tell ASP.NET about a custom membership or roles provider is in the web.config file as below but if I do this ASP.NET will just try to call the default constructor, which won't work. Any help appreciated.

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

解决方案

The simplest way to get this to work is to use ASP.NET's standard mechanism of <membership> in web.config. You just let it use the default constructor but you override Initialize() and pull the dependencies there. Use this as reference.

Personally, due to things like this, I prefer to avoid the provider model altogether so I use an approach similar to the ones described in the MonoRail docs. IMHO it's less bloated and more flexible. In the end, it's just about setting HttpContext.User with a proper IPrincipal implementation which is what the AuthorizeAttribute uses.

I recently blogged about a solution to do proper IoC with MembershipProviders.

这篇关于如何将IoC成员资格提供商与ASP.NET MVC集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆