控制反转和依赖注入

####1.引言
对于不懂的专业术语或者专有名词,总是心存敬畏,或多或少有一种它代表多牛逼的技术的潜意识。但是当你了解之后,才发现有些术语你经常在使用,只是不知道这个术语而已,控制反转和依赖注入就是这样的术语名词,不禁让人想骂上一句MMP。(新手入行,错误的地方欢迎批评指正)
####2.示例
在使用一个简单的示例来说明这两个术语之前,需要明确两点:

  1. 参考了很多网友的说法,有许多人说控制反转(IoC)和依赖注入(DI)是从不同角度切入的理解形式不一样而已,这种说法我反正是理解不了,我更推崇的另一种说法,控制反转是一种设计模式或者说是一种思想,而依赖注入是这种设计模式的经典实现。也就是说二者不是一对对等概念,一个是思想,一个是实现。
  2. 控制反转主要解决的问题是解耦依赖对象和被依赖的对象,至于怎么解耦,下面的示例会让你大跌眼镜,因为你一直都在这么做,我确定,除非你比我还新手,否则的话你一定会感叹:“这TM不就是属性复制,参数传递吗?”

既然是控制反转,那必定就会有一个原始的“控制正转”,可能是“控制正转”存在一些缺陷所以转换思路到“控制反转”。下面的代码简单的描述了“控制正转”:

	public class Programmer
    {
        //something else

        /// <summary>
        /// 控制正转
        /// </summary>
        public void Code_Normal()
        {
            IDE ide = new IDE() { MainCodeLanguage = "C#", Name = "VS2015" };
            System.Console.WriteLine(ide.ToString());
        }
    }


	public class IDE
    {
        public string MainCodeLanguage { get; set; }

        public string Name { get; set; }

        public override string ToString()
        {
            return string.Format("name:{0};langauge:{1}", this.Name, this.MainCodeLanguage);
        }
    }

在“控制正转”的代码中,工程师Programmer每次敲代码Code_Normal都需要重新创建一个IDE,有这个必要吗?我想换一个IDE怎么办?在这种情况下,programmer对象与其依赖的对象IDE紧密的耦合在一起,后期的变动都会带来代码的修改,违背开闭原则。

那应该怎么办?传参咯,Programmer所需要的IDE从外部注入,这是一个很正常的思路,我们把这种从外部注入的思想或者说设计模式叫做“控制反转”。既然有了思路那就剩下实现思路了,而实现“控制反转”的经典方式就是依赖注入(DI),依赖注入有三种形式:

  1. 构造注入,通过构造函数注入依赖对象
  2. Setter注入,通过属性setter方法或者类似的成员方法注入依赖对象
  3. 接口注入
	/// <summary>
    /// 构造注入
    /// </summary>
    public class Programmer
    {
        private IDE _ide;
        public Programmer(IDE ide)
        {
            this._ide = ide;
        }
        
        public void Code_IOC()
        {
            if (this._ide == null)
                System.Console.WriteLine("use notepad??");
            System.Console.WriteLine(this._ide.ToString());
        }
    }
	/// <summary>
    /// setter注入
    /// </summary>
    public class Programmer
    {
        private IDE _ide;
        
        public IDE CreateIDE
        {
            set { this._ide = value; }
        }
        
        public void Code_IOC()
        {
            if (this._ide == null)
                System.Console.WriteLine("use notepad??");
            System.Console.WriteLine(this._ide.ToString());
        }
    }
	/// <summary>
    /// 接口注入
    /// </summary>
    public class Programmer:ICreateIDE
    {
        private IDE _ide;
        
        public void Code_IOC()
        {
            if (this._ide == null)
                System.Console.WriteLine("use notepad??");
            System.Console.WriteLine(this._ide.ToString());
        }

        public void CreteIDE(IDE ide)
        {
            this._ide = ide;
        }
    }


	interface ICreateIDE
    {
        void CreteIDE(IDE ide);
    }

上面的三种注入依赖对象的方式,在不同的项目环境下选择不同的方式可能会有意想不到的效果,总之一点不在内部创建IDE对象,从外部传入,那么为什么叫控制反转呢?这是区别于原来的“控制正转”,原来Programmer对象依赖IDE对象,它会每次重新创建一个IDE对象,控制权在Programmer手里,而通过依赖注入依赖对象时,控制权却不在Programmer对象手里,IDE对象是从外部传入的啊,这时候的控制权实际上是在IoC容器的手里,可以把IoC容器理解为一个装有多种IDE对象的容器,IoC容器向Programmer对象里面注入哪种IDE,Programmer对象就是用哪种,没有选择的权利,控制权是不是转换了,此所谓“控制反转”。
####3.说明
控制反转是思路的转变,我觉得是顺其自然的转变,这种转变使得对象和被依赖的对象之间灵活配置组装,从而达到解耦的目的。当然理解和灵活使用还是有很大的区别,需要在项目中根据情况来决定怎么依赖注入和积累经验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值