MVC3、Ninject、MvcSiteMapProvider - 如何将依赖项注入到重写方法
我有一个使用 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
来使用服务定位。但是,我在查看 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 上,所有答案都说不要使用服务位置。
我该怎么办?
I have an MVC3 application that is using Ninject and MvcSiteMapProvider.
I have created this class which MvcSiteMapProvider uses to dynamically add nodes to my sitemap:
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);
}
}
}
The MvcSiteMapProvider instantiates this type itself, so I'm not sure how to inject my repository into it.
I thought about using service location by getting a handle on my kernel and calling Get<Repository>()
in the method. But, I saw this property when looking at the definition of NinjectHttpApplication:
// Summary:
// Gets the kernel.
[Obsolete("Do not use Ninject as Service Locator")]
public IKernel Kernel { get; }
Do not use Ninject as Service Locator
?! How else am I supposed to do this?
I then found this question here on stackoverflow and all answers say don't use Service Location.
What am I supposed to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这似乎是《为什么提供商的设计不好?》一书中的另一章。对于任何类型的 ASP.NET 提供程序,您都会遇到同样的问题。对于他们来说,没有真正好的、令人满意的解决方案。只是黑客。
我认为最好的选择是分叉该项目并更改 DefaultSiteMapProvider 以使用 DepenencyResolver 而不是 Activator 并将实现提供回社区。然后您可以在 PageNodeProvider 实现中使用构造函数注入。这将为所有类型和所有人一次性解决问题。
当然,您也可以在实现中使用 DependencyResolver。但这到目前为止还不是最好的解决方案,因为您应该让实例尽可能接近根,这会使测试变得更加复杂,并且它只为您解决问题。
This seems to be another chapter from the book "Why providers are bad design?". You have the same problem as with any kind of ASP.NET providers. There are no really good and satisfying solutions for them. Just hacks.
I think the best option you have is to fork the project and change the DefaultSiteMapProvider to use DepencencyResolver instead of the Activator and provide the implementation back to the community. Then you can use constructor injection in your PageNodeProvider implementation. This will solve the problem once for all types and everyone.
Of course you could also use the DependencyResolver just in your implementation. But this is by far not the best solution because you should get the instances as close to the root as possible, it makes testing more complicated and it solves the problem just for you.
尽管我看到您已决定完全放弃提供程序,但我仍想详细说明如何使用 DependencyResolver。基本上,您可以使用 Ninject 手动获取正确的存储库实例。
这不太健壮,因为如果内容发生变化,您必须维护它以及 NinjectMVC3.cs 类,并且测试起来有点复杂。
Even though I see that you've decided to ditch the provider altogether, I'd like to elaborate on using the DependencyResolver. Basically, you can manually get the correct repository instance via Ninject using
This is less robust, as you have to maintain this as well as the NinjectMVC3.cs class should the stuff change, and it is a bit more complicated to test.