在MVC5中的使用

Ninject

从MVC3中就开始接触Ninject这个IOC工具。也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等。性能和使用上面个有千秋。下面先看一下Ninject的使用:

1.添加Ninject。工具-->Nuget程序包管理器-->程序包管理器控制台,输入下面的命令:

Install-Package Ninject -version 3.0.1.10
Install-Package Ninject.Web.Common -version 3.0.0.7
Install-Package Ninject.MVC3 -Version 3.0.0.6

2.创建依赖分解器 NinjectDependencyResolver。

NinjectDependencyResolver实现了IDependencyResolver接口,当一个请求进来的时候,MVC框架会调用GetService或GetServices方法去获取对象的实例去服务这个请求。GetAll方法支持单个类型的多重绑定。我们在AddBinds方法中添加接口的绑定。

 public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
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<IProductRepository>().To<EFProductRepository>();
               kernel.Bind<IAuthProvider>().To<FormsAuthProvider>();

        }
}

3.注册

在MVC3,4中,我们是在Global的Application_Start()中注册。当应用启动的时候回触发Application_Start()中的方法。

 DependencyResolver.SetResolver(new NinjectDependencyResolver());

那再MVC5中,更加完善。注意到我们之前引用了Ninject.Web.Common,这个是在MVC4以前没有出场的。它会在App_Start文件中创建一个NinjectWebCommon.cs类:

它的Start方法是会先于Global的Application_Start()方法执行。

[assembly: WebActivator.PreApplicationStartMethod(typeof(NinjectWebCommon), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectWebCommon), "Stop")]
namespace SportsStore.WebUI
{
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
} /// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
} /// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); RegisterServices(kernel);
return kernel;
} /// <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 Infrastructure.NinjectDependencyResolver(kernel));
}
}
}

它充分使用Asp.Net 4.0的新技术,并使用了WebActivator框架,在Web程序启动前动态调用Start函数,在关闭前调用Stop函数.在Start函数中,动态注册了OnePerRequestHttpModule和NinjectHttpModule.而对于CreateKernel函数,首先新建了IOC核心,然后绑定了Func<IKernel>类型与IHttpModule类型.

5.绑定方法:

1)基本绑定

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

2)传递参数:

创建一个IDiscountHelper接口。让DefaultDiscountHelper 实现它。

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

也可以从构造函数传递参数:

public class DefaultDiscountHelper : IDiscountHelper {
public decimal discountSize;
public DefaultDiscountHelper(decimal discountParam) {
discountSize = discountParam;
}
public decimal ApplyDiscount(decimal totalParam) {
return (totalParam - (discountSize / 100m * totalParam));
}
}
kernel.Bind<IDiscountHelper>().To<DefaultDiscountHelper>().WithConstructorArgument("discountParam", 50M);

3)条件绑定

有时候我们一个接口,有不同的实现对象。这个时候我们需要根据使用情况来获取相应的实例。我们再创建一个FlexibleDiscountHelper来实现上面的接口。

public class FlexibleDiscountHelper : IDiscountHelper {
public decimal ApplyDiscount(decimal totalParam) {
decimal discount = totalParam > 100 ? 70 : 25;
return (totalParam - (discount / 100m * totalParam));
}
}
kernel.Bind<IDiscountHelper>().To<FlexibleDiscountHelper>().WhenInjectedInto<LinqValueCalculator>();

上面的意思就是:当注入到LinqValueCalculator的时候,绑定FlexibleDiscountHelper。这样就方便多了。

方法 效果
When(predicate) 当Lambda表达式结果为ture时使用该绑定
WhenClassHas<T>() 当被注入的对象被特性T标记时使用该绑定
WhenInjectedInto<T>() 当被注入的对象是T时使用绑定。

4)作用范围

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

InRequestScope是一个扩展方法,位于Ninject.Web.Common命名空间中,告诉Ninject,只应该为每一个Asp.Net 接受到的Http请求创建一个LinqValueCalculator实例。

方法 效果
InTransientScope() 默认模式,解决每次依赖的时候都会创建一个新实例。
InSingletonScope() 单例模式,贯穿整个应用。
ToConstant(object) 绑定到某个常亮。
InThreadScope() 对于单个线程创建单个实例
InRequestScope() 对于单个Http请求创建单个实例

这里说明下ToConstant,对于某个接口,我们实现好了一个对象,可以用ToConstant方法来绑定

比如我们用moq实现了接口IProductRepository,这样在使用到这个接口的地方,注入的实例中就已经含有了三个Product对象,相当于已经初始化好了。

  var mock=new Mock<IProductRepository>();
mock.Setup(m => m.Products).Returns(new List<Product>
{
new Product {Name = "Football", Price = 25},
new Product {Name = "Surf board", Price = 179},
new Product {Name = "Running shoes", Price = 95}
}); kernel.Bind<IProductRepository>().ToConstant(mock.Object);

小结:IOC在MVC中应用的很多,有必要选择一款适合自己需要的IOC框架。希望本文对你有帮助。

参考文章:NinJect 源码分析: http://www.verydemo.com/demo_c360_i40786.html

IOC 框架性能比较:http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html

小牛之路 Ninject:http://www.cnblogs.com/willick/p/3299077.html

阅读书籍:Apress Pro Asp.Net MVC5

在MVC5中的使用Ninject的更多相关文章

  1. 【读书笔记】Ninject 在MVC5中的使用

    从MVC3中就开始接触Ninject这个IOC工具.也一直是MVC Framework系列书籍中推荐的IOC工具,当然还有优秀的Autofac等.性能和使用上面个有千秋.下面先看一下Ninject的使 ...

  2. MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子

    MVC5中后台提供Json,前台处理Json,绑定给Dropdownlist的例子: 前端: 我们以前在前端定义了两个控件: <div class="row"> < ...

  3. MVC5中Model层开发数据注解

    ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...

  4. ASP.NET MVC5中的数据注解

    ASP.NET MVC5中Model层开发,使用的数据注解有三个作用: 数据映射(把Model层的类用EntityFramework映射成对应的表) 数据验证(在服务器端和客户端验证数据的有效性) 数 ...

  5. 【转】MVC5中的区域(Areas)

    MVC本身提倡的就是关注点分离.但是当项目本身的业务逻辑足够复杂,如果所有的业务逻辑都写个Controller文件夹下面的时候,你会看到非常庞大的各种命名的Controller,这个时候区域的作用就非 ...

  6. MVC5中使用SignalR2.0实现实时聊天室

    原文 MVC5中使用SignalR2.0实现实时聊天室 有时候需要浏览器和服务端保持实时的通讯(比如在线聊天),SignalR的出现让这一切变得非常简单.它能够让服务端向客户端实时的推送消息.如果用户 ...

  7. asp.net mvc5中使用缓存依赖SqlCacheDependency

    缓存是用来提高应用性能,降低服务器压力.适用于数据不易变,数据易通用的情景, 对于动态查询数据,例如数据分析,最好放弃使用缓存.使用缓存最麻烦的就是保持源数据和缓存的中的数据一致. 缓存(Cache) ...

  8. 实例分析ASP.NET在MVC5中使用MiniProfiler监控MVC性能的方法 

    这篇文章主要为大家详细介绍了ASP.NET MVC5使用MiniProfiler监控MVC性能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 MiniProfiler ,一个简单而有效的迷你剖析器 ...

  9. asp.net mvc5中的过滤器重写

    asp.net mvc5中增加了一种过滤器类型叫过滤器重写,这种过滤器类型可以在操作或者控制器上忽略更高层次上设置的过滤器类型,它可以重写五种基本的过滤器接口类型:IAuthenticationFil ...

随机推荐

  1. web:转盘抽奖

    移动web:转盘抽奖(幸运大转盘)   为了获取客户.回馈客户,平台一般会推出抽奖活动类的营销页.因此web页面中,有各式各样的抽奖效果. 格子式(九宫格),背景滚动式(数字/文字/图案),旋转式(转 ...

  2. Java二叉排序树(转)

    一.二叉排序树定义 1.二叉排序树的定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree).其定义为:二叉排序树或者是空树,或者是满足如下性 ...

  3. 请注意CSDN社区微通道,许多其他的精彩等着你

    CSDN社区微信公众号"程序人生"(微信ID:coder_life)来了,每天我们会将CSDN社区中大量的优质内容浓缩成1~3篇文章.推送到您的手机中,让您不管何时何地都能感受到知 ...

  4. 非正确使用浮点数据由项目产生BUG讨论的问题

    乘分配 当小学学会了乘法分配.详细乘法分配:并与多个两个数相乘的,他们能够把这个数字乘以,然后加入.由于一个恒定.乘法分配律也能够使用表达式的定义"(a+b)×c = a×c+b×c&quo ...

  5. 代码的未来读书笔记&lt;二&gt;

    代码的未来读书笔记<二> 3.1语言的设计 对Ruby JavaScript Java Go 从服务端client以及静态动态这2个角度进行了对照. 这四种语言因为不同的设计方针,产生了不 ...

  6. MongoDB时间处理问题

    MongoDB保存到数据库的时候,默认为UTC时间,在数据库保存时,会和当前时间有个间隔,差距为8小时. 在读取的时候,需要再次转换回来,比较麻烦. 其实,Mongo本身就已经提供了相应的处理方法,即 ...

  7. C#中对于float,double,decimal的误解

    原文:C#中对于float,double,decimal的误解 一直很奇怪C#的预定义数据类型中为什么加了一个decimal,有float和double不就够了吗?今天来挖一挖. 浮点型 如果我们在代 ...

  8. iphone6 plus有什么办法

    在苹果9月9号最新的秋季公布会上苹果官方公布了最新的iPhone6 plus,可能非常多朋友不知道plus是什么意思,这样命名有什么特殊的意义呢?本次Ly经典家居小编就为大家带来这方面的具体解答,一起 ...

  9. 【翻译自mos文章】rman 备份时报:ORA-02396: exceeded maximum idle time

    rman 备份时报:ORA-02396: exceeded maximum idle time 參考原文: RMAN backup faling with ORA-02396: exceeded ma ...

  10. SQL优化策略高级优化经常使用-1(The Return Of The King)

    1 经常使用的优化策略 1.1    语句 1.1.1使用实际的列名 当我们查询SQL语句时.你是否觉得使用实际的列名比使用*更快呢?答案是肯定的. 为了证实这一点,感兴趣的朋友能够自己验证一下.我这 ...