在MVC3应用程序中使用Ninject和自定义角色提供程序

9
我将尝试在MVC3应用程序中使用自定义角色提供程序。我已经使用Ninject使成员提供程序正常工作,但无法似乎让角色提供程序工作。成员提供程序不需要一个无参数的构造函数,但是角色提供程序需要。以下是一些代码片段:
Web.config
<membership>
  <providers>
    <clear/>
    <add name="MyMembershipProvider" type="MyApp.Models.NHibernateMembershipProvider" 
         applicationName="myApp" />
  </providers>
</membership>

<roleManager enabled="true">
  <providers>
    <add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
         applicationName="myApp" />
  </providers>
</roleManager>

我有一个Ninject模块。

public class MyNinjectModule : NinjectModule
{
    public override void Load()
    {
        this.Bind<ISession>().ToMethod(
            x => MyApp.MvcApplication.SessionFactoryData.GetCurrentSession());

        // Respository
        this.Bind<IUserRepository>().To<UserRepository>();
        this.Bind<MembershipProvider>().To<NHibernateMembershipProvider>();
        this.Bind<RoleProvider>().To<NHibernateRoleProvider>();
    }
}

定制的会员提供程序
public class NHibernateMembershipProvider : MembershipProvider
{
    private IUserRepository _repo;

    public NHibernateMembershipProvider(IUserRepository repository)
    {
        _repo = repository;
    }
    ...

角色提供者
public class NHibernateRoleProvider : RoleProvider
{

    private IUserRepository _repo;

    public NHibernateRoleProvider(IUserRepository repository)
    {
        _repo = repository;
    }
    ...

然后我配置我的控制器以要求授权。

    [Authorize(Roles="Admin")]
    public ActionResult Edit(int? id)
    {
       ...

启动应用程序时,我遇到了这个错误。

Parser Error Message: No parameterless constructor defined for this object.

Source Error: 


Line 49:     <roleManager enabled="true">
Line 50:       <providers>
Line 51:         <add name="MyRolesProvider" type="MyApp.Models.NHibernateRoleProvider"
Line 52:              applicationName="myApp" />
Line 53:       </providers>

我可以通过成员提供程序访问用户,因此存储库已经被正确注入,但是角色提供程序似乎不同。为什么角色提供程序需要一个无参构造函数?有没有简单的方法使角色提供程序与Ninject一起工作?任何帮助都将不胜感激。


我现在大部分时间都已经让角色提供程序正常工作了,但是如果我尝试对用户进行身份验证,加载的角色提供程序没有对存储库的引用(它为null)。不确定为什么会发生这种情况。 - Matt
2
仓储库为空的原因是Ninject没有创建角色提供程序。它是由ASP.NET框架创建的,而该框架本身不太支持依赖注入。这就是为什么它需要一个无参数构造函数的原因。 - mrydengren
2个回答

18

由于在此情况下,角色提供程序(NHibernateRoleProvider)是由ASP.NET框架实例化的,最好的解决方案是使用服务定位器模式。服务定位器模式通常被认为是反面模式,但有时您必须实用主义并接受正在使用的框架上的限制(在这种情况下是ASP.NET框架)。

假设您正在使用Ninject的IDependencyResolver接口的实现。以下代码应该可以工作。

public class NHibernateMembershipProvider : MembershipProvider
{
    private IUserRepository _repo;

    public NHibernateMembershipProvider()
    {
        _repo = DependencyResolver.Current.GetService<IUserRepository>();
    }

    // ...
}

使用IDependencyResolver接口的优点是什么? - Matt
真的没有优势。我在这个例子中使用它,因为它为我提供了一个众所周知的服务定位器模式的抽象。 - mrydengren
1
另一种选择是将存储库注入到自定义成员资格提供程序的属性中,如此处所示 - http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/ - Baldy

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接