【问题标题】:Dependency Injection with Custom Membership Provider使用自定义成员资格提供程序进行依赖注入
【发布时间】:2010-05-02 12:19:44
【问题描述】:

我有一个实现自定义成员资格提供程序的 ASP.NET MVC Web 应用程序。自定义成员资格提供程序将UserRepository 传递给它的构造函数,该构造函数提供成员资格提供程序和 NHibernate 之间的接口。 UserRepository 由 Ninject IoC 容器提供。

然而,显然,当提供程序由 .NET 实例化时,这不起作用:无参数构造函数没有 UserRepository 并且无法创建(UserRepository 需要将 NHibernate 会话传递给它的构造函数),这意味着提供者无法访问其数据存储。如何解决我的对象依赖性?

可能值得注意的是,这是一个使用 Ninject 改造的现有应用程序。以前,我使用无参数构造函数,它们能够与有参数构造函数一起创建所需的依赖项,以协助单元测试。

有什么想法,还是我把自己困在了这里?

【问题讨论】:

    标签: asp.net asp.net-mvc dependency-injection ninject ninject-2


    【解决方案1】:

    您可能希望保留使用 Ninject 初始化所需存储库的无参数构造函数。您可能想要使用Common Service Locator,因此您既不需要引用 Ninject 也不需要它是自定义提供程序中的容器。似乎 Ninject 没有针对 CSL 的官方适配器实现,但编写一个应该不难(检查其他实现,如 Windsor 的),而且我确信某处有一个非官方的实现。

    【讨论】:

    • Ninject 于 2010 年 1 月拥有官方 CSL 适配器。
    • CSL 主页中仍然缺少它(它包含在 NInject 版本中)
    • "构造函数,使用 Ninject 初始化所需的存储库" - 注意,如果您的存储库(或它们的依赖项)在请求或瞬态范围内并且任何类型的一次性数据上下文开始发挥作用,您将最终访问除第一个请求之外的所有数据上下文(因为您不控制提供者的生命周期,而 ASP.NET 将在请求之间重用它)。当我遇到这个问题时,每次我需要调用定位器时,我最终都会从定位器中获取一个存储库实例。
    • Fabio70a 的评论:这是解决方案:stackoverflow.com/questions/1551503/…
    【解决方案2】:

    Michael B. 的正确答案来自:Dependency injection and ASP.Net Membership Providers

    您可以通过这种方式获取您的存储库(或服务)注入:

    public IRepository Repository { get { return DependencyResolver.Current.GetService(IRepository ); } }
    

    【讨论】:

      【解决方案3】:

      由于成员集合和 MemberShip.Provider 实例是在 Ninject 实例化它们之前创建的,因此您需要对对象执行创建后激活。如果您在提供程序类中为您的属性使用 [Inject] 标记您的依赖项,则可以调用 kernel.Inject(MemberShip.Provider) - 这会将所有依赖项分配给您的属性。

      【讨论】:

      • 听起来不错;我用 CSL 解决了这个问题,但可能值得重新访问以删除额外的依赖项。
      • 你会在哪里调用 kernel.Inject...?
      【解决方案4】:

      我有同样的问题,我通过使用身份验证票将所需数据传递给身份对象来解决它。

      那么不需要将对象注入到成员资格提供者中。

      在我的验证码中有

          [NonAction]
          private void SetAuthTicket(Member member, bool isPersistent)
          {
              HttpCookie cookie = Request.Cookies.Get(FormsAuthentication.FormsCookieName);
      
              FormsAuthentication.SetAuthCookie(member.Email, isPersistent);
      
              string userData = "|" + member.ID + "|" + member.Firstname + "|" + member.Lastname + member.Culture;
      
              FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, member.Email, DateTime.UtcNow, DateTime.UtcNow.AddDays(7), isPersistent, userData);
      
              string encryptedTicket = FormsAuthentication.Encrypt(ticket);
              cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
              Response.Cookies.Add(cookie);
          }
      

      在 Global.asax 中

          void Application_OnPostAuthenticateRequest(object sender, EventArgs e)
          {
              IPrincipal user = HttpContext.Current.User;
              if (user.Identity.IsAuthenticated && user.Identity.AuthenticationType == "Forms")
              {
                  FormsIdentity identity = user.Identity as FormsIdentity;
      
                  MyIdentity ai = new MyIdentity(identity.Ticket);            
                  MyPrincipal p = new MyPrincipal(ai);
      
                  HttpContext.Current.User = p;
                  System.Threading.Thread.CurrentPrincipal = p;
      
                  if (!String.IsNullOrEmpty(ai.Culture))
                  {
                      CultureInfo ci = new CultureInfo(ai.Culture);
                      System.Threading.Thread.CurrentThread.CurrentUICulture = ci;
                      System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
                  }
              }
          }
      

      在 Identity 类中,我有 MemberName、Firstname 和 Lastname 属性,它们返回票证字符串的一部分。

      【讨论】:

      • 请您再详细一点吗?例如,您的场景中的 CreateUser() 函数将如何覆盖?你是说在我的场景中我必须在身份验证票中传递存储库对象吗?
      • 而不是传递存储库传递用户 ID
      • 什么??我同意@alasairs,你如何在没有存储库的情况下创建用户和其他东西?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多