依赖注入(DI)就不多说了,可以自行百度,本笔记整理自Pro ASP.NET MVC5。

1,Ninject安装

Ninject是一个开源的注入容器,可以通过VS的Nuget进行安装。由于是在mvc中应用,需要安装下面3个类库。

  • Ninject
  • Ninject.Web.Common
  • Ninject.Web.Mvc

2,简单使用

在没有用DI之前,我们通常是这样写的。

        // GET: Home
public ActionResult Index()
{
IValueCalculator calc = new LinqValueCalculator(); ShoppingCart cart = new ShoppingCart(calc);
cart.Products = products; decimal totalValue = cart.CalulateProductTotal(); return View(totalValue);
}

我们的目标是,不去new LinqValueCalculator,这样才会消除依赖,于是利用Ninject变成下面这样。

        public ActionResult Index()
{ IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<IValueCalculator>().To<LinqValueCalculator>();
IValueCalculator calc = ninjectKernel.Get<IValueCalculator>(); ShoppingCart cart = new ShoppingCart(calc);
cart.Products = products; decimal totalValue = cart.CalulateProductTotal(); return View(totalValue);
}

简单的3句代码,建立起了IValueCalculator和LinqValueCalculator之间的映射关系,然后调用Get方法获得实例。

这样做了之后,我们就不用再new了,但是这远远不够,Controler类中依然存在LingValueCalculator和额外的Ninject的类,

我们需要把这些代码移出Controler类。

3,改进Ninject,达到真正的解耦

1)在Controler的构造函数中传入IValueCalculator

    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.5M },
new Product {Name = "Corner flag", Category = "Soccer", Price = 34.95M }
}; public HomeController(IValueCalculator calc)
{
this.calc = calc;
} // GET: Home
public ActionResult Index()
{
ShoppingCart cart = new ShoppingCart(calc);
cart.Products = products; decimal totalValue = cart.CalulateProductTotal(); return View(totalValue);
}
}

难道构造函数中的IValueCalculator会自动初始化?是的,这就是Ninject帮你做的,但必须先按照下面这样做。

2)实现IDependecyResolver接口,这个接口是MVC自带的,不是Ninject的。实现了这个接口,MVC框架才会自动按照上面那样创建对应接口的实例。

    public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernal; public NinjectDependencyResolver(IKernel kernalParam)
{
kernal = kernalParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernal.TryGet(serviceType);
} public IEnumerable<object> GetServices(Type serviceType)
{
return kernal.GetAll(serviceType);
} public void AddBindings()
{
kernal.Bind<IValueCalculator>().To<LinqValueCalculator>().InRequestScope();
kernal.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithConstructorArgument("discount", 10m);
kernal.Bind<IDiscountHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();
}
}

GetService和GetServices是接口的方法,大致就是传入一个接口类型,然后传出去一个实例。

你完全可以自己简单的实现这两个方法,但是Ninject毕竟是经受了考验的,各种配置齐全的DI容器,本文的主旨也就是介绍Ninject,所以用Ninject实现这两个方法。

具体就是上面这样,所有的映射关系放在了AddBinding这个方法中,以后只用修改这个方法,就可以全局改变不同的实现。

3)NinjectDependencyResolver的初始化

上面的这个NinjectDependencyResolver需要初始化,在添加Njinect类库的时候,在App_Start下,生成了一个NinjectWebCommon.cs文件,其中有一个RegisterServices方法,

这个方法会在应用程序初始化的时候调用,所以我们就在这里初始化我们的NinjectDependencyResolver。

    public static class NinjectWebCommon
{
。。。
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
System.Web.Mvc.DependencyResolver.SetResolver(new
EssentialTools.Infrastructure.NinjectDependencyResolver(kernel));
}
}

好了,到此为止,我们就可以在Controler这个类的构造函数任意的传人需要使用的接口,只要在NinjectDependencyResolver中添加对应的映射,Ninject就会自动的帮我们创建好。

4)Ninject不是简单的new,它可以在建立映射的时候配置不同的选项,下面例举几个重要的配置选项。

  • 创建对象的生命周期的控制
kernal.Bind<IValueCalculator>().To<LinqValueCalculator>().InRequestScope();
  • 创建对象的构造函数参数的设置(属性值也可以设置)
kernal.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithConstructorArgument("discount", 10m);
  • 建立的映射的适用条件
kernal.Bind<IDiscountHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();
  • 实例初始化时,又依赖于其他接口时,Ninject会把依赖的所有接口一并初始化,这一点我们自己实现的话可能会比较困难。

以上就是Ninject的简单介绍,更加详尽的功能,可以查阅相关文档。另外,微软自带的Utinity也是和Ninject相似的DI容器,有了Ninject的使用经验,

再用其他的DI容器应该也不是很困难。

依赖注入:Ninject学习笔记的更多相关文章

  1. ASP.NET Core快速入门(第3章:依赖注入)--学习笔记

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务16:介绍 1.依赖注入概念详解 从UML和软件建模来理解 从单元测试来理 ...

  2. spring 控制反转与依赖注入原理-学习笔记

    在Spring中有两个非常重要的概念,控制反转和依赖注入:控制反转将依赖对象的创建和管理交由Spring容器,而依赖注入则是在控制反转的基础上将Spring容器管理的依赖对象注入到应用之中: 所谓依赖 ...

  3. Ninject学习笔记<二>

    本文转载自kuangkro 如果给您带来不便请联系博主 一.控制反转和依赖注入 Ninject是一个轻量级的基于.Net平台的依赖注入(IOC)框架.所谓的IOC,即控制反转(Inversion of ...

  4. Spring.NET依赖注入框架学习--实例化容器常用方法

    Spring.NET依赖注入框架学习---实例化容器常用方法 本篇学习实例化Spring.NET容器的俩种方式 1.通过XmlObjectFactory创建一个Spring.NET容器 IResour ...

  5. Spring.NET依赖注入框架学习--简单对象注入

    Spring.NET依赖注入框架学习--简单对象注入 在前面的俩篇中讲解了依赖注入的概念以及Spring.NET框架的核心模块介绍,今天就要看看怎么来使用Spring.NET实现一个简单的对象注入 常 ...

  6. Spring.NET依赖注入框架学习--简介

    Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...

  7. Spring.NET依赖注入框架学习--入门

    Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...

  8. Spring.NET依赖注入框架学习-- 泛型对象的创建和使用

    Spring.NET依赖注入框架学习-- 泛型对象的创建和使用 泛型对象的创建方法和普通对象是一样的. 通过构造器创建泛型对象 下面是一个泛型类的代码: namespace GenericsPlay ...

  9. Ninject学习笔记<一>

    本文转载自永远的阿哲 如果给您带来不便请联系博主. Ninject是一款.Net平台下的开源依赖注入框架.按照官方说法,它快如闪电.超级轻量,且充分利用了.Net的最新语法,使用Lambda表达式代替 ...

随机推荐

  1. CentOS扩展库配置

    背景:经常用到第三方的库,通过yum命令查询不到.例如:yum search ilbcWarning: No matches found for: ilbc 不要感叹,CentOS没你想象的支持力度那 ...

  2. xml中的<![CDATA[]]> 简介

    被<![CDATA[]]>这个标记所包含的内容将表示为纯文本,比如<![CDATA[<]]>表示文本内容“<”.  此标记用于xml文档中,我们先来看看使用转义符的 ...

  3. 【转载】centos7.3 防火墙配置

    firewalld介绍原文:https://www.cnblogs.com/moxiaoan/p/5683743.html 一. centos7 默认有一个防火墙 firewalld,具体使用如下: ...

  4. python selenium 报错unknown error: cannot focus element 解决办法

    登录框由于js限制,定位到元素后无法sendkey ,sendky报错如下: selenium.common.exceptions.WebDriverException: Message: unkno ...

  5. category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性

    属性 其实就是get/set 方法.我们可以使用  objc_setAssociatedObject/objc_getAssociatedObject  实现 动态向类中添加 方法 @interfac ...

  6. Android USB配件模式

    原文:http://android.eoe.cn/topic/android_sdk USB配件模式允许用户连接那些专门搭载Android设备的USB主机硬件.这些配件必须遵守Android配件开发工 ...

  7. Datagrid分页、排序、删除代码

    <%@ Page language="c#" Codebehind="default.aspx.cs" AutoEventWireup="fal ...

  8. Serizlizable

    关闭   忧郁王子的专栏 伟大的意大利,伟大的罗伯特-巴乔       目录视图 摘要视图 订阅 赠书 | 异步2周年,技术图书免费选      每周荐书:分布式.深度学习算法.iOS(评论送书)   ...

  9. Rational Rose 2003 下载及破解方法

    FROM:http://blog.csdn.net/fenglibing/archive/2007/08/17/1747693.aspx 这么好的东西,不拿来出分享,我对不起原作者呀.但是我这里不知道 ...

  10. ASP.NET MVC中全局异常处理

    以前不知道从哪里找到的处理全局异常的,觉得蛮好用就记下来了. 1, 建立MyExecptionAttribute.cs类,写入如下代码: using System; using System.Coll ...