松耦合、针对抽象编程、不针对实现编程是面向对象设计的原则。依赖注入就是,在一个类的内部,不通过创建对象的实例而能够获得实现了某个公开接口的对象引用。所谓的控制反转也是相同的意思。把依赖的创建转移到了使用这些依赖的类的外部,反转的是依赖的创建。控制反转可以是通过依赖注入和服务定位器模式来实现。依赖注入特别适用于复杂的依赖关系的程序中。

在Asp.net MVC程序中,经常使用仓储模式来分离控制器和数据访问层。有利于进行单元测试和测试驱动开发(TDD)。

实现依赖注入可以使控制器和使用的仓储层相互独立,使用控制器减少了对仓储层的依赖。依赖注入可以通过直接构造方法注入和属性注入、IOC容器注入三种方式。

在Asp.net MVc中,使用NInject 实现依赖注入的步骤如下

1、安装 Ninject

在VS中在程序包管理控制台中输入 Install-Package Ninject -Project ApplicationName。则NuGet或自动下载和安装、引用Ninject的程序集。也可以直接使用 vs 的 工具 的管理窗口操作抽完Nuget下载。

2、 可以有两种方式。

第一种:

1、:建立一个控制器工厂类,接管控制器对象的创建。在ASP.NET MVC中,一个客户端请求是在特定Controller的Action中进行处理的。 默认情况下,ASP.NET MVC使用内置的Controller工厂类 DefaultControllerFactory来创建某个请求对应的Controller实例。有时候默认的Controller工厂不能满足我们实际的需求,我们就需要对这种默认行为进行扩展,即创建一个继承自DefaultControllerFactory类的自定义Controller工厂类并重写其中的一些方法。

public class NinjectControllerFactory: DefaultControllerFactory

{

private IKernel ninjectKernel;

protected override IController GetControllerInstance(RequestContext request requestContext,Type controllerType)

{

return controllerType== null ?null :(IController)njinectKernel.Get(controllerType);

}

// 添加绑定。

private void AddBindings()

{

_kernel.Bind<IStudentRepository>().To<StudentRepository>();

}

}

上面代码中的 ninjectKernel.Get(controllerType) 可获取到一个Controller实例。在这里如果手动实例化Controller类是一个非常复杂的过程,我们不知道Controller类有没有带参数的构造函数,也不知道构造函数的参数是什么类型。而使用Ninject只需要使用上面的一个Get方法就可以,Ninject内部会自动处理所有的依赖关系,智能地创建我们需要的对象。

2、需在Global.asax文件的Application_Start方法中添加下面代码:

protected void Application_Start() {
...... //设置Controller工厂
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
} 第二种方式:实现 System.Web.MVc 命名空间下的IDepenednctyResolver接口
完整的代码如下:
1、模型类:Student

public class Student
{
public int ID { get; set; }

public string LastName { get; set; }

public string FirstName { get; set; }

public DateTime EnrollmentDate { get; set; }

public string FullName
{
get { return FirstName + LastName; }
}
}
}

2、建立仓储接口  IStudentRepository类,和实现接口StudentRepository类

public interface IStudentRepository:IDisposable
{
  IQueryable <Student> GetStudents();  //IQueryable<>和IEumrable<>都可以,但使用 IQueryable<>效率高一些,因为他是延迟查询,只会查出需要使用的数据。为什么用IQueryable而不用IEnumerable作为返回类型?答案是:使用IQueryable,EF会根据调用者的Linq表达式先生成相应的SQL查询语句,然后到数据库中执行查询,查询出来的数据即是用户想要的数据;而使用IEnumerable,Linq表达式的过滤、排序等操作都是在内存中发生的,即EF会先从数据库中把整个表的数据查询出来放在内存中,然后由调用者使用Linq语句进行过滤、排序等操作。

IQueryable虽然可以很智能地根据Linq表达式生成相应的SQL语句,但毕竟有一个分析Linq表达式的过程,相对来说性能比IEnumerable要差。那么我们什么时候用IEnumerable,什么时候用IQueryable呢?我想,对于少量的数据(比如从数据库中读取应用程序相关的系统信息)和不需要对数据进行过滤操作的情况,用IEnumerable比较适合;对于数据量较大需要对数据进行过滤(比如分页查询)的情况,则用IQueryable比较合适

Student GetStudentByID(int? studetnID);
void InsertStduent(Student student);
void DeleteStudent(int? studentID);
void UpdateStudent(Student student);
void Save();
}

//实现仓储接口。

public class StudentRepository:IStudentRepository,IDisposable
{
private SchoolContext context;

public StudentRepository(SchoolContext context)
{
this.context = context;
}
public IQueryable <Student> GetStudents()

{
return context.Students.ToList();
}

public Student GetStudentByID(int? studetnID)
{
return context.Students.Find(studetnID);
}

public void InsertStduent(Student student)
{
context.Students.Add(student);
}

public void DeleteStudent(int? studentID)
{
Student student = context.Students.Find(studentID);
context.Students.Remove(student);
}

public void UpdateStudent(Student student)
{
context.Entry(student).State = EntityState.Modified;
}

public void Save()
{
context.SaveChanges();
}

private bool disposed = false;

protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

3、实现IDendenctyResolver接口的 NinjectDependencyResolver。

public class NinjectDependencyResolver:IDependencyResolver
{
private readonly IKernel _kernel;       //创建Ninject内核实例

public NinjectDependencyResolver()
{
_kernel = new StandardKernel();
AddBindings();
}

private void AddBindings()    //绑定接口到实现了该接口的类

{
    _kernel.Bind<IStudentRepository>().To<StudentRepository>();
 // _kernel.Bind<IStudentRepository>().To<StudentRepositoryInMemory>();

}

public object GetService(Type serviceType)   //【实现IDendcyResolver 接口的两个方法
{
return _kernel.TryGet(serviceType);
}

public IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType);
}
}

4、同样需要的 globe.asax 中注册依赖解析器

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);

DependencyResolver.SetResolver(new NinjectDependencyResolver()); //注册依赖解析容器。
}

5、控制器

public class StudentController : Controller
{
private IStudentRepository studentRepository;
//如果你正使用Dependenty injection 或者DI,你不需要默认的构造方法,因为DI软件将始终保证正确的仓储对象被提供。
public StudentController(IStudentRepository studentRepository)
{
this.studentRepository = studentRepository;
}

// GET: Student
public ActionResult Index()
{
return View(studentRepository.GetStudents());
}

StudentController的构造函数接受了一个IStudentRepository参数,当StudentController被实例化的时候,Ninject就为其注入了StudentRepository的依赖。
6、修改由基架自动生成的控制器方法,控制器由直接访问 数据库上下文变成访问 仓储接口。

// GET: Student
public ActionResult Index()
{
return View(studentRepository.GetStudents());
} 另外:还可以使用 Kernel内核对象来获取 接口的实现,比如
Student student =ninjectKernel.Get<IStudentRepository>(); GET<>方法返回的是绑定的 StudentRepository对象。

Asp.net MVC 中使用 Ninject 实现依赖注入的更多相关文章

  1. ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC中使用Unity进行依赖注入的三种方式 2013-12-15 21:07 by 小白哥哥, 146 阅读, 0 评论, 收藏, 编辑 在ASP.NET MVC4中,为了在解开C ...

  2. 在ASP.NET MVC中使用Unity进行依赖注入的三种方式

    在ASP.NET MVC4中,为了在解开Controller和Model的耦合,我们通常需要在Controller激活系统中引入IoC,用于处理用户请求的 Controller,让Controller ...

  3. [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject

    本人博客已转移至:http://www.exblr.com/liam  为什么需要依赖注入 在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特征是关注点分离( ...

  4. ASP.NET MVC中使用Ninject

    ASP.NET MVC中使用Ninject 在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事 ...

  5. ASP.NET Core 中的框架级依赖注入

    https://tech.io/playgrounds/5040/framework-level-dependency-injection-with-asp-net-core 作者: Gunnar P ...

  6. 【ASP.NET MVC 学习笔记】- 04 依赖注入(DI)

    本文参考:http://www.cnblogs.com/willick/p/3223042.html 1.在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用.这种"需 ...

  7. 【ASP.NET MVC 学习笔记】- 05 依赖注入工具Ninject

    本文参考:http://www.cnblogs.com/willick/p/3223042.html 1.Ninject是一款轻量级的DI工具,可通过VS的插件NuGet将其引用到项目中. 2.使用N ...

  8. ASP.NET Web API和ASP.NET Web MVC中使用Ninject

    ASP.NET Web API和ASP.NET Web MVC中使用Ninject 先附上源码下载地址 一.准备工作 1.新建一个名为MvcDemo的空解决方案 2.新建一个名为MvcDemo.Web ...

  9. 在ASP.NET Web API和ASP.NET Web MVC中使用Ninject

    先附上源码下载地址 一.准备工作 1.新建一个名为MvcDemo的空解决方案 2.新建一个名为MvcDemo.WebUI的空MVC应用程序 3.使用NuGet安装Ninject库   二.在ASP.N ...

随机推荐

  1. argument to nsmutablearray method addobject cannot be nil 警告

    You cannot add nil to an NSMutableArray, and you will raise an exception if you try to. There's NSNu ...

  2. 【js html】对于<img>图片的引用填充,src可以给什么值?

    平时多见的<img>的使用,常见于如下: <img class="img-responsive img-rounded" src="static/img ...

  3. BUPT 2012复试机考 2T

    题目描述 ​给你一个n*n的矩阵, , 求其矩阵的k次幂,即Pk 输入格式 第一行,一个整数T(0<T<=10),表示要求矩阵的个数. 接下来有T组数据,每组数据格式如下: 第一行:两个数 ...

  4. JS判断访问设备(userAgent)加载不同页面 JS判断客户端操作系统类型(platform)

    //平台.设备和操作系统 var system ={ win : false, mac : false, xll : false }; //检测平台 var p = navigator.platfor ...

  5. Access 执行查询时,抛出“标准表达式中数据类型不匹配”的错误

    Access根据时间查询时应在查询条件前后加# SELECT COUNT(*) FROM [User] WHERE [CreateTime] > #{0}#

  6. LeetCode(11)题解: Container With Most Water

    https://leetcode.com/problems/container-with-most-water/ 题目: Given n non-negative integers a1, a2, . ...

  7. Domino函件收集器的配置及使用方法

     [背景] 今天一个朋友问我这样一个问题,他们OA的应用数据库和接口数据库部署在两台不同的server. 接口server主要负责和第三方系统进行集成,第三方系统调接口创建OA单据,OA系统进行审 ...

  8. 获取IOS应用安装列表

    原文转载至 http://blog.csdn.net/justinjing0612/article/details/8887747 转自鸟哥博客:http://blog.cnrainbird.com/ ...

  9. SpringBoot项目 部署到服务器的tomcat下

    把spring-boot项目按照平常的web项目一样发布到tomcat容器下 一.修改pom文件 修改打包方式 修改或增加maven插件 注意: 二.移除嵌入式tomcat插件 三.添加servlet ...

  10. 通过定时任务 bash 脚本 控制 进程 的 执行时间

    通过定时任务 bash 脚本 控制 进程 的 执行时间