我有一个正在使用NinjectMvcSiteMapProvider的MVC3应用程序。

我创建了此类,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本身会实例化此类型,因此我不确定如何将存储库注入(inject)其中。

我考虑过通过在内核上获取一个句柄并在该方法中调用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?!我应该怎么做呢?
然后我发现this question here on stackoverflow,所有答案都说不使用服务位置。

我应该做些什么?

最佳答案

这似乎是“为什么提供者是不良设计?”这本书的另一章。您遇到与任何类型的ASP.NET提供程序相同的问题。对于他们来说,没有真正好的和令人满意的解决方案。只是骇客。

我认为您最好的选择是派生项目,并将DefaultSiteMapProvider更改为使用DepencencyResolver而不是Activator,然后将实现提供回社区。然后,您可以在PageNodeProvider实现中使用构造函数注入(inject)。这将为所有类型和每个人解决一次该问题。

当然,您也可以仅在实现中使用DependencyResolver。但是,到目前为止,这并不是最佳解决方案,因为您应该使实例尽可能靠近根,这会使测试变得更加复杂,并且只为您解决问题。

09-25 21:43