What you should do is create an empty membership provider that does nothing more than call into the MVC Dependency Resolver to fetch the real Membership Provider
. By doing this you achieve three things:
- This implementation has a default constructor and can be configured in the web.config.
- The implementation is a MVC infrastructure component and is decoupled from the actual membership provider that contains the implementation (that you probably want to test).
- This infrastructure component has no dependency on Unity (or any other container), but just on MVC3 which lowers the coupling of the container itself.
The implementation might look like this:
public class DependencyResolverMembershipProvider : MembershipProvider
{
private static MembershipProvider Provider
{
get
{
var provider = DependencyResolver.Current.GetService<MembershipProvider>();
if (provider == null)
{
throw new InvalidOperationException(
"Make sure the MembershipProvider is registered.");
}
return provider;
}
}
public override string ApplicationName
{
get { return Provider.ApplicationName; }
set { Provider.ApplicationName = value; }
}
public override bool ChangePassword(string username,
string oldPassword, string newPassword)
{
return Provider.ChangePassword(username, oldPassword, newPassword);
}
public override bool ChangePasswordQuestionAndAnswer(string username,
string password, string newPasswordQuestion, string newPasswordAnswer)
{
return Provider.ChangePasswordQuestionAndAnswer(username,
password, newPasswordQuestion, newPasswordAnswer);
}
public override MembershipUser CreateUser(string username,
string password, string email, string passwordQuestion,
string passwordAnswer, bool isApproved, object providerUserKey,
out MembershipCreateStatus status)
{
return Provider.CreateUser(username, password, email,
passwordQuestion, passwordAnswer, isApproved, providerUserKey,
out status);
}
// Implement all other methods here
}
This is still a lot of work, since the MembershipProvider
has a lot of methods. There are two ways you can make this easier:
- Use a framework such as Griffin.MvcContrib, which already do such a thing for you and do it even in a more pleasant way, since it separates the responsibilities that are inside these classes and expose a few new interfaces that you can implement for this functionality.
- Prevent any part of the system of depending on the static
Membership
class, but always inject aMembershipProvider
into those classes or even better: don't use theMembershipProvider
but simply inject the interfaces that are probably behind thatMembershipProvider
(such asIUserRepository
andIPasswordManager
).