Custom MembershipProvider:没有为此对象定义的无参数构造函数

时间:2014-01-03 11:52:55

标签: c# asp.net-mvc dependency-injection asp.net-membership unity-container

我有一个自定义的MembershipProvider类,它继承自MembershipProvider,它带有两个参数:

public class CustomMembershipProvider : MembershipProvider
{
    private readonly ISecurityRepository _securityRepository;
    private readonly IUserRepository _userRepository;

    public CustomMembershipProvider(ISecurityRepository securityRepository, IUserRepository userRepository)
    {
        ...
    }

    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        ...
    }

    ... etc
}

此配置文件与此类似:

<membership defaultProvider="CustomMembershipProvider">
  <providers>
    <clear />
    <add name="CustomMembershipProvider" type="Library.Membership.CustomMembershipProvider" />
  </providers>
</membership>

这在我的Web应用程序中主要用于登录和注销。我正在使用Unity for DI并在我的Boostrapper.cs类中设置必要的类。

但是,当我想创建自定义User类并调用Membership.GetUser方法时,我最近遇到了一个问题。当我这样做时,我得到以下异常:

{"No parameterless constructor defined for this object. (C:\\*app path*\\web.config line 43)"}

我的配置文件中的第43行指向我上面发布的自定义成员资格提供程序。我认为应用程序在其他地方使用Unity来解析这些参数,但是在使用Membership类时它不会。

有什么方法可以告诉应用程序如何解决这些依赖关系,或者如果没有办法在不使用具体实现的情况下将这些依赖关系添加到我的成员资格提供程序中?

编辑1:

以下是自定义用户类:

public class User : MembershipUser
{
    public int UserId { get; set; }
    public string Username { get; set; }
    public string Email { get; set; }
    public DateTime LastLoggedOnDate { get; set; }
    ...         
}

编辑2:

在我的自定义成员资格提供程序类中,这就是GetUser方法的样子:

public override MembershipUser GetUser(string username, bool userIsOnline)
{
    return _userRepository.GetUser(username);
}

3 个答案:

答案 0 :(得分:6)

问题是您无法通过构造函数注入Membership提供程序。请参阅this question

我使用Ninject实现了自定义成员资格提供程序,我使用ServiceLocator来获取服务的实例。

public class AccountMembershipProvider : MembershipProvider
{
    private readonly IUsers _users;

    public AccountMembershipProvider()
    {
        _users = ServiceLocator.Current.GetInstance<IUsers>();
    }

    public override bool ValidateUser(string username, string password)
    {
        return _users.IsValidLogin(username, password);
    }
...
}

在您的情况下,您需要获取IUserRepository和ISecurityRepository。

连接接口/服务时

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IUsers>().To<UsersService>();
        kernel.Bind<IRoles>().To<RolesService>();

        kernel.Bind<MembershipProvider>().To<AccountMembershipProvider>().InRequestScope();
        kernel.Bind<RoleProvider>().To<AccountRoleProvider>().InRequestScope();

    }

您可以在此处查看完整的示例(使用Ninject,但您可以将其调整为Unity):https://github.com/lopezbertoni/SampleApp

希望这有帮助,

答案 1 :(得分:4)

我也使用Unity并实现了自定义成员资格提供程序,但使用了稍微不同的方法。检查代码示例:

/// <summary>
/// Defines the custom membership provider class.
/// </summary>
public class SsoMembershipProvider : MembershipProvider
{


    private IApplicationsRepository _appsRepo;
    private IUsersRepository _usersRepo;
    private IMembershipsRepository _membershipsRepo;



    /// <summary>
    /// Initializes a new instance of the <see cref="SsoMembershipProvider"/> class
    /// using injectionConstructor attribute in order to get the repositories needed.
    /// </summary>
    /// <param name="appsRepo">The apps repo.</param>
    /// <param name="usersRepo">The users repo.</param>
    /// <param name="membershipsRepo">The memberships repo.</param>
    [InjectionConstructor]
    public SsoMembershipProvider(IApplicationsRepository appsRepo, IUsersRepository usersRepo, IMembershipsRepository membershipsRepo)
    {
        _appsRepo = appsRepo;
        _usersRepo = usersRepo;
        _membershipsRepo = membershipsRepo;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="SsoMembershipProvider"/> class.
    /// which calls the internal contructor.
    /// </summary>
    /// <remarks>This is happening due to the fact that membership provider needs a
    /// parametless constructor to be initialized</remarks>
    public SsoMembershipProvider()
        : this(DependencyResolver.Current.GetService<IApplicationsRepository>(),
        DependencyResolver.Current.GetService<IUsersRepository>(),
        DependencyResolver.Current.GetService<IMembershipsRepository>())
    { }


}

答案 2 :(得分:1)

这对我有用

public ICustomerRepository CustomerRepository { 
 get { return DependencyResolver.Current.GetService<ICustomerRepository>(); } 
}

然后使用

public override bool ValidateUser(string username, string password)
{
    var abc = CustomerRepository.ValidateCustomer(username, password);
}