定制会员提供商和Unity注入

时间:2013-03-14 13:25:58

标签: dependency-injection unity-container custom-membershipprovider

我为我的MVC4解决方案创建了一个自定义成员资格提供程序。问题是我无法通过Unity注入它。

我尝试过使用构造函数注入,但后来我得到了无参数构造函数错误。如果我尝试使用InjectionProperty,它不会改变我的任何属性。我尝试过使用DependencyResolver.Current.GetService();它返回null。

我首先通过web.config附加提供程序:

  <membership defaultProvider="ExtendedServiceMembershipProvider" userIsOnlineTimeWindow="15">
  <providers>
    <clear />
    <add name="ExtendedServiceMembershipProvider" type="Foo.Providers.Security.BoxMembershipProvider, Foo" />
  </providers>
</membership>
<roleManager defaultProvider="ExtendedServiceRoleProvider">
  <providers>
    <clear />
    <add name="ExtendedServiceRoleProvider" type="Foo.Providers.Security.BoxRoleProvider, Foo" />
  </providers>
</roleManager>

这是正确的做法吗? 希望你们中的一些人能解决我的问题。

感谢。

1 个答案:

答案 0 :(得分:3)

你应该做的是创建一个空的成员资格提供程序,除了调用MVC依赖性解析程序以获取真实的Membership Provider之外什么也不做。通过这样做,您可以实现三件事:

  • 此实现具有默认构造函数,可以在web.config中配置。
  • 该实现是一个MVC基础架构组件,并与包含该实现(您可能想要测试)的实际成员资格提供程序分离。
  • 此基础架构组件不依赖于Unity(或任何其他容器),而只是依赖于MVC3,这会降低容器本身的耦合。

实现可能如下所示:

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
}

这仍然是很多工作,因为MembershipProvider有很多方法。有两种方法可以使这更容易:

  • 使用Griffin.MvcContrib之类的框架,它已经为你做了这样的事情,甚至以更愉快的方式做到了,因为它分离了这些类中的责任并暴露了一些新的接口。可以实现此功能。
  • 防止系统的任何部分依赖于静态Membership类,但始终将MembershipProvider注入到这些类中甚至更好:不要使用MembershipProvider而只是注入可能落后于MembershipProvider的接口(例如IUserRepositoryIPasswordManager)。