IoC(Inversion of Contro ,控制反转) ,它不是一种技术,而且我们架构中常用的一种设计模式。

ioc核心思想是:将程序中实列的控制权交由(反转)给容器来管理,由容器来创建实列管理生命周期,

通过DI(Dependency Injectioiocn,依赖注入) 技术将容器中的实列注入到依赖的抽象中;

ioc最大的好处是可以降低程序耦合度,实现面向抽象编程

 

通过简单列子来对比一下ioc和传统程序架构之间的区别,以便更好了解;

下面是一个Order类,下单成功会给用户发邮件,提示下单成功;

        public class Order
        {
            Email email;
            public void Ordered(string account, string content)
            {
                if (email == null)
                {
                    email = new Email();
                }
                email.Send(account, content);
            }
        }

        //发送邮件类
        public class Email
        {
            public void Send(string account, string content)
            {
                //send email code......
            }
        }

这样的做法层与层是直接依赖的,上层调用下层直接new,

后面需求有变,下单成功后不能发邮件,需要发短信。 

我们遵循面向对象的原则,需要写一个发送短信类;然后修改Order的代码,将发送邮件改为发送短信;

        public class Order
        {
            //Email email;
            SMS sms;
            public void Ordered(string account, string content)
            {
                //if (email == null)
                //{
                //    email = new Email();
                //}
                //email.Send(account, content);
                if (sms == null)
                {
                    sms = new SMS();
                }
                sms.Send(account, content);
            }
        }

        //发送短信服务类
        public class SMS
        {
            public void Send(string account, string content)
            {
                //code.....
            }
        }

注意到问题没,Order注释了很多代码。下层改变直接影响了上层。

这样很严重的,我现在只有一个地方调用Email类,真正程序中可能有好多个地方调用。那我每个调用的地方都需要改;

 

如果解决呢,我之前工作中所接触的一些设计模式看看能不能解决;

单列:

下单是一个很简单的单列,(真正的单列实列最好还是存到缓存或者上下文中。我demo没有封装就直接声明实列了);

        public class Singleton<T> where T : class, new()
        {
            private static T _instance;
            private static readonly object objlock = new object();
            public static T Load
            {
                get
                {
                    if (_instance == null)
                    {
                        lock (objlock)
                        {
                            if (_instance == null)
                            {
                                _instance = new T();
                            }
                        }
                    }
                    return _instance;
                }
            }
        }
        public class Order
        {
            public void Ordered(string account, string content)
            {
                //1.发送邮件
                //Singleton<Email>.Load.Send(account, content);  

                //2.需求变更,不能发邮件需要发短信
                Singleton<SMS>.Load.Send(account, content);
            }
        }

好像确实节省了很多代码。但是还是需要改Order类的代码,每个使用Email的地方都要改成SMS。

 

其实我们可以用工厂,不需要每个地方自己去获取实列了,让统一工厂创建实列吧。

工厂:

        //消息服务接口,发送邮件、发送短信接口要继承
        public interface IMS
        {
            void Send(string account, string content);
        }

        //消息服务工厂,获取实列
        public class MSFactory
        {
            public static IMS CreateObject(string typeName)
            {
                //抽象工厂这里一般是反射的;
                //return Assembly.Load("DAL." + typeName) as IMS;
                //反射具体代码我也不记得了,就这样这样new实列把;
                if (typeName == "Email")
                {
                    return new Email();
                }
                else if (typeName == "SMS")
                {
                    return new SMS();
                }
                return null;
            }
        }

发送邮件和发送短信类要继承的

 

 

 接下来看看Order类该如何调用

        public class Order
        {
            IMS _ims;
            public Order()
            {
                //1.发送邮件
                //_ims = MSFactory.CreateObject("Email");

                //2.需求变化,需要发送短息
                _ims = MSFactory.CreateObject("SMS");
            }
            public void Ordered(string account, string content)
            {
                _ims.Send(account, content);
            }
        }

这种工厂模式的调用就实现抽象化了。声明抽象接口,然后从工厂获取需要的实列。

直可惜没有注入。其实还是由Order层获取的(Order发起的获取实列)

 

最后来看下IOC:

        public class Order
        {
            IMS _ims;//声明抽象
            public Order(IMS ims)//具体是什么,这里不需要关系了。看容器里面注册的是什么
            {
                _ims = ims;
            }
            public void Ordered(string account, string content)
            {
                _ims.Send(account, content);
            }
        }

容器里面注册实列,这里是asp.net core自带的容器

 

 

 

 

对比上面的单列和工厂。虽然是封装了。统一获取实列。

但是本质还是由上层发起的创建实列。IOC是完全把实列的控制前交给一个容器了,并且由容器给抽象提供实列;

白话就是:传统架构:需要什么自己拿

       IOC:需要什么让别人送;

 

原文地址:http://www.cnblogs.com/liuzheng0612/p/16748449.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性