Ninject.MVC 知识点记录

时间:2023-03-08 16:59:20
Ninject.MVC 知识点记录

Ninject 是跟Unity 差不多的DI容器。Ninject 推荐零配置,快速使用。小中型项目,最适合。

通过nuget,安装Ninject.MVC。略。参考博客:Ninject依赖注入     WebForm中使用

场景模拟  项目下载地址:https://coding.net/u/chenxygx/p/CodeSave/git/tree/master/EssentialTools

定义一个计算产品的接口,IValueCalculator,往后都会围绕产品计算,来进行依赖注入。

namespace EssentialTools.Models
{
public interface IValueCalculator
{
decimal ValueProduct(IEnumerable<Product> products);
}
}

IValueCalculator

接下来定义产品实现,LinqValueCalculator

public class LinqValueCalculator : IValueCalculator
{
public decimal ValueProduct(IEnumerable<Product> products)
{
return products.Sum(p => p.Price);
}
}

LinqValueCalculator

Product,就是一个普通的实体类,就不贴了。

然后在控制器中,使用Ninject进行输出。

 public class HomeController : Controller
{
private IValueCalculator calc;
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 flagW",Category="Soccer",Price = 34.95M }
};
// GET: Home
public ActionResult Index()
{
IKernel kernel = new StandardKernel();
kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
IValueCalculator calc = kernel.Get<IValueCalculator>();
return View(calc.ValueProduct(products));
}
}

HomeController

接下来,把Ninject跟MVC进行整合操作。首先需要添加一个Ninject依赖项解析器,NinjectDependencyResolver

 public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
} private void AddBindings()
{
kernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
} public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
}

NinjectDependencyResolver

主要作用就是在页面加载之前,进行依赖注入。然后我们将解析器与MVC关联一下。在App_Start的NinjectWebCommon里面修改

private static void RegisterServices(IKernel kernel)
{
new NinjectDependencyResolver(kernel);
}

这样,在MVC程序运行后,会首先进行依赖注入。然后就可以在需要的时候,控制反转出实例了。

接下来,实现构造器的控制反转

public class HomeController : Controller
{
private IValueCalculator calc;
public HomeController(IValueCalculator calcParam)
{
calc = calcParam;
} // GET: Home
public ActionResult Index()
{
return View(calc.ValueProduct(products));
}
}

HomeController

控制反转会考察依赖项是否依赖其他类型,例如如果LinqValueCalculator,还有依赖项,则也会进行控制反转。

指定属性参数值

可以使用 WithPropertyValue 指定实例中属性的值。

kernel.Bind<IDiscountHelper>().To<DefuaultDicountHelper>().WithPropertyValue("DiscountSize", 50M)

会传递50M到DefuaultDicountHelper里面的 DiscountSize属性。

指定构造器参数

可以使用 WinthConstructorArugment方法指定构造器中参数的值。

 kernel.Bind<IDiscountHelper>().To<DefuaultDicountHelper>().WithConstructorArgument("discountParam",50M);

public DefuaultDicountHelper(decimal discountParam)
{
DiscountSize = discountParam;
}

条件绑定

可以针对依赖注入设置对应条件,例如:要创建 LinqValueCalculator对象时,使用FlexibleDiscountHelper 作为 IDiscountHelper接口的实现。

kernel.Bind<IDiscountHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();

WhenInjectedInto<T>()   当要被注入的类是类型T时,进行绑定

WhenClassHas<T>()   当被注入的类以注解属性进行注释,而类型为T时,进行绑定

作用域

可以设置绑定的作用域

kernel.Bind<IValueCalculator>().To<LinqValueCalculator>().InRequestScope();

InRequestScope()   创建一个单一实例,用于解析一个HTTP请求中各个对象的依赖项

InThreadScope()   创建一个单一实例,将其用于解析一个线程中各个对象的依赖项

InSingletonScope()  使其共享于整个应用程序