MVC3,Ninject,MvcSiteMapProvider - 如何将依赖注入到重写方法

Ron*_*rby 7 asp.net-mvc dependency-injection ninject inversion-of-control service-locator

我有一个使用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);
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

MvcSiteMapProvider本身实例化了这个类型,所以我不确定如何将我的存储库注入其中.

我想通过获取内核的句柄并调用Get<Repository>()方法来使用服务位置.但是,在查看NinjectHttpApplication的定义时,我看到了这个属性:

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

Do not use Ninject as Service Locator?!我还应该怎么做呢?然后我在stackoverflow上找到了这个问题,并且所有答案都说不要使用服务位置.

我应该做些什么?

Rem*_*oor 4

这似乎是《为什么提供商的设计不好?》一书中的另一章。对于任何类型的 ASP.NET 提供程序,您都会遇到同样的问题。对于他们来说,没有真正好的、令人满意的解决方案。只是黑客。

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

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