本文参考:http://www.cnblogs.com/willick/p/3223042.html
1、在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用。这种"需要",就称为依赖注入(Dependency Injection)。
2、依赖注入和和所谓的控制反转(Inversion of Control )是一个意思。
3、依赖注入是通过接口实现松耦合的设计模式,是解耦的重要手段。
4、依赖注入分为两步:移除对组件的依赖;通过类的构造器(或setter访问器)来传递实现了公开接口的组件的引用。
5、示例:
- 产品类定义
public class Product { public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } }
- 公开接口定义
public interface IValueCalculator { decimal ValueProducts(params Product[] products); }
- 公开接口实现类
public class LinqValueCalculator : IValueCalculator { public decimal ValueProducts(params Product[] products) { return products.Sum(p => p.Price); } }
- 使用接口的类(不依赖注入)
public class ShoppingCart { //计算购物车内商品总价钱 public decimal CalculateStockValue() { Product[] products = { new Product {Name = "西瓜", Category = "水果", Price = 2.3M}, new Product {Name = "苹果", Category = "水果", Price = 4.9M}, new Product {Name = "空心菜", Category = "蔬菜", Price = 2.2M}, new Product {Name = "地瓜", Category = "蔬菜", Price = 1.9M} }; IValueCalculator calculator = new LinqValueCalculator(); //计算商品总价钱 decimal totalValue = calculator.ValueProducts(products); return totalValue; } }
- 使用接口的类(依赖注入)
public class ShoppingCart { IValueCalculator calculator; //构造函数,参数为实现了IValueCalculator接口的类的实例 public ShoppingCart(IValueCalculator calcParam) { calculator = calcParam; } //计算购物车内商品总价钱 public decimal CalculateStockValue() { Product[] products =
{ new Product {Name = "西瓜", Category = "水果", Price = 2.3M}, new Product {Name = "苹果", Category = "水果", Price = 4.9M}, new Product {Name = "空心菜", Category = "蔬菜", Price = 2.2M}, new Product {Name = "地瓜", Category = "蔬菜", Price = 1.9M} }; //计算商品总价钱 decimal totalValue = calculator.ValueProducts(products); return totalValue; } }
这样就彻底断开了ShoppingCart和LinqValueCalculator之间的依赖关系,使用实现了IValueCalculator接口的类(示例中的LinqValueCalculator)的实例引用作为参数,传递给ShoppingCart类的构造函数。ShoppingCart类不知道也不关心这个实现了IValueCalculator接口的类是什么,更没有责任去操作这个类。
ShoppingCart、LinqValueCalculator和IValueCalculator之间的关系: