自定义成员资格提供程

jus*_*yan 5 membership dependency-injection unity-container asp.net-mvc-3

我有ASP.NET MVC3项目,我想使用自定义成员资格提供程序.另外,我想使用Unity来解决我的依赖注入问题.

这是Global.asax的代码:

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);

        var container = new UnityContainer();
        container.RegisterType<IAuthentification, Authentification>();
        container.RegisterType<IRepository, Repository>();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));

    }
Run Code Online (Sandbox Code Playgroud)

这是我的会员提供者的代码:

public class CustomMembershipProvider : MembershipProvider
{
   [Dependency]
   private IProveaRepository Repository { get; set; }

   public override bool ValidateUser(string username, string password)
    {
       .....
    }
Run Code Online (Sandbox Code Playgroud)

问题是当我将断点放到ValidateUser方法时,我看到Repository属性没有初始化.但这种结构:

   [Dependency]
   private IProveaRepository Repository { get; set; }
Run Code Online (Sandbox Code Playgroud)

例如,在控制器中工作正常.

有人知道为什么会这样,该怎么办?

And*_*per 17

在过去的几天里我遇到了同样的问题.我最终得到了以下解决方案(更改了类型和字段名称以匹配您的).

public class CustomMembershipProvider : MembershipProvider       
{
    private IProveaRepository repository;

    public CustomMembershipProvider() 
        : this (DependencyResolver.Current.GetService<IProveaRepository>())
    { }

    public CustomMembershipProvider(IProveaRepository repository)
    {
        this.repository= repository;
    }

    public override bool ValidateUser(string username, string password)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,即使Unity无法控制构建CustomMembershipProvider,无参数构造函数也会通过MVC3调用Unity DependencyResolver来提供正确的存储库实例.

如果您正在进行单元测试,CustomMembershipProvider那么您可以直接使用Unity构建一个实例,它将使用第二个构造函数并避免调用DependencyResolver.


Tom*_*uλa 1

Unity 无法将 IProveaRepository 实例注入您的自定义会员资格提供程序,因为:

  • 您没有对其进行配置
  • CustomMembershipProvider 不是由统一解析的,因此它无法控制向其中注入依赖项

如果您在代码中使用会员资格 priovider 类,您可以执行以下操作:

尝试将您的 customMembershipProvider 包装在抽象中,例如 IMembershipProvider,它仅具有您使用的方法的签名。结果是这样的:

public class CustomMembershipProvider : MembershipProvider, IMembershipProvider
Run Code Online (Sandbox Code Playgroud)

然后你可以统一注册它:

container.RegisterType<IMembershipProvider, CustomMembershipProvider>(new InjectionProperty(new ResolvedParameter<IProveaRepository>()));
Run Code Online (Sandbox Code Playgroud)

那么约束就是像这样传递控制器中的依赖关系:

public class HomeController : Controller
{
 private IMembershipProvider _membershipprovider;
 public HomeController(IMembershipProvider membershipProvider)
 {
   _membershipProvider = membershipProvider
 }
 // some actions
}
Run Code Online (Sandbox Code Playgroud)

但最好不要使用属性注入,而是使用构造函数注入,如下所示:

public class CustomMembershipProvider : MembershipProvider
{
   private IProveaRepository Repository { get; set; }

   public CustomMembershipProvider(IProveaRepository proveaRepository)
   {
     Repository = proveaRepository
   }

   public override bool ValidateUser(string username, string password)
    {
       .....
    }
Run Code Online (Sandbox Code Playgroud)

这就是我理解和去做的方式。但也许有更好的方法,或者我忽略了一些有助于更轻松地实现它的 Unity API。

无论如何我希望它有帮助。