我目前正在启动ASP.NET MVC 4,在我正在阅读的书中,作者介绍了Ninject进行依赖项注入。他创建了一个自定义的依赖项解析器(我不完全了解它的工作原理,但我认为它的用途是轻松管理依赖项解析)。
这是控制器代码:
public class HomeController : Controller
{
private Product[] products = {
new Product {Name = "Kayak", Category = "Watersports", Price = 275M},
new Product {Name = "Lifejacket", Category = "Watersports", Price = 48.95M},
new Product {Name = "Soccer ball", Category = "Soccer", Price = 19.50M},
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M}
};
private IValueCalculator calc;
public HomeController(IValueCalculator calcParam)
{
calc = calcParam;
}
public ActionResult Index()
{
ShoppingCart cart = new ShoppingCart(calc) { Products = products };
decimal totalValue = cart.CalculateProductTotal();
return View(totalValue);
}
}
和自定义依赖项解析器:
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver()
{
kernel = new StandardKernel();
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
}
}
在Application_Start()中,设置了解析器:
DependencyResolver.SetResolver(new NinjectDependencyResolver());
问题:
ASP.NET MVC如何知道要调用哪个控制器构造函数?我以为它将要调用默认构造函数,但没有一个,我尝试添加一个,但仍调用了带有参数的构造函数。
ASP.NET MVC如何将IValueCalculator传递给构造函数?
这是来自文档的引用(https://github.com/ninject/ninject/wiki/Dependency-Injection-With-Ninject):
当要求实例化一个对象时,Ninject将查看该类型可用的公共构造函数,并选择具有其知道如何解析的参数最多的一个-如果没有合适的参数,则选择无参数的一个(有一个可以使用的属性)要覆盖它,请参阅构造函数注入以了解更多细节)。
以及来自这里的另一个报价(https://github.com/ninject/ninject/wiki/Injection-Patterns):
如果构造函数具有[Inject]属性,则将使用它(但是,如果
将该属性应用于多个属性,则Ninject
在检测到运行时会抛出NotSupportedException)。如果没有构造函数具有[Inject]属性,则Ninject将选择Ninject
能够解析的参数最多的一个。如果未定义构造函数,则Ninject将选择默认的无参数构造函数(假设有一个)。
以及ASP.NET MVC如何将IValueCalculator传递给构造函数?
整个MVC管道使用控制器工厂来构建特定控制器的实例。控制器工厂在内部使用DependencyResolver。这就是为什么在应用程序启动时注册依赖解析器的原因:
DependencyResolver.SetResolver(new NinjectDependencyResolver());
正如我之前写的,Ninject知道如何找到正确的构造函数并使用它来构建实例。它找到以下构造函数:
public HomeController(IValueCalculator calcParam)
依赖解析器用于查找的实现IValueCalculator
,该实现在此处定义:
private void AddBindings()
{
kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
}
Ninject在这里再次尝试为class查找构造函数LinqValueCalculator
。如果构造函数具有依赖项,则将使用相同的机制注入它们。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句