MVC3, Ninject, MvcSiteMapProvider - Как внедрить зависимость в переопределенный метод - PullRequest
7 голосов
/ 28 октября 2011

У меня есть приложение MVC3, которое использует Ninject и MvcSiteMapProvider .

Я создал этот класс, который MvcSiteMapProvider использует для динамического добавления узлов в мою карту сайта:

public class PageNodeProvider : DynamicNodeProviderBase
{
    public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
    {            
         // need to get repository instance
         var repository = // how do I get this???

         foreach (var item in repository.GetItems())
         {
              yield return MakeDynamicNode(item);
         }
    }
}

MvcSiteMapProvider сам создает экземпляр этого типа, поэтому я не уверен, как внедрить в него мой репозиторий.

Я думал об использовании расположения службы, получив дескриптор моего ядра и вызвав егоGet<Repository>() в методе.Но я увидел это свойство, глядя на определение NinjectHttpApplication:

    // Summary:
    //     Gets the kernel.
    [Obsolete("Do not use Ninject as Service Locator")]
    public IKernel Kernel { get; }

Do not use Ninject as Service Locator?!Как еще я должен это сделать?Затем я нашел этот вопрос здесь в stackoverflow , и во всех ответах говорится, что не использовать расположение службы.

Что я должен делать?

Ответы [ 2 ]

4 голосов
/ 29 октября 2011

Это, кажется, еще одна глава из книги «Почему провайдеры плохого дизайна?». У вас та же проблема, что и с любыми поставщиками ASP.NET. Для них нет действительно хороших и удовлетворительных решений. Просто хаки.

Я думаю, что лучший вариант, который у вас есть, - это разветвить проект и изменить DefaultSiteMapProvider, чтобы использовать DepencencyResolver вместо Activator и предоставить реализацию обратно сообществу. Затем вы можете использовать инжектор конструктора в вашей реализации PageNodeProvider. Это решит проблему один раз для всех типов и для всех.

Конечно, вы также можете использовать DependencyResolver только в вашей реализации. Но это далеко не лучшее решение, потому что вы должны располагать экземпляры как можно ближе к корню, это усложняет тестирование и решает проблему только для вас.

1 голос
/ 18 апреля 2012

Несмотря на то, что я вижу, что вы решили полностью отказаться от провайдера, я бы хотел подробнее остановиться на использовании DependencyResolver.По сути, вы можете вручную получить правильный экземпляр репозитория через Ninject, используя

var repository = DependencyResolver.Current.GetService<IRepository>();

Это менее надежно, так как вы должны поддерживать это так же, как и класс NinjectMVC3.cs, если материал меняется,немного сложнее, чтобы проверить.

...