一、名词解释
IoC:Inverse of control,控制反转;
DI:Depedency Injection 依赖注入
IoC和DI是从不同角度描述同一件事情,即DI模式是Ioc的具体实现方式,通过引入IoC容器,利用依赖关系注入,实现对象的解耦。
二、问题引入
先来看普通的方式:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace IocDemo
- {
- class Program
- {
- static void Main(string[] args)
- {
- UserService user = new UserService(1);
- user.SaveUser();
- Console.Read();
- }
- }
- interface IDal
- {
- void save();
- }
- class SqlServerDal : IDal
- {
- public void save()
- {
- Console.WriteLine("SqlServer save.");
- }
- }
- class OracleDal : IDal
- {
- public void save()
- {
- Console.WriteLine("Oracle save.");
- }
- }
- class UserService
- {
- private IDal dal;
- public UserService(int type)
- {
- if (type == 1)
- dal = new OracleDal();
- else
- dal = new SqlServerDal();
- }
- public void SaveUser()
- {
- dal.save();
- }
- }
- }
我们发现UserService和具体的类OracleDal,SqlserverDal紧密耦合。
如果把它进行简单的修改,那么UserService就和具体的类没有关系了,而是直接依赖于抽象。
- class UserService
- {
- private IDal dal;
- public UserService(IDal dal)
- {
- this.dal = dal;
- }
- public void SaveUser()
- {
- dal.save();
- }
- }
- }
那么运行时具体的类是哪个呢?这是我们就可以事先注册好一种对于关系,
先看一段Unity的代码混个眼熟:
- UnityContainer container = new UnityContainer();
- container .RegisterType<IDal, OracleDal>();
通过解析对应关系可以知道IDal具体的类。调用时:
- var dal = container .Resolve<IDal>();//这是得到OracleDal的实例。
- UserService user = new UserService(dal);
- user.SaveUser();
可见DI的目的其实就是为了减少对象间的依赖性,降低模块间的耦合度。
三、优缺点
优点:实现松耦合;
缺点:对性能有一定损失,不过现在各个产品都进行了优化升级,目前性能已经相差不会太大了。
四、IoC相关产品
Unity,Autofac,Castle,Munq,Funq,Ninject,windsor,StructMap
在后面的系列中将介绍其中几种Ioc容器。