zoukankan      html  css  js  c++  java
  • MVC+EF6教程六:使用DI进行解耦

    如果大家研究一些开源项目,会发现无处不在的DI(Dependency Injection依赖注入)。
    本篇文章将会详细讲述如何在MVC中使用Ninject实现DI

    文章提纲

    • 场景描述 & 问题引出
    • 第一轮重构
    • 引入Ninject
    • 第二轮重构
    • 总结

    场景描述 & 问题引出

    DI是一种实现组件解耦的设计模式。
    先模拟一个场景来引出问题,我们直接使用Ninject官网的示例:一群勇士为了荣耀而战。
    首先,我们需要一件合适的武器装备这些勇士。

    public class Sword 
    {
      public void Hit(string target)
      {
         Console.WriteLine("Chopped {0} clean in half", target);
      }
    }

    其次,我们定义勇士类。勇士有一个Attack()方法,用来攻击敌人。

    public class Samurai
    {
        readonly Sword sword;
        public Samurai()
        {
            this.sword = new Sword();
        }
        
        public void Attack(string target)
        {
            this.sword.Hit(target);
        }
    }

    现在我们就可以创建一个勇士来战斗。

    var warrior = new Samurai();
    warrior.Attack("the evildoers");

    我们运行这个程序就会打印出 Chopped the evildoers clean in half
    现在引出我们的问题:如果我们想要给Samurai 装备不同的武器呢?
    由于 Sword 是在 Samurai 类的构造函数中创建的,必须要改 Samurai才行。
    很显然 Samurai 和 Sword 的耦合性太高了,我们先定义一个接口来解耦。

    第一轮重构

    首先需要建立松耦合组件:通过引入IWeapon,保证了与Sword之间没有直接的依赖项。

        public interface IWeapon
        {
            /// <summary>
            /// 击打目标
            /// </summary>
            /// <param name="target">目标</param>
            string Hit(string target);
        }

    修改 Sword 类

        public class Sword : IWeapon
        {
            public string Hit(string target)
            {
                // 将目标切成两半
               return string.Format("Chopped {0} clean in half", target);
            }
        }

    修改 Samurai 类,将原来构造函数中的Sword 移到构造函数的参数上,以接口来代替 , 然后我们就可以通过 Samurai 的构造函数来注入 Sword ,这就是一个DI的例子(通过构造函数注入)。

        public class Samurai
        {
            readonly IWeapon weapon;
            public Samurai(IWeapon weapon)
            {
                this.weapon = weapon;
            }
    
            public string Attack(string target)
            {
               return this.weapon.Hit(target);
            }
        }

    如果我们需要用其他武器就不需要修改Samurai了。我们再创建另外一种武器。

        public class Shuriken : IWeapon
        {
            public string Hit(string target)
            {
                // 刺穿目标的铠甲
                return string.Format("Pierced {0}'s armor", target);
            }
        }

    现在我们可以创建装备不同武器的战士了

    var warrior1 = new Samurai(new Shuriken());
    var warrior2 = new Samurai(new Sword());
    warrior1.Attack("the evildoers");
    warrior2.Attack("the evildoers");

    权责申明

    作者:编程小纸条 出处: https://www.cnblogs.com/miro/category/620362.html

  • 相关阅读:
    oracle数据泵导入导出命令
    深入理解JVM—JVM内存模型
    JVM 内存初学 堆(heap)、栈(stack)和方法区(method)
    Java中Comparable和Comparator接口区别分析
    Java中的匿名内部类总结
    Git版本控制软件结合GitHub从入门到精通常用命令学习手册
    Git客户端图文详解如何安装配置GitHub操作流程攻略
    Java内部类详解
    Java类加载原理解析
    OracleDBconsoleorcl服务无法启动的原因及解决思路
  • 原文地址:https://www.cnblogs.com/qianj/p/12522307.html
Copyright © 2011-2022 走看看