【问题标题】:NinjectMVC3 2.2.00 and Membership ProviderNinjectMVC3 2.2.00 和会员提供者
【发布时间】:2012-02-09 01:55:08
【问题描述】:

有谁知道如何使用 NinjectMVC3.cs 来注入自定义会员提供程序类?我已经用谷歌搜索并尝试了每一个实现,但它们都不起作用。有人这样做吗?我尝试使用属性属性 [Inject] 进行注入不起作用并且不知道任何其他方式,因为构造函数注入也不起作用。

这些都不起作用:

public class AccountMembershipProvider : MembershipProvider
[Inject]
protected IAccountRepository accountRepository { get; set; } 

//NinjectMVC.cs RegisterServices
kernel.Bind<IAccountRepository>().To<AccountRepository>();
kernel.Bind<MembershipProvider>().ToProvider<AccountMembershipProvider>();

public class AccountMembershipProvider : MembershipProvider
[Inject]
protected IAccountRepository accountRepository { get; set; }  

//NinjectMVC.cs RegisterServices
kernel.Bind<IAccountRepository>().To<AccountRepository>();
kernel.Bind<MembershipProvider>().ToMethod(ctx=>Membership.Provider); 

注入自定义成员资格提供程序的完整示例会很好。

【问题讨论】:

  • 我使用统一,但尝试将成员资格提供者反对您的控制器怎么样。然后通过构造函数注入,您可以将存储库注入成员资格提供程序,以及不反对 tk 属性注入用法。
  • 我考虑过这样做,但我希望能够编写 Membership.CreateUser(..) 而不依赖于自定义成员资格提供程序。我在自定义成员资格提供程序中使用存储库,成员资格提供程序是通过 Web 配置设置的。如果我要将成员资格注入控制器,那么我什至可能不使用 ASPNET 成员资格提供程序,这是我准备做的。使用带有 DI 的 MS Provider Model 几乎不值得头疼。非常感谢您的回复,不胜感激。
  • 昨晚我读了一篇有趣的文章,介绍了在提供程序中解决的另一种技术 - stackoverflow.com/questions/4193484/… 虽然本质上它与下面的 Remo 完全相同,只是使用 Castle Windsor:bugsquash.blogspot.com/2010/11/…跨度>
  • 我确实可以使用 Remo 的解决方案与 Ninject 3.0.0 一起使用,但我确实必须将 .InRequestScope 添加到 AccountRepository 这似乎有点有趣,因为我有 dbContext 的 .InRequestScope ?如果我在 memberhsip 提供程序之前调用另一个存储库,那么它不会公开,但如果我不这样做,它会引发 ObjectContext 已处置错误,我认为这是因为 HttpModule 中的 Dispose 方法,我不知道我是否应该这样做在其中实现一些东西。 Castle Windsor 的解决方案看起来确实干净多了,但我还没有放弃 Ninject
  • 一旦我完成这篇文章,我肯定会在 github 上发布一个完整的示例应用程序。感谢您的回复 Adam,我会在示例应用程序上及时通知您。

标签: asp.net-mvc-3 ninject membership-provider


【解决方案1】:

Ninject 3.0.0 工作它实例化了自定义成员资格提供程序使用的 IRepository,尽管我收到了上下文已处置错误,所以我将 .InRequestScope 添加到 IAccountRepository 绑定。你能检查绑定是否正确吗?我需要在 IAccount 存储库上使用 InRequestScope 还是需要在 HttpModule 中实现一些代码??

这就是我所拥有的

//custom membership provider
public class AccountMembershipProvider : MembershipProvider
{
    [Inject]
    public IAccountRepository accountRepository
    {
        get;
        set;
    }
//example method
public override int GetNumberOfUsersOnline()
    {          
        return this.accountRepository.TotalUsers;
    }


//AccountRepository
 public class AccountRepository : IAccountRepository
{
    private EFDbContext context;

    public AccountRepository(EFDbContext dbContext)
    {
        this.context = dbContext;
    }

public int TotalUsers
    {
        get { return this.context.Users.Count(); }
    }


//HttpModule  Do I need to implement anything here ???
public class ProviderInitializationHttpModule : IHttpModule
{
    public ProviderInitializationHttpModule(MembershipProvider membershipProvider){}
    public void Init(HttpApplication context){}
    public void Dispose{}        
} 


//NinjectWebCommon.cs    RegisterServices
//dbContext bindings
kernel.Bind<EFDbContext>().ToSelf().InRequestScope();
kernel.Bind<IDbContext>().ToMethod(ctx => ctx.Kernel.Get<EFDbContext>());
kernel.Bind<DbContext>().ToMethod(ctx => ctx.Kernel.Get<EFDbContext>());

//Repository - I had to add .InRequestScope so the Memeberhip Provider doesn't 
//dispose the dbcontext. I believe this is because of the HttpModule disposing
kernel.Bind<IAccountRepository>().To<AccountRepository>().InRequestScope();**

//Custom Membership implemented using the Repository Pattern
kernel.Bind<MembershipProvider>().ToMethod(ctx=>Membership.Provider);
kernel.Bind<IHttpModule>().To<ProviderInitializationHttpModule>();

【讨论】:

  • Membership.Provider 是一个单例。它的生命周期比请求长得多。因此它不能依赖于请求范围内的任何依赖。您最终将引用死对象。存储库的范围不会改变 db 上下文的处置。现在两者都被处理掉了。最好是注入一个工厂来为每个用户验证重新创建存储库,而不是存储库本身。请参阅:planetgeek.ch/2011/12/31/… 如果提供者是帐户实体上的唯一一项操作,单例范围可能会起作用。
  • 忘记我的其他 cmets,我真的很困惑。我要多尝试一下工厂方法。我完全忘记了对其他数据库的实体框架支持。我试图通过使用存储库来围绕实体框架进行编码,而不是记住我正在使用接口进行测试和 DI。哇,这玩意儿一会就搞糊涂了。
  • 我重新创建了项目,但由于某种原因,我无法重新创建昨天遇到的问题。我拥有与上面完全相同的所有代码,但没有 InRequestScope。也许我还在引用一个旧的 Ninject DLL。
猜你喜欢
  • 1970-01-01
  • 2010-10-28
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 2011-04-03
相关资源
最近更新 更多