4

OK, so I've been working on this for hours. I've found a couple of posts here, but nothing that actually resolves the problem. So, let me try it again...

I have an MVC2 app using Ninject and a custom membership provider.

If I try and inject the provider using the ctor, I get an error: 'No parameterless constructor defined for this object.'

public class MyMembershipProvider : MembershipProvider
{
    IMyRepository _repository;

    public MyMembershipProvider(IMyRepository repository)
    {
        _repository = repository;
    }

I've also been playing around with factories and Initialize(), but everything is coming up blanks.

Any thoughts/examples?

skaffman
  • 398,947
  • 96
  • 818
  • 769
AlDev
  • 173
  • 1
  • 7

3 Answers3

5

The Membership provider model can only instantiate a configured provider when it has a default constructor. You might try this using the Service Locator pattern, instead of using Dependency Injection. Example:

public class MyMembershipProvider : MembershipProvider
{
    IMyRepository _repository;

    public MyMembershipProvider()
    {
        // This example uses the Common Service Locator as IoC facade, but
        // you can change this to call NInject directly if you wish.
        _repository = ServiceLocator.Current.GetInstance<IMyRepository>;
    }
Steven
  • 166,672
  • 24
  • 332
  • 435
  • 1
    Adding to this, you can also use property injection - mark some properties [Inject] and then do a Kernel.Inject(this) (Not sure if the SL pattern / CSL thing you're using exposes such a facility though) – Ruben Bartelink Jun 06 '10 at 13:29
  • I've having the same problem, and have tried Ruben's suggestion to no avail. I think it's happening because the Membership provider is being created before Ninject is configured. – mattdwen Jun 11 '10 at 03:07
  • 1
    I don't think property injection can work in this scenario, because it is not NInject that will create an instance of the `MyMembershipProvider`, but it is the `System.Web.Security.Membership` sub system that will instantiate a new instance. – Steven Jun 11 '10 at 11:52
  • @Reuben - do you put the Kernel.Inject(this) inside the membership provider constructor? – Matt May 16 '11 at 09:45
1

This is how I was able to do this:

1) I created a static helper class for Ninject

public static class NinjectHelper
{
    public static readonly IKernel Kernel = new StandardKernel(new FooServices());

    private class FooServices : NinjectModule
    {
        public override void Load()
        {
            Bind<IFooRepository>()
                .To<EntityFooRepository>()
                .WithConstructorArgument("connectionString",
                    ConfigurationManager.ConnectionStrings["FooDb"].ConnectionString);
        }
    }
}

2) Here is my Membership override:

    public class FooMembershipProvider : MembershipProvider
    {
        private IFooRepository _FooRepository;

        public FooMembershipProvider()
        {
            NinjectHelper.Kernel.Inject(this);
        }

        [Inject]
        public IFooRepository Repository 
        { 
            set
            {
                _FooRepository = value;
            }
        }
        ...

With this approach it doesn't really matter when the Membership provider is instantiated.

ptrandem
  • 300
  • 5
  • 10
1

I had the same problem at the exact same spot in the book. It wasn't until later on in the book that I noticed there were two separate web.config files. I initially placed my connectionString key in the wrong web.config file. It wasn't until I placed the connectionString in the correct web.config file that the 'no parameterless constructor' error went away.

DBhelper
  • 11
  • 1