Creating a new project on top of existing API is always a challenge. The problem we faced the other day was how strange our legacy MembershipProvider behaved when integrated in our new project that used IoC containers.

If you search on how to implement a MembershipProvider, you’ll see that there is an Initialize method that you can override. Instead of constructor, this is the place where initialization is taking place. In our case, the strange thing was that the Initialize method never executed, which turned out to be logical, after all. The code that registered an instance of the MembershipProvider in the container looked like this:

1
2
3
container.Register(Component.For<MembershipProvider>()
.ImplementedBy<BocaMembershipProvider>()
.LifeStyle.Singleton);

This basically tells the container that MembershipProvider is a singleton so the first time an instance is created by the container, it will be reused on subsequent requests. But why Initialize method is not called? On further inspections, the problem is quite obvious. If you have ever used a MembershipProvider, you know that it is designed using the singleton pattern itself so, for example, user validation is done this way:

1
Membership.Provider.ValidateUser(username, password);

So it is obvious that the first time the instance is requested through singleton Provider property, initialize method is called. Checking the implementation using Reflector confirms that MembershipProvider is initializied lazily, so obviously the way we have registered it in the container is not right. Notice how the following test fails:

1
2
3
4
5
6
7
8
9
10
11
12
13
[Fact]
public void MembershipProvider_Is_Initialized_When_Resolving()
{
var container = new WindsorContainer();

container.Register(Component.For<MyMembershipProvider>()
.ImplementedBy<MyMembershipProvider>()
.LifeStyle.Singleton);

var provider = container.Resolve<MyMembershipProvider>();

Assert.True(provider.Initialized);
}

But how to fix this? The fix was pretty easy and quick. Just change the way it is registered in the container and the failing test will pass:

1
2
3
4
5
6
7
8
9
10
11
12
[Fact]
public void MembershipProvider_Is_Initialized_When_Resolving()
{
var container = new WindsorContainer();

container.Register(Component.For<MyMembershipProvider>()
.Instance((MyMembershipProvider)Membership.Provider));

var provider = container.Resolve<MyMembershipProvider>();

Assert.True(provider.Initialized);
}