I’m creating a custom MembershipProvider for a site I’m working on. I’m not a huge fan of the way these Providers were implemented, but let’s put that aside because using Providers can save a lot of time. When creating anything we want to make sure 1) it’s testable and 2) it’s easy to change.
It took me a little bit of prodding to figure this one out, so let me show you how I did it.
Here’s a peek at my custom Membership Provider class:
public class PropertyFalconMembershipProvider : MembershipProvider
private IMembershipRepository repository;
Notice that repository? Nice! Now if you’re like me, you’re probably thinking “ok, so you can create a constructor that takes an IMembershipRepository and you’re done!”. You might think that, but then you’d be wrong. Because when ASP.NET magically instantiates your MembershipProvider after pulling its data from your Web.Config, it’s going to call the Initialize() method. So it’s a little more complicated. Here’s how I did it:
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
MembershipRepositoryFactory factory = new MembershipRepositoryFactory();
repository = factory.GetRepository(name);
What’s that MembershipRepositoryFactory? Well it’s just a way of pulling the correct IMembershipRepository at runtime (using StructureMap but you can use any IoC tool you wish):
public class MembershipRepositoryFactory
public IMembershipRepository GetRepository(string ProviderName)
That’s it. Now you have a clean, testable MembershipProvider!
Just for completeness, here’s a test that shows the functionality:
public void Can_Get_User()
IMembershipRepository repository = MockRepository.GenerateStub<IMembershipRepository>();
User user = MockRepository.GenerateMock<User>();
user.Email = “Username”;
repository.Expect(x => x.GetUser(“Username”)).Return(user);
MembershipProvider provider = new MyCustomMembershipProvider();
provider.Initialize(“PropertyFalconMembershipProvider”, new System.Collections.Specialized.NameValueCollection());
MembershipUser membershipUser = provider.GetUser(“Username”, false);