我有一个正在使用Ninject和MvcSiteMapProvider的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。但是,到目前为止,这并不是最佳解决方案,因为您应该使实例尽可能靠近根,这会使测试变得更加复杂,并且只为您解决问题。