IoC
前言
在说这些名词前,我们先弄清楚两个词的区别:设计原则和设计模式。
设计原则
为软件设计提供高级指导,不提供实现,不受编程语言约束。例如:SOLID(SRP,OCP,LSP,ISP,DIP)原则。
例如,单一责任原则(SRP)表明,一个类应该只有一个原因要改变。这是我们在为应用程序设计或创建类时可以牢记的高级声明。 SRP不提供具体的实施步骤。
设计模式
常为面向对象的问题提供低级解决方案(实现)。换句话说,设计模式为具体的面向对象编程问题提出了具体的实现。
例如,如果要创建一次只能有一个对象的类,那么可以使用Singleton设计模式,这样可以创建一个只能有一个对象的类的最佳方法。
理解之后,我们看下图:
紧耦合到松耦合
- 使用工厂模式实现IoC(控制反转)
- 创建抽象层实现DIP(依赖倒置原则)
- 实现DI(依赖注入)
- 使用IoC容器
举例子
public class CustomerBusinessLogic
{
DataAccess _dataAccess;
public CustomerBusinessLogic()
{
_dataAccess = new DataAccess();
}
public string GetCustomerName(int id)
{
return _dataAccess.GetCustomerName(id);
}
}
public class DataAccess
{
public DataAccess()
{
}
public string GetCustomerName(int id) {
return "Dummy Customer Name"; // get it from DB in real app
}
}
1.使用工厂模式实现IoC
public class CustomerBusinessLogic
{
public CustomerBusinessLogic()
{
}
public string GetCustomerName(int id)
{
DataAccess _dataAccess = DataAccessFactory.GetDataAccessObj();
return _dataAccess.GetCustomerName(id);
}
}
public class DataAccessFactory
{
public static DataAccess GetDataAccessObj()
{
return new DataAccess();
}
}
public class DataAccess
{
public DataAccess()
{
}
public string GetCustomerName(int id) {
return "Dummy Customer Name"; // get it from DB in real app
}
}
2.创建抽象层实现DIP
- 高级模块不应该依赖于低级模块,两者都应该取决于抽象。
- 抽象不应该依赖细节,细节应该取决于抽象。
public interface ICustomerDataAccess
{
string GetCustomerName(int id);
}
public class CustomerDataAccess: ICustomerDataAccess
{
public CustomerDataAccess() {
}
public string GetCustomerName(int id) {
return "Dummy Customer Name";
}
}
public class DataAccessFactory
{
public static ICustomerDataAccess GetCustomerDataAccessObj()
{
return new CustomerDataAccess();
}
}
public class CustomerBusinessLogic
{
ICustomerDataAccess _custDataAccess;
public CustomerBusinessLogic()
{
_custDataAccess = DataAccessFactory.GetCustomerDataAccessObj();
}
public string GetCustomerName(int id)
{
return _custDataAccess.GetCustomerName(id);
}
}
3.实现DI
- 构造函数注入
- 属性注入
- 方法注入
构造函数注入示例:
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
_customerBL = new CustomerBusinessLogic(new CustomerDataAccess());
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}
属性注入示例:
public class CustomerBusinessLogic
{
public CustomerBusinessLogic()
{
}
public string GetCustomerName(int id)
{
return DataAccess.GetCustomerName(id);
}
public ICustomerDataAccess DataAccess { get; set; }
}
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
_customerBL.DataAccess = new CustomerDataAccess();
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}
方法注入示例:
interface IDataAccessDependency
{
void SetDependency(ICustomerDataAccess customerDataAccess);
}
public class CustomerBusinessLogic : IDataAccessDependency
{
ICustomerDataAccess _dataAccess;
public CustomerBusinessLogic()
{
}
public string GetCustomerName(int id)
{
return _dataAccess.GetCustomerName(id);
}
public void SetDependency(ICustomerDataAccess customerDataAccess)
{
_dataAccess = customerDataAccess;
}
}
public class CustomerService
{
CustomerBusinessLogic _customerBL;
public CustomerService()
{
_customerBL = new CustomerBusinessLogic();
((IDataAccessDependency)_customerBL).SetDependency(new CustomerDataAccess());
}
public string GetCustomerName(int id) {
return _customerBL.GetCustomerName(id);
}
}
4.使用IoC容器
- MEF
- Autofac
- Unity
来源
内容和图片均来自:http://www.tutorialsteacher.com/ioc