2

I'm working on an ASP.NET MVC3 application, which has a custom MembershipProvider to handle authentication. This provider has a dependency on a service called IUserService, which is being set by property injection.

public class MyMembershipProvider : MembershipProvider
{
    public IUserService UserService { get; set; }

    public override bool ValidateUser(string username, string password)
    {
        return UserService.IsValidLogon(username, password);
    }
}

I'm using Castle Windsor 3 to manage everything. In my application startup, I register the membership provider successfully:

protected void Application_Start()
{
    _container = new WindsorContainer().Install(FromAssembly.This());
    _container.Register(Component.For<MyMembershipProvider>().LifeStyle.Transient.Named("myProvider"));
}

but when the provider gets called, I get a null reference exception for the UserService property. How can I tell Castle Windsor to inject my property?

David Keaveny
  • 3,904
  • 2
  • 38
  • 52
  • possible duplicate of [How to integrate IoC Membership provider with ASP.NET MVC](http://stackoverflow.com/questions/1003587/how-to-integrate-ioc-membership-provider-with-asp-net-mvc) – Mauricio Scheffer Feb 06 '12 at 12:40

3 Answers3

3

ASP.NET does not delegate creation of Membership Provider to 3rd Parties(ie. You can not DI the MembershipProvider). This is one of the pain points of ASP.NET. The MembershipProvider instance created by ASP.NET can be accessed through Membership.Provider. You can do property injection on this.

Eranga
  • 32,181
  • 5
  • 97
  • 96
  • 2
    I found this article - http://bugsquash.blogspot.com.au/2010/11/windsor-managed-membershipproviders.html which seems to provide a workable solution - what do you make of it? – David Keaveny Feb 06 '12 at 02:03
  • @DavidKeaveny Its an Adapter that delegates calls to the underlying provider. It looks OK. – Eranga Feb 06 '12 at 02:24
1

I've created a membership provider which breaks down the different responsibilities in smaller interfaces (which allows you to use DI). It's free and available as a nuget package

http://blog.gauffin.org/2011/09/a-more-structured-membershipprovider/

jgauffin
  • 99,844
  • 45
  • 235
  • 372
  • That's great for abstracting the membership provider into a more testable interface. however, the question was how to use DI in the provider itself. – Erik Funkenbusch Feb 06 '12 at 17:23
0

As Eranga points out, you will have to manually inject the property the first time you access the MembershipProvider. Not much you can do about it, since the MembershipProvider loads it's instance deep in the bowels of asp.net.

I would suggest that you NOT use dependency injection with this, however. Since the Membership provider is a static class. It is created once per application, and thus the connection will stay open for the lifetime of the application pool.

For my custom provider, I usually just new up my instances so that connection lifetimes can be better maintained. It sucks, but I feel it's better than leaving a hanging connection laying around.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • "Not much you can do about it" -> yes you can, see http://stackoverflow.com/questions/1003587/how-to-integrate-ioc-membership-provider-with-asp-net-mvc – Mauricio Scheffer Feb 06 '12 at 13:54
  • @MauricioScheffer - Yes, but it still suffers from the fact that the object will hang around for the lifetime of the app pool (and thus the connection will stay open). – Erik Funkenbusch Feb 06 '12 at 16:52
  • @MystereMan : only the adapter object, not your custom membership provider, which is what matters here. – Mauricio Scheffer Feb 06 '12 at 17:07
  • @MauricioScheffer - No, your custom membership provider stays around for the lifetime of the app as well, and since you create the connection (by using the service locator) in the constructor of the provider, that means it always retains a reference and thus the connection stays open until the app pool is collected. – Erik Funkenbusch Feb 06 '12 at 17:20
  • @MystereMan : nope, you can define the lifestyle of your custom membership. You can make it transient if you want. Take a look at my article and the implementation. – Mauricio Scheffer Feb 06 '12 at 17:29
  • @MauricioScheffer - that doesn't define the lifestyle of your provider, it only defines the lifestyle of dependant object (ie IUserService). ASP.NET controls the lifetime of your provider, and this lifetime is for the app pool. Because you acquire a reference to your dependant objects in the constructor of the provider, the reference is never released, thus the lifestyle configuration on your request is irrelevant. – Erik Funkenbusch Feb 06 '12 at 17:35
  • @MystereMan : yes, it does define the lifestyle of your provider. ASP.NET only controls the lifetime of the *bridge/adapter* provider. I recommend taking a good look at the implementation and play with the sample app. – Mauricio Scheffer Feb 06 '12 at 17:54