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