首页 > 其他分享 >控制反转IOC

控制反转IOC

时间:2022-11-01 00:12:19浏览次数:71  
标签:控制 account string 反转 实列 content Order IOC public

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:需要什么让别人送;

 

标签:控制,account,string,反转,实列,content,Order,IOC,public
From: https://www.cnblogs.com/liuzheng0612/p/16748449.html

相关文章

  • 【单片机入门】(四)应用层软件开发的单片机学习之路-----ESP32开发板PWM控制电机以及
    引言各位大佬,晚上好啊,在上一篇博客中,我们讲了什么是UART串口通讯,以及使用USB转TTL使得单片机可以和c#上位机做一个串口通讯,接下来,为大家带来PWM的概念原理,以及实际案例,使......
  • 【WPF依赖注入】开篇. NET Core 控制反转(IoC)和依赖注入(DI) IServiceCollection
    参考Microsoft.Extensions.DependencyInjection入门https://www.cnblogs.com/zcqiand/p/14257661.html原文:NETCore依赖注入的IServiceCollection 前置阅读在阅......
  • 控制台效果Demo
    先看下效果:效果是这样的,主要是运用的定时器让文字逐步显现出来。......
  • [单片机框架][driver层][ioctl] MCU模拟Linux注册驱动
    概念ioctl是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设ioctl()命......
  • c#在控制窗体最大化时不覆盖状态栏
    c#在控制窗体最大化时不覆盖状态栏,可以通过下面这种方式privatevoidForm1_Load(objectsender,EventArgse){this.Left=0;this.Top=......
  • HTML中图片位置及大小的控制
    经过一些思考和突发奇想,我发现有些时候,在HTML中,如果将三张图片放在一行,那么如果将网页缩小,还会在一行吗。现在有两种方法:(1)用table<table><tr><td></td></tr></table>这种用......
  • DMA(三) - DMA控制器接口函数
    DMA控制器接口函数主要作用是配置DMA控制器并启动相应传输s3c2440中关于公共DMA控制器的函数提供有:s3c2410_dma_config()s3c2410_dma_ctrl()s3c2410_dma_enqueue()......
  • std::cout 控制输出小数点位数
    转自:https://blog.csdn.net/zfjBIT/article/details/93972484 #include<iomanip> std::cout<<std::setiosflags(std::ios::fixed)<<std::setiosflags(std::i......
  • 多轴插补运动控制
    一、基本概述    数控技术一般以标准的格式对程序段进行描述,例如程序段“N15G02XloY25120JOF125LF”就规定了一个以(10,25)为起点,在X-Y平面上以150mm/min的进给......
  • linux控制cpu占用率
    之前在<编程之美>上提到说控制cpu的使用率使能在任务管理器上画一条正弦线现在下面提供一个在Linux平台上实现的控制cpu频率在某个值​cpu_load.c​​#include<iostream......