7

我有一个使用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 自己实例化这种类型,所以我不确定如何将我的存储库注入其中。

我考虑通过获取内核句柄并调用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上找到了这个问题,所有答案都说不要使用服务位置。

我应该做些什么?

4

2 回答 2

4

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

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

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

于 2011-10-29T01:22:29.820 回答
1

尽管我看到您已决定完全放弃提供程序,但我还是想详细说明使用 DependencyResolver。基本上,您可以使用 Ninject 手动获取正确的存储库实例

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

这不太健壮,因为如果内容发生变化,您必须维护它以及 NinjectMVC3.cs 类,并且测试起来有点复杂。

于 2012-04-18T15:10:18.437 回答