(转)IOC框架Ninject实践总结

http://www.cnblogs.com/jeffwongishandsome/archive/2012/04/15/2450462.html

一、控制反转和依赖注入

Ninject是一个轻量级的基于.Net平台的依赖注入(IOC)框架。所谓的IOC,即控制反转(Inversion of Control),它是一个经典的面向对象编程法则,它的作用主要是用来帮助应用程序解耦,并把程序分离成一个个松耦合高内聚的模块。控制反转还有一个名字叫依赖注入(Dependency Injection),简称DI。

二、快速无xml配置注入

1、定义应用程序Module

using LogService;
using LogService.Impl;
using Ninject.Modules;
using NinjectApp.Warrior;
using NinjectApp.Weapon;

namespace NinjectApp
{
    internal class ServiceModule : NinjectModule
    {
        public override void Load()
        {
            Bind<ILogService>().To<DbLogService>();

            Bind<IWeapon>().To<Sword>().InSingletonScope();
            //Bind<IWeapon>().To<Shuriken>();

            Bind<Shuriken>().ToSelf().WhenInjectedInto<IWeapon>();

            Bind<IWarrior>().To<FootSoldier>();
            //Bind<IWarrior>().To<Samurai>();

        }
    }
}

2、手动调用服务

InjectManual

注:Ninject的绑定对象作用域有多种,本文的demo中有具体的单元测试,具体可以直接查看源码或者参考官方文档。。

三、配置文件注入

通过Ninject的xml扩展,可以实现传统的类似于Spring.net、Unity等IOC容器的注入方式。

1、配置文件

<?xml version="1.0" encoding="utf-8" ?>
<module name="ServiceModule">
  <bind name="Txtlog" service="LogService.ILogService,LogService" to="LogService.Impl.TxtLogService,LogService"/>
  <!--<bind name="Dblog" service="LogService.ILogService,LogService" to="LogService.Impl.DbLogService,LogService"/>-->
  <bind name="Sword" service="NinjectApp.Weapon.IWeapon,NinjectApp" to="NinjectApp.Weapon.Sword,NinjectApp"/>
  <bind name="FootSoldier" service="NinjectApp.Warrior.IWarrior,NinjectApp" to="NinjectApp.Warrior.FootSoldier,NinjectApp"/>
</module>

2、利用扩展加载服务

XmlServiceModule

3、调用服务

InjectByConfig

虽然配置注入看上去更容易扩展应对外部变化,但是项目庞大臃肿之后,配置文件并不好管理。固然有一些可视化的工具,但是仍然容易出现偏差。Ninject最擅长的基本注入功能就是无配置简单快速注入,达到free yourself from xml的目的,对于一般的中小型应用程序完全可以零配置。

四、MVC项目的依赖注入

通过Ninject的MVC扩展可以轻松实现MVC项目的依赖注入。

1、NinjectHttpApplication

在Global.asax.cs文件里重新定义MvcApplication继承自NinjectHttpApplication,重写OnApplicationStarted事件和CreateKernel方法:

MvcApplication

2、通过构造函数或者属性或者Module实现注入

(1)、Controller实现注入

a、构造函数注入

Account/Index

b、属性注入

定义属性,加上Inject特性即可实现注入。

       [Inject]
        public IUserService CurrentUserService { get; set; }

c、module注入

定义Module:

MvcServiceModule

接着调用即可:

MvcServiceModule

(2)、自定义Attribute实现注入

ExceptionHandleAttribute

和Controller非常相似,示例使用属性加上Inject特性的方式实现注入,其他注入方式略过。

到这里,你应该已经可以看到,这可以算是web应用程序中非常干净利落的注入方式,简单的令人发指。

五、组合还是继承

通过IOC框架实现服务依赖注入本来不难,但是这里或多或少会牵扯到一个问题:注入服务调用是使用组合还是继承?

举例来说,最基础的用户服务(或者日志服务),一般的web应用程序几乎每个控制器(或者页面)都或多或少和用户有关系。

问题来了,不同的控制器或者页面要调用用户服务该怎么做?

下面以MVC项目为例来说明一下通常的注入方法。

如你所知,通常的做法,所谓组合优于继承(继承被认为是一种强耦合),我们只要在需要调用服务的控制器中定义一个服务变量或者属性,通过构造函数注入,类似下面这样:

controllerconstructor

然后在对应的Action中就可以调用用户服务了。

如果你的Controller很少,这种方式当然可以接受。但是,实际项目中控制器真的比较多的时候,有一些几乎每个控制器必然用到的公共服务,我们是不是不得不哼哧哼哧写很多构造函数实现依赖注入呢?

到这里,你一定想到,是啊,都调用一样的服务,几乎都类似的代码,重构吧!

最简单的方式,利用继承,集中在一个地方(通常就叫BaseController吧)写一次,

using System.Web.Mvc;
using LogService;
using Ninject;
using UserService;
using UserService.Model;

namespace MVCApp.Helper
{
    [ExceptionHandle]
    public class BaseController : Controller
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public BaseController()
        {
            if (CurrentLogService==null)
            {
                using (var kernel = new StandardKernel(new ServiceModule()))
                {
                    var logger = kernel.Get<ILogService>();
                    logger.AppendLog("As you see,in constructor log service is not initilized by inject attribute.");
                }
            }
        }

        protected UserInfo CurrentUser
        {
            get { return CurrentUserService.CurrentUser; }
        }

        #region 服务

        [Inject]
        public IUserService CurrentUserService { get; set; }

        [Inject]
        public ILogService CurrentLogService { get; set; }

        #endregion
    }
}

然后,在相应的Controller下this点服务属性名调用一下,多么优雅干净简洁。但是这种方式有一点需要特别需要注意,在Controller的构造函数里调用服务初始化一些数据可能不能让你那么随心所欲,因为在构造函数内,服务还没有初始化。

如上代码所示,通过Inject特性实现服务注入,通过继承实现公共服务调用,不管哪种表现形式的应用程序都可以使用,有AOP和继承的世界看上去是多么美好啊。当然了,具体使用哪种方式好每个人肯定都有自己的看法,实际项目中,我们通常选择组合和继承相结合的方式,这样就可以兼顾两者的优点实现注入。

最后还有几个困扰人的问题需要思考:如何划分服务?服务和服务之间是否应该依赖注入?如果仅仅是在表现层实现依赖注入,难道不觉得IOC的作用有点太酱油了吗?

时间: 2024-08-26 11:02:21

(转)IOC框架Ninject实践总结的相关文章

c#中创建IOC框架的步骤(无参,Ninject容器)

创建无参的IOC框架 步骤: 1. 一个接口 2. 通过创建一个实体类显示接口 3. 再创建一个类制造构造函数(并将接口作为参数传递),再此类中创建一个无返回值的方法,调用接口里的方法 4. 在Main里面写代码: 1) 用接口new出创建接口实体的类. 2) 把创建构造函数的类名new出来,将1)的对象写入括号中. 3) 调用2)的无返回值方法. 第一步,定义一个接口: namespace NInjectEmail { interface ISendMsg { void SendEmail()

IOC框架之Ninject 简介

还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 上篇博客介绍了依赖注入的三种方式:构造方法注入,属性注入,接口注入!详情请参考:学习 IOC 设计模式前必读:依赖注入的三种实现 本篇继续介绍IOC和DI的故事 今天将以一个具体的IOC框架来介绍,Ninject 框架: 1.Ninject简介 Ninject是基于.Net平台的依赖注入框架,它能够将应用程序分离成一个个高内聚.低耦合(loosely-coupled, hig

ASP.NET MVC IOC 之Ninject攻略

一.为什么要使用Ninject? 很多其它类型的IOC容器过于依赖配置文件,老是配置,总感觉有点不爽,而且要使用assembly-qualified名称(也就是类型的全名)来进行定义,稍不注意就会因为打错字而令整个程序崩掉.Ninject是一个快如闪电.超轻量级的基于.Net平台的IOC容器,主要用来解决程序中模块的耦合问题,它的目的在于做到最少配置.因此如果你不喜欢配置,不喜欢重量级IOC框架,那么就用小苹果Ninject吧! 二.Ninject的使用 首先你必须获取Ninject,其官网下载

架构师之路(39)---IoC框架

1 IoC理论的背景     我们都知道,在採用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,全部的对象通过彼此的合作,终于实现系统的业务逻辑. 图1:软件系统中耦合的对象 假设我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针.分针和秒针顺时针旋转,从而在表盘上产生正确的时间.图1中描写叙述的就是这种一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完毕某项任务.我们能够看到,在这种齿轮组中,假设有一个齿轮出了问题,就可能会影响到整

【架构师之路】依赖注入原理---IoC框架

1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.  图1:软件系统中耦合的对象 如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针.分针和秒针顺时针旋转,从而在表盘上产生正确的时间.图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务.我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整

IoC框架(转载)

1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.  图1:软件系统中耦合的对象 如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针.分针和秒针顺时针旋转,从而在表盘上产生正确的时间.图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务.我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整

IoC框架

1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.  图1:软件系统中耦合的对象 如果我们打开机械式手表的后盖,就会看到与上面类似的情形,各个齿轮分别带动时针.分针和秒针顺时针旋转,从而在表盘上产生正确的时间.图1中描述的就是这样的一个齿轮组,它拥有多个独立的齿轮,这些齿轮相互啮合在一起,协同工作,共同完成某项任务.我们可以看到,在这样的齿轮组中,如果有一个齿轮出了问题,就可能会影响到整

MVC4 基于 Unity Ioc 框架的 ControllerFactory

首先引入Untiy框架. 可以在NuGet程序包 管理器中直接安装. 新建 继承DefaultControllerFactory  的UnityControllerFactory: 重写虚方法GetControllerInstance. public class UnityControllerFactory : DefaultControllerFactory { public IUnityContainer UnityContainer { get; private set; } public

各大主流.Net的IOC框架性能测试比较

在上一篇中,我简单介绍了下Autofac的使用,有人希望能有个性能上的测试,考虑到有那么多的IOC框架,而主流的有:Castle Windsor.微软企业库中的Unity.Spring.NET.StructureMap.Ninject等等.本篇文章主要针对这些IOC框架编写测试程序. Autofac下载地址:http://code.google.com/p/autofac/ Castle Windsor下载地址:http://sourceforge.net/projects/castleproj