1

Does anyone know how to use the NinjectMVC3.cs to inject a custom membership provider class? I've googled and tried every single implementation and none of them work. Is anyone doing this? I've tried injecting using the property attribute [Inject] doesn't work and don't know of any other way since constructor injection doesn't work either.

None of this works:

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

A complete example of injecting a custom membership provider would be nice.

Fab
  • 904
  • 2
  • 14
  • 38
  • I use unity but how about trying to object the membership provider into your controller. Then via constructor injection you can inject the repository into the membership provider as well unopposed tk the attribute inject usage. – Adam Tuliper Feb 09 '12 at 02:15
  • I thought about doing that except I want to be able to code Membership.CreateUser(..) without any dependency on the custom membership provider. I'm using a repository inside the custom membership provider, the membership provider is set via the web config. If I'm going to inject the membership into the controller then I might as well not even use the ASPNET Membership Provider which is what I'm about ready to do. Its almost not worth the headache using MS Provider Model with DI. Thank you very much for the reply, I appreciate it. – Fab Feb 09 '12 at 14:37
  • I read an interesting article last night on another technique to resolve in the provider - http://stackoverflow.com/questions/4193484/how-do-i-control-membershipprovider-instance-creation-lifetime although in essence it does the exact same thing as Remo's below, just using Castle Windsor: http://bugsquash.blogspot.com/2010/11/windsor-managed-membershipproviders.html – Adam Tuliper Feb 09 '12 at 15:23
  • I do have it working with Ninject 3.0.0 using Remo's solution except I did have to add .InRequestScope to AccountRepository which seems a bit funny since I have .InRequestScope of the dbContext ?? If I call another repository before the memberhsip provider then it is not exposed but if I don't it throws a ObjectContext disposed error which I believe is because of the Dispose method in the HttpModule which I don't know if I'm suppose to implement something inside of it. The Castle Windsor solution does look a lot cleaner but I'm not giving up on Ninject just yet – Fab Feb 10 '12 at 00:59
  • I definetly posting a full blown example application on github as soon as I get this piece completed. Thanks for your response Adam I'll keep you posted on the example app. – Fab Feb 10 '12 at 01:08

1 Answers1

0

The Ninject 3.0.0 works it instantiated the IRepository that is used by the Custom Membership Provider although I was getting the context was disposed error so I added .InRequestScope to the IAccountRepository bindings. Can you check if the bindings are correct? Do I need to use InRequestScope on the IAccount Repository or do I need to implement some code in the HttpModule ??

Here's what I have

//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>();
Fab
  • 904
  • 2
  • 14
  • 38
  • 1
    Membership.Provider is a singleton. It has a much longer lifecycle than a request. Therefore it must not rely on any dependency in request scope. You will end up referencing dead objects. The scope of the repository does noch change the disposal of the db context. Now both are disposed. Best is to inject a facory to recreate the repository for every user validation instead of the repository itself. See: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/ If the provider is the only one operation on the account entities singleton scope might work instead. – Remo Gloor Feb 10 '12 at 01:26
  • Forget about my other comments, I was getting really confused. I going to try out the factory method a little more. I totally forgot about entity framework support for other databases. I was trying to code around entity framework by using repositories instead of remembering that I am using the interfaces for testing and DI. Wow, this stuff gets confusing after a while. – Fab Feb 10 '12 at 21:33
  • I recreated the project and for some reason I'm not able to recreate the issue I was having yesterday. I have all the code exactly as above but without InRequestScope. Perhaps I was still referencing an old Ninject DLL. – Fab Feb 11 '12 at 16:57