zoukankan      html  css  js  c++  java
  • Ninject

    一、为什么要使用依赖注入框架

      依赖注入框架也叫IoC容器。它的作用使类与类之间解耦

      我们看看为什么要用依赖注入框架,举个几个梨子:

      1,高度耦合的类

      

          有一个Order类,Order类是用于订单操作的,DataAccess使用的sqlserver的方式查询订单。看看代码:

    public class Order
        {
            private DataAccess dataAccess = new DataAccess();
            public string QueryOrder()
            {
                return dataAccess.QueryOrder();
            }
        }
    
        public class DataAccess
        {
            public string QueryOrder()
            {
                return "sqlserver查询Order";
            }
        }

      看到这两个类(Order,DataAccess),它们出现了高度耦合。如果产品汪突然狂犬病大发让我们换成MySql方式查询,我们不得不修改Order类的private DataAccess data = new DataAccess() 和DataAccess的QueryOrder方法。这里违反了开放封闭原则(对扩展开放,对修改关闭),当然一个项目不只只有订单(Order)操作,还有购物车、产品等等操作,那改动起来将会是一场噩梦。

      2,使用依赖倒转原则来改进

      依赖倒转原则口诀:高层次模块不应该依赖于低层次模块,要依赖抽象,不要依赖具体。

      口诀听着很绕口,其实理解起来并不难,看下面的类图,Order相当于是高层模块,SqlServerData和MySqlData相当于底层模块,高层模块依赖于接口,所以可以随时更换底层模块

      

      我们现在把DataAccess抽象为接口,使SqlServerData和MySqlData实现IDataAccess

        public class Order
        {
            private IDataAccess dataAccess = new MySqlData();
            public string QueryOrder()
            {
                return dataAccess.QueryOrder();
            }
        }
    
    
        public interface IDataAccess
        {
            string QueryOrder();
        }
    
    
        public class SqlServerData : IDataAccess
        {
            public string QueryOrder()
            {
                return "sqlserver查询Order";
            }
        }
    
        public class MySqlData : IDataAccess
        {
            public string QueryOrder()
            {
                return "MySql查询Order";
            }
        }

      现在我们高层模块依赖于接口,如果产品汪再叫我们换Oracle数据库,我们就可以再添加一个OracleData类,然后实现IDataAccess接口,然后在Order类中的private IDataAccess dataAccess = new MySqlData()改为private IDataAccess dataAccess = new OracleData()。虽然改动的地方减少了,但是我们还是修改了类。可是我们并不希望修改类,就可以更换数据访问,这就需要解耦,需要用到Ioc容器,我们的Ninject终于该出场了,出场费还不低哦!

    二、实战Ninject

      

    1,使用注册机制

      首先安装一个Ninject的Dll,我们用NuGet安装。

      ①反键项目引用,选中管理NuGet程序包

      

      ②搜索Ninject,点击安装

      

      ③代码实现(只实现Order类操作,Product类操作与Order类一致)

      IDataAccess:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace RegisterNinject
    {
        public interface IDataAccess
        {
            string QueryOrder();
        }
    }

      MySqlDataOrder:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace RegisterNinject
    {
        public class MySqlDataOrder : IDataAccess
        {
            public string QueryOrder()
            {
                return "MySql查询Order";
            }
        }
    }

      SqlServerDataOrder:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace RegisterNinject
    {
        public class SqlServerDataOrder : IDataAccess
        {
            public string QueryOrder()
            {
                return "sqlserver查询Order";
            }
        }
    }

      Register:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Ninject; //引入命名空间
    namespace RegisterNinject
    {
        public class Register
        {
            private StandardKernel _kernel = new StandardKernel();
            // 在这里注册
            public Register()
            {
                _kernel.Bind<IDataAccess>().To<MySqlDataOrder>();
                //_kernel.Bind<IDataAccess>().To<SqlServerDataOrder>();
                //_kernel.Bind<IDataProduct>().To<SqlServerDataProduct>();
            }
    
            //获取
            public TInterface Get<TInterface>()
            {
                return _kernel.Get<TInterface>();
            }
    
            public void Dispose()
            {
                _kernel.Dispose();
            }
        }
    }

      Order:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace RegisterNinject
    {
        public class Order
        {
            private Register reg = new Register();
            public string QueryOrder()
            {
                return reg.Get<IDataAccess>().QueryOrder();
            }
    
        }
    }

      这样,妈妈再也不用担心我换数据库了。如果产品汪再让我们换回sqlserver数据库[神经病](小插曲:换数据库是举的例子,Ioc容器的意义是让类与类之间解耦的,不是换数据库用的!),我们只需要在Register类中的构造函数中修改注册即可。

      有人说,"你还是修改了类呀!"。Register类的定位不一样,他是一个公共类,专门提供注册机制的。如果不去要修改类,就能完成换数据库,那就要引入新的概念———热插拔技术。

      

    2,使用Xml文件(热插拔)

      现在我们用xml文件的方式,动态的更换接口。我们需要建一个xml文件。把他放在项目中。

      Register.xml

    <?xml version="1.0" encoding="utf-8" ?> 
    <module name="register">
      <bind service="XmlNinject.IDataAccess,XmlNinject" to="XmlNinject.SqlServerDataOrder,XmlNinject"/>
    </module>

      注意:module元素,name属性,bind元素,service属性,to属性为规定的元素属性,不能写成别的。格式也要正确。

      然后更改下Register

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Ninject; //引入命名空间
    using Ninject.Extensions.Xml;//引入命名空间
    namespace XmlNinject
    {
        public class Register
        {
            private StandardKernel _kernel = new StandardKernel();
    
            // 以后这里就不用更改这里了,只需要该xml文件就可以了
            public Register()
            {
                var settings = new NinjectSettings() { LoadExtensions = false };
                _kernel = new StandardKernel(settings, new XmlExtensionModule());
                _kernel.Load("Xml/Register.xml");
            }
    
            //获取
            public TInterface Get<TInterface>()
            {
                return _kernel.Get<TInterface>();
            }
    
            public void Dispose()
            {
                _kernel.Dispose();
            }
        }
    }

       以后要更换接口,直接更改xml文件就可以了。

       源码下载http://pan.baidu.com/s/1sjJXVrv  

    学习永不止境,技术成就梦想。
  • 相关阅读:
    TreeView 读取 xml 显示节点
    网上流传的数据操作类
    文件上传, 打开, 删除操作
    Reflector8.5 .net反编译工具 破解教程
    asp.net c# 打开新页面或页面跳转
    UGUI 要点总结
    EventSystem
    拖拽事件
    Unity Transform
    鼠标跟随(坐标转换)
  • 原文地址:https://www.cnblogs.com/zd1994/p/4585798.html
Copyright © 2011-2022 走看看