自定义成员资格提供程序的依赖注入

发布于 2024-08-31 08:57:18 字数 459 浏览 7 评论 0原文

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

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

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

有什么想法,还是我把自己逼到了一个角落?

I have an ASP.NET MVC web application that implements a custom membership provider. The custom membership provider takes a UserRepository to its constructor that provides an interface between the membership provider and NHibernate. The UserRepository is provided by the Ninject IoC container.

Obviously, however, this doesn't work when the provider is instantiated by .NET: the parameterless constructor does not have a UserRepository and cannot create one (the UserRepository requires an NHibernate session be passed to its constructor), which then means that the provider cannot access its data store. How can I resolve my object dependency?

It's probably worth noting that this is an existing application that has been retrofitted with Ninject. Previously I used parameterless constructors that were able to create their required dependencies in conjunction with the parametered constructors to assist unit testing.

Any thoughts, or have I built myself into a corner here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

您可能希望保留无参数构造函数,它使用 Ninject 初始化所需的存储库。您可能想要使用公共服务定位器,因此您不需要引用 Ninject 或它是您的自定义提供程序内的容器。看起来 Ninject 没有针对 CSL 的官方适配器实现,但是编写一个适配器应该不难(检查其他实现,例如 Windsor 的实现),并且我确信某个地方有一个非官方实现。

You might want to keep the parameterless constructor, that initializes the needed repositories using Ninject. You might want to use the Common Service Locator, so you won't need to have neither a reference to Ninject nor it's container inside your custom provider. It seems Ninject doesn't have an official an adapter implementation for CSL, but writing one shouldn't be to hard (check the other implementations, like Windsor's), and I'm sure there's an unofficial implementation somewhere.

残花月 2024-09-07 08:57:18

Michael B. 的正确答案来自: 依赖注入和 ASP.Net会员提供者

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

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

Correct answer from Michael B. from: Dependency injection and ASP.Net Membership Providers

You can obtain your repository (or service) injection in this way:

public IRepository Repository { get { return DependencyResolver.Current.GetService(IRepository ); } }
最偏执的依靠 2024-09-07 08:57:18

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

Since the membership collection and the MemberShip.Provider instance are created before Ninject can instantiate them, you need to perform post creation activation on the object. If you mark your dependencies with [Inject] for your properties in your provider class, you can call kernel.Inject(MemberShip.Provider) - this will assign all dependencies to your properties.

冷弦 2024-09-07 08:57:18

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

然后不需要将任何对象注入到成员资格提供程序中。

在我的身份验证代码中

    [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 属性,它们返回票证字符串的一部分。

I had same problem, I solved it by passing required data using authentication ticket to identity object.

Then no objects need to be injected into membership providers.

In my authentication code I have

    [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);
    }

And in 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);
            }
        }
    }

And in Identity class I have MemberName, Firstname and Lastname properties that return parts of ticket string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文