ASP.NET MVC IOC 之Ninject攻略
ASP.NET MVC IOC 之Ninject攻略
一、为什么要使用Ninject?
很多其它类型的IOC容器过于依赖配置文件,老是配置,总感觉有点不爽,而且要使用assembly-qualified名称(也就是类型的全名)来进行定义,稍不注意就会因为打错字而令整个程序崩掉。Ninject是一个快如闪电、超轻量级的基于.Net平台的IOC容器,主要用来解决程序中模块的耦合问题,它的目的在于做到最少配置。因此如果你不喜欢配置,不喜欢重量级IOC框架,那么就用小苹果Ninject吧!
二、Ninject的使用
首先你必须获取Ninject,其官网下载地址:http://www.ninject.org,你也可以通过VS中的NuGet来加载Nniject,不论是哪种方式,最终的目的就是将 Ninject.dll 这个程序集引用到你的项目中。这样在你的项目中,如果想使用Ninject,只需添加其命名空间引用即可~
using Ninject;
1、Ninject入门
我们先定义一个记录日志的接口:
public interface ILogger
{
void Write(string message);
}
然后用文件记录日志方式和数据库记录日志方式分别实现这个接口,不过这里只是演示而已,所以并没有真正去实现这两个类,你懂的~

public class FileLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("文件记录日志:{0}", message));
}
} public class DBLogger : ILogger
{
public void Write(string message)
{
Console.WriteLine(String.Format("数据库记录日志:{0}", message));
}
}

在Ninject中,我们可以通过重写Ninject.Modules.NinjectModule类的方法Load()而实现依赖注入,注意这里用的是代码的形式!

public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<FileLogger>();
Bind<ILogger>().To<DBLogger>();
}
}

具体调用方法:

private static IKernel kernel = new StandardKernel(new MyModule());
static void Main(string[] args)
{
ILogger logger = kernel.Get<ILogger>();//获取的是FileLogger
logger.Write(" Hello Ninject!");
Console.Read();
}

没错,用Ninject进行依赖注入就是这么爽歪歪~
2、Ninject常用方法属性说明
这里我们使用构造函数注入一个栗子:
首先新建一个测试接口ITester与其实现类NinjectTester ,显然NinjectTester依赖于ILogger

interface ITester
{
void Test();
} class NinjectTester:ITester
{
public string _Message{set;get;}
private ILogger _logger;
public NinjectTester(ILogger logger)
{
_logger = logger;
}
public void Test()
{
_logger.Write("Hello Ninject!");
}
}

下面就看看用Ninject的方式实现依赖注入的过程中用到的一些东东~
(1)Bind<T1>().To<T2>()
其实就是接口IKernel的方法,把某个类绑定到某个接口,T1代表的就是接口或者抽象类,而T2代表的就是其实现类
例如:
IKernel ninjectKernel = new StandardKernel();
ninjectKernel.Bind<ILogger>().To<FileLogger>();
(2)Get<ISomeInterface>()
其实就是得到某个接口的实例,例如下面的栗子就是得到ILogger的实例FileLogger:
ILogger myLogger= ninjectKernel.Get<ILogger>();
(3)Bind<T1>() .To<T2>(). WithPropertyValue("SomeProprity", value);
其实就是在绑定接口的实例时,同时给实例NinjectTester的属性赋值,例如:
ninjectKernel.Bind<ITester>().To<NinjectTester>().WithPropertyValue("_Message", "这是一个属性值注入");
(4)ninjectKernel.Bind<T1>().To<T2>(). WithConstructorArgument("someParam", value);
其实就是说我们可以为实例的构造方法所用的参数赋值,例如:

public class DefalutDiscountHelper : IDiscountHelper
{
private decimal discountRate;
public decimal DiscountSize { get; set; }
public DefalutDiscountHelper(decimal discountParam)
{
discountRate = discountParam;
} public decimal ApplyDiscount(decimal totalParam)
{
return (totalParam - (discountRate / 100M * totalParam));
}
}

ninjectKernel.Bind<IDiscountHelper>().To<DefalutDiscountHelper>().WithConstructorArgument("discountParam", 50M);
(5)Bind<T1>().ToConstant()
这个方法的意思是绑定到某个已经存在的常量,例如:
StudentRepository sr = new StudentRepository();
ninjectKernel.Bind<IStudentRepository>().ToConstant(sr);
(6)Bind<T1>().ToSelf()
这个方法意思是绑定到自身,但是这个绑定的对象只能是具体类,不能是抽象类。为什么要自身绑定呢?其实也就是为了能够利用Ninject解析对象本身而已。例如:
ninjectKernel.Bind<StudentRepository>().ToSelf();
StudentRepository sr = ninjectKernel.Get<StudentRepository>();
(7)Bind<T1>().To<T2>().WhenInjectedInto<instance>()
这个方法是条件绑定,就是说只有当注入的对象是某个对象的实例时才会将绑定的接口进行实例化
ninjectKernel.Bind<IValueCalculater>().To<IterativeValueCalculatgor>().WhenInjectedInto<LimitShoppingCart>();
(8)Bind<T1>().To<T2>().InTransientScope()或者Bind<T1>().To<T2>().InSingletonScope()
这个方法是为绑定的对象指明生命周期其实
ninjectKernel.Bind<IStudentRepository>().To<StudentRepository>().InTransientScope();
//每次调用创建新实例
ninjectKernel.Bind<IStudentRepository>().To<StudentRepository>().InSingletonScope();
//每次调用是同一个实例
(9)Load()方法
这里的Load()方法其实是抽象类Ninject.Modules.NinjectModule的一个抽象方法,通过重写Load()方法可以对相关接口和类进行集中绑定,例如:

public class MyModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
Bind<ILogger>().To<FileLogger>();
Bind<ITester>().To<NinjectTester>();
}
}

这是通过Load()方法绑定之后的完整代码:

private static IKernel kernel = new StandardKernel(new MyModule());
static void Main(string[] args)
{
ITester tester = kernel.Get<ITester>(); // 因为是链式解析,因此只解析ITester即可,其它依赖的东东都会顺带解析
tester.Test();
Console.Read();
}

(10)Inject属性
在Inject中,我们可以通过在构造函数、属性和字段上加 Inject特性指定注入的属性、方法和字段等,例如下面的栗子,MessageDB有两个构造函数:int和object类型的。现在我们已经为int型的指定了Inject特性,因此在注入的时候选择的就是int型的构造函数;如果没有在构造函数上指定Inject特性,则默认选择第一个构造函数:

public class MessageDB : IMessage
{
public MessageDB() { }
public MessageDB(object msg)
{
Console.WriteLine("使用了object 参数构造:{0}", msg);
} [Inject]
public MessageDB(int msg)
{
Console.WriteLine("使用了int 参数构造:{0}", msg);
} public string GetMsgNumber()
{
return "从数据中读取消息号!";
}
}

3、Ninject能使用配置文件吗?
答案是肯定的,要不怎么说Ninject是可扩展的呢,必须可以,但是如果这样的话,你就没必要用Ninject了,因为这样又回到了繁琐的配置上面,还不如用其他的IOC容器来得方便,这里用的是Ninject的XML扩展,你可以通过下面的地址https://github.com/ninject/ninject.extensions.xml下载扩展组件,主要也就是Ninject.Extensions.Xml这个东东起的作用,这里不想详说,给个栗子了结:
(1)配置文件
(2)利用扩展加载服务
(3)调用服务
三、ASP.NET MVC与Ninject
说了这么多Ninject,主要还是想将其用到ASP.NET MVC的IOC中,其实很简单,大概就几个步骤搞定:
1、继承DefaultControllerFactory,重载GetControllerInstance方法,实现自己的NinjectControllerFactory类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Ninject;
using NinjectMvc.Models; namespace NinjectMvc.Ioc
{
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectKernel; public NinjectControllerFactory()
{
ninjectKernel = new StandardKernel();
AddBindings();
} protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType);
} private void AddBindings()
{
ninjectKernel.Bind<IStudentRepository>().To<StudentRepository>();
}
}
}

2、在函数Application_Start() 注册自己的控制器工厂类

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth(); ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
//设置控制器工厂生产类为自己定义的NinjectControllerFactory
}
}

3、现在在你的MVC程序中注入依赖代码就ok了
(1)首先声明一个Student学生类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace NinjectMvc.Models
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Graduation { get; set; }
public string School { get; set; }
public string Major { get; set; }
}
}

(2)然后声明仓储接口和其实现

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace NinjectMvc.Models
{
public interface IStudentRepository
{
IEnumerable<Student> GetAll();
Student Get(int id);
Student Add(Student item);
bool Update(Student item);
bool Delete(int id);
}
}

(3)最后添加控制器StudentController,并注入依赖代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using NinjectMvc.Models; namespace NinjectMvc.Controllers
{
public class StudentController : Controller
{
readonly IStudentRepository repository;
//构造器注入
public StudentController(IStudentRepository repository)
{
this.repository = repository;
} public ActionResult Index()
{
var data = repository.GetAll();
return View(data);
} }
}

(4)最后为控制器StudentController的Index方法添加视图即可,这里不再详述,运行效果如下
总结
ASP.NET MVC IOC 之Ninject攻略的更多相关文章
- ASP.NET MVC IOC之Unity攻略
ASP.NET MVC IOC之Unity攻略 一.你知道IOC与DI吗? 1.IOC(Inversion of Control )——控制反转 即依赖对象不在被依赖模块的类中直接通过new来获取 先 ...
- [转]ASP.NET MVC IOC 之AutoFac攻略
本文转自:http://www.cnblogs.com/WeiGe/p/3871451.html 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用A ...
- ASP.NET MVC IOC 之AutoFac攻略
一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天,发现这个东东确实是个高大上的IOC容器~ Autofa ...
- ASP.NET MVC Razor视图引擎攻略
--引子 看下面一段MVC 2.0的代码. <%if (Model != null){%> <p><%=Model%></p><%}%>&l ...
- ASP.NET MVC IOC 之AutoFac
ASP.NET MVC IOC 之AutoFac攻略 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌似更为普遍,于是捯饬了两天, ...
- ASP.NET没有魔法——ASP.NET MVC IoC
之前的文章介绍了MVC如何通过ControllerFactory及ControllerActivator创建Controller,而Controller又是如何通过ControllerBase这个模板 ...
- ASP.NET MVC中使用Ninject
ASP.NET MVC中使用Ninject 在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事 ...
- ASP.NET MVC IOC依赖注入之Autofac系列(二)- WebForm当中应用
上一章主要介绍了Autofac在MVC当中的具体应用,本章将继续简单的介绍下Autofac在普通的WebForm当中的使用. PS:目前本人还不知道WebForm页面的构造函数要如何注入,以下在Web ...
- Asp.net MVC 中使用 Ninject 实现依赖注入
松耦合.针对抽象编程.不针对实现编程是面向对象设计的原则.依赖注入就是,在一个类的内部,不通过创建对象的实例而能够获得实现了某个公开接口的对象引用.所谓的控制反转也是相同的意思.把依赖的创建转移到了使 ...
随机推荐
- Web 服务器 (IIS) 角色
原文:Web 服务器 (IIS) 角色 1. 对于默认安装,请在命令行提示符下键入以下命令,然后按 Enter: start /w pkgmgr /iu:IIS-WebServerRole;WAS-W ...
- HDU 1198 Farm Irrigation (并检查集合 和 dfs两种实现)
Farm Irrigation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- dede织梦背景经常使用标签
一些非常实用的标签调用的方法 关键描写叙述调用标签: <meta name="keywords" content="{dede:field name='keywor ...
- WinForm实现类似QQ停靠,显示隐藏过程添加特效效果
原文:WinForm实现类似QQ停靠,显示隐藏过程添加特效效果 这可能是个老题长谈的问题了,只是在项目中会用到这个效果,所以今天做个记录.大家见了别喷我.在项目中的需求是这样的. 打开程序,在屏幕的右 ...
- 华为OJ: 公共字符串计算
有几个需要注意的地方,这个问题是不是大写和小写之间的区别.这样你就输入字符串大写或小写转换的计算前. 第二个,定要清晰.先将s1从[i]处開始与s2的[j]開始匹配,不相等则j++直到j等于s2.le ...
- ios 调节器 modal 得知
代码中创建: 1.appdelegate 该contoller放置controller下一个 - (BOOL)application:(UIApplication *)application didF ...
- javascript获取浏览器窗口大小办法
四个属性: 1:outerWidth 2:outerHeight 3:innerWidth 4:innerHeight 经最新版本的浏览器(Chrom IE Firefox Opera)测试,初 ...
- 菜鸟学Java(二十一)——怎样更好的进行单元測试——JUnit
測试在软件生命周期中的重要性,不用我多说想必大家也都很清楚.软件測试有许多分类,从測试的方法上可分为:黑盒測试.白盒測试.静态測试.动态測试等:从软件开发的过程分为:单元測试.集成測试.确认測试.验收 ...
- UVA - 817 According to Bartjens
Description According to Bartjens The wide dissemination of calculators and computers has itsdisad ...
- DevExpress asp.net 导出Excel 自动开启迅雷问题,默认保存为aspx页面
目前采取曲线救国策略: 利用MVC ..... <dx:ASPxGridView ID="ASPxGridView1" runat="server" Au ...