Внедрение зависимостей с помощью пользовательского поставщика - PullRequest
11 голосов
/ 02 мая 2010

У меня есть веб-приложение ASP.NET MVC, которое реализует пользовательский поставщик членства. Пользовательский поставщик членства получает UserRepository своему конструктору, который обеспечивает интерфейс между поставщиком членства и NHibernate. UserRepository предоставляется контейнером Ninject IoC.

Очевидно, однако, что это не работает, когда поставщик создается в .NET: конструктор без параметров не имеет UserRepository и не может его создать (UserRepository требует, чтобы сеанс NHibernate передавался его конструктору), что затем что провайдер не может получить доступ к своему хранилищу данных. Как я могу разрешить мою объектную зависимость?

Вероятно, стоит отметить, что это существующее приложение, которое было модифицировано с помощью Ninject. Ранее я использовал конструкторы без параметров, которые могли создавать требуемые зависимости в сочетании с конструкторами с параметрами, чтобы помочь модульному тестированию.

Есть какие-нибудь мысли, или я здесь загнал себя в угол?

Ответы [ 4 ]

5 голосов
/ 12 декабря 2012

Правильный ответ от Майкла Б. от: Внедрение зависимостей и поставщиков членства в ASP.Net

Вы можете получить инъекцию хранилища (или службы) следующим образом:

public IRepository Repository { get { return DependencyResolver.Current.GetService(IRepository ); } }
5 голосов
/ 02 мая 2010

Возможно, вы захотите сохранить конструктор без параметров, который инициализирует необходимые репозитории с помощью Ninject. Возможно, вы захотите использовать Common Service Locator , поэтому вам не нужно будет иметь ни ссылку на Ninject, ни ее контейнер внутри вашего собственного провайдера. Похоже, что у Ninject нет официальной реализации адаптера для CSL, но написание ее не должно быть трудным (проверьте другие реализации, такие как Виндзор), и я уверен, что где-то есть неофициальная реализация.

4 голосов
/ 08 ноября 2010

Поскольку коллекция членства и экземпляр MemberShip.Provider созданы до того, как Ninject сможет их создать, необходимо выполнить активацию после создания объекта. Если вы пометите свои зависимости [Inject] для своих свойств в классе провайдера, вы можете вызвать kernel.Inject (MemberShip.Provider) - это назначит все зависимости вашим свойствам.

0 голосов
/ 02 мая 2010

У меня была такая же проблема, я решил ее, передав необходимые данные с помощью билета аутентификации в объект идентификации.

Тогда нет необходимости вводить объекты в поставщики членства.

В моем коде аутентификации у меня есть

    [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, которые возвращают части строки заявки.

...