3

According to this article description custom-membership-provider-with-repository-injection

I implement the custom Membership provide with inject.

Custom Membership provider

using Ninject;

public class CustomMembershipProvider : MembershipProvider
{
        [Inject]
        public IUserRepository UserRepository { get; set; }

[...]

Custom Role Provider

using Ninject;

public class CustomRoleProvider : RoleProvider
{
      [Inject]
      public IUserRoleRepository UserRoleRepository { get; set; }
[...]

within Web.Config

<membership defaultProvider="CustomsMembershipProvider">
      <providers>
        <clear/>
        <add name="CustomsMembershipProvider" type="namespace.CustomsMembershipProvider"/>
      </providers>
</membership>
<roleManager enabled="true" defaultProvider="customRoleProvider">
      <providers>
        <clear/>
        <add name="customRoleProvider" type="namespace.customRoleProvider"/>
      </providers>
</roleManager>

Now within NinjectWebCommon

private static IKernel CreateKernel()
{
      var kernel = new StandardKernel();
      kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
      kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

      RegisterServices(kernel);
      return kernel;
}

private static void RegisterServices(IKernel kernel)
{
  [...]

  kernel.Bind<IUserRepository>().To<UserRepository>();
  kernel.Bind<IUserRoleRepository>().To<UserRoleRepository>();

  // Inject user & role repository into our custom membership & role providers.
   kernel.Inject(Membership.Provider);
   kernel.Inject(Roles.Provider);
}

when I run application I got error

This method cannot be called during the application's pre-start initialization stage.

from kernel.Inject(Membership.Provider); this line

But If I Kernel setting put within Application_Start

I got bellow Error

Error activating IUserRepository No matching bindings are available, and the type is not self-bindable. Activation path: 2) Injection of dependency IUserRepository into property UserRepository of type CustomMembershipProvider 1) Request for CustomeMembershipProvider

How to solve that. ??

Shubhajyoti Ghosh
  • 1,292
  • 5
  • 27
  • 45

3 Answers3

8

The result is always null. why? because asp.net has it's own static property for membership.

which is membership.provider. and this instance is not part of instance ninject management.

to workaround it , you need to use kernel.inject . but on the generate aspnetmvc.cs you would see that it's injection on PreApplicationStart event and won't let you.

here is the soloution by cipto that solve the problem for me. add this to your NinjectWebCommon

    [assembly: WebActivator.PreApplicationStartMethod(typeof(TopRankFantasy.App_Start.NinjectMVC3), "Start")]
    [assembly: WebActivator.PostApplicationStartMethod(typeof(TopRankFantasy.App_Start.NinjectMVC3), "RegisterMembership")]
    [assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(TopRankFantasy.App_Start.NinjectMVC3), "Stop")]

    public static void RegisterMembership()
    {
        bootstrapper.Kernel.Inject(Membership.Provider);
    } 

Link to article: Ninject and customMembership asp.net mvc 3

ramon22
  • 3,528
  • 2
  • 35
  • 48
  • "Did you ever know that you're my hero, and everything I would like to be?" Thanks for saving my butt, this is the right way to do it with ninject and MVC – Michael La Voie May 01 '13 at 22:58
2

I had a lot of trouble trying this and ended up adding a method that gets me a repository

using System.Web.Mvc;  //Used to access dependency resolver

    private IUserRepository GetUserRepository()
    {
        return DependencyResolver.Current.GetService<IUserRepository>();
    }

I then call this in the methods that require it

I was able to get the repository to become injected using constructor injection but as soon as I went to use the repository the object had been disposed. I found the above to be the simplest alternative.

However, I guess you could also use the Initialize() method

    IUserRepository userRepository;
    public override void Initialize(string name, NameValueCollection config)
    {
        base.Initialize(name, config);
        this.userRepository = DependencyResolver.Current.GetService<IUserRepository>();
    }

Or another way would be to use a property

public IUserRepository UserRepository
{
    get
    {
        return DependencyResolver.Current.GetService<IUserRepository>();
    }
}
NinjaNye
  • 7,046
  • 1
  • 32
  • 46
  • Where I put `Initialize()` method or `IUserRepository UserRepository` property. Now within controller `(IUserRepository userRepository)` , so any changes required to call from Controller ? – Shubhajyoti Ghosh Jan 19 '13 at 08:12
  • No, all of the above can be put in your membership provider. – NinjaNye Jan 19 '13 at 08:13
  • So there is no `set;` for `IUserRepository UserRepository` property? only `[inject]IUserRepository UserRepository {get;}` within membership provider. Rest of the `Kernel.Inject` & kernel.bind<>` settings within **NinjaWebCommmon** and configuration in **Web.Config** remain same ? – Shubhajyoti Ghosh Jan 19 '13 at 08:19
  • You need to remove the `[Inject]` attribute as we are no longer injecting it. Instead we are now getting it from ninject when we need it. NinjectWebCommon and Web.config can remain unchanged – NinjaNye Jan 19 '13 at 08:22
  • You can probably remove the bindings you are doing in `CreateKernel()` – NinjaNye Jan 19 '13 at 08:24
  • `kernel.Inject(Membership.Provider); kernel.Inject(Roles.Provider);`. So this is also not required within NinjectWebCommon ? But basic binding such as `kernel.Bind().To();` required ?? – Shubhajyoti Ghosh Jan 19 '13 at 08:37
  • Correct. You are not using ninject to inject your providers, only your repositories – NinjaNye Jan 19 '13 at 08:39
  • One stupid question, is `DependencyResolver` is a part of the Ninija? – Shubhajyoti Ghosh Jan 19 '13 at 08:43
  • Not a stupid question. `DependencyResolver` is part of `System.Web.Mvc` so add a using to you membership provider – NinjaNye Jan 19 '13 at 08:44
  • Thanks, now let me try this. – Shubhajyoti Ghosh Jan 19 '13 at 08:48
  • Will you please help me regarding this (http://stackoverflow.com/questions/14425236/how-to-call-custom-membership-provider-method-within-controller-with-ninject-rep) – Shubhajyoti Ghosh Jan 20 '13 at 18:09
1

Since a custom RoleProvider often comes along with the custom MembershipProvider, in that case it is useful to add an injection for the Role Provider class. I used the ramon22's solution with an additional line.

[assembly: WebActivator.PreApplicationStartMethod(typeof(TopRankFantasy.App_Start.NinjectMVC3), "Start")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(TopRankFantasy.App_Start.NinjectMVC3), "RegisterMembership")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(TopRankFantasy.App_Start.NinjectMVC3), "Stop")]

public static void RegisterMembership()
{
    bootstrapper.Kernel.Inject(Membership.Provider);
    bootstrapper.Kernel.Inject(Roles.Provider);
} 
Imantas
  • 1,621
  • 13
  • 19