IoC,Dependency Injection,Service Locator

控制注入原则,DIP,Dependency Inversion Principle

  1. 高层模块不应该依赖于低层模块。而两者都应该依赖于抽象(接口)。
  2. 抽象不应该依赖于细节,细节应该依赖于抽象。

DIP通过让高层模块依赖于抽象而不是依赖于低层模块的具体的实现,帮助我们开发松耦合的代码。反转控制模式是这个原则的一个实现方式。

 

反转控制,IoC,Inversion of Control

 

IoC指的是一种编程风格,在框架或runtime上控制程序的流程。IoC改变了正常的控制方式,它运行于DIP之上,大多数.NET Framework的软件都用IoC。

比如:

  1. 当写ASP.NET的程序时,进入了ASP.NET页面的生命周期,但是不能控制它。
  2. 当写WCF服务时,用属性装饰实现的接口。你可能写服务代码,但是从根本上没有控制WCF。

更多的,IoC是一个通用的术语,而不局限于DI。实际上,DI和Service Locator模式是特定的IoC模式的版本,或者可以说DI和Service Locator是实现IoC的方式。

比如,假设Client类需要使用Service类组件,然后能做的事情是让Client类知道IService接口而不是Service类。用这种方式,可以在任何时候改变Service类的实现,而不用破坏host的代码。

 

IoC和DIP

 

DIP说高层模块不应该依赖于低层模块,而两者都应该依赖于抽象。IoC是一种提供抽象的方式,是一种改变控制的方式。IoC给出了一些实现DIP的方式。如果你想让高层模块和低层模块相对独立,那么需要反转控制,这样低层模块不控制接口和对象的创建,最后IoC给出一些控制反转的方式。

 

IoC和DI

术语依赖注入DI(Dependency Injection)和控制反转IoC(Inversion of Control)通常可以互换,来描述相同的设计模式。这种模式起初叫IoC,但是Martin Fowler提出了DI,因为所有的框架都在某种程度上反转控制,然后他想更具体地指定哪方面的控制被反转了。

 

依赖注入,DI,Dependency Injection

DI是一个软件设计模式,允许我们开发松耦合的代码。DI是一种很好的方式来减少软件组件间的紧耦合。DI还允许我们更好的管理未来的改变和软件中的其他复杂性。DI的目的是让代码可维护。

依赖注入模式使用一个builder对象来初始化,并提供对象所需的依赖,意味着它允许你从类外“注入”依赖。

 

SL,Service Locator

Service Locator是一个软件设计模式,允许我们开发松耦合的代码。它实现了DIP原则,并且可以容易地用在现有的代码上,因为它使得整体的设计变得宽松,而不用改变public的接口。

Service Locator模式引入了一个locator对象,用来解决依赖,意味着它允许在类中“解决”依赖。

 

DI和SL

我们来考虑两个类之间的简单地依赖,如下图:

 

public class Service
{
 public void Serve()
 {
 Console.WriteLine("Service Called");

 //To Do: Some Stuff
 }
}
 
public class Client
{
 private Service _service;
 
 public Client()
 {
 this._service = new Service();
 }
 
 public void Start()
 {
 Console.WriteLine("Service Started");
 this._service.Serve();

 //To Do: Some Stuff
 }
}


明显,Client类依赖于Service类。如果你想让它松耦合,你不得不使用IoC让它更灵活和能够重用。

要实现IoC,可以用SL和DI。SL允许你在一个类中“解决”依赖,DI允许你从类外“注入”依赖。

 

使用Service Locator

 

public interface IService
{
 void Serve();
}

public class Service : IService
{
 public void Serve()
 {
 Console.WriteLine("Service Called");
 
 //To Do: Some Stuff
 }
}

public static class LocateService
{
 public static IService _Service { get; set; }

 public static IService GetService()
 {
 if (_Service == null)
 _Service = new Service();

 return _Service;
 }
}

public class Client
{
 private IService _service;

 public Client()
 {
 this._service = LocateService.GetService();
 }

 public void Start()
 {
 Console.WriteLine("Service Started");
 this._service.Serve();
 
 //To Do: Some Stuff
 }
}

Service Locator的实现:

class Program
{
 static void Main(string[] args)
 {
 var client = new Client();
 client.Start();
 
 Console.ReadKey();
 }
}


反转发生在构造函数中,通过放置Service实现IService接口。依赖通过Locator组装起来。

 

使用依赖注入

 

public interface IService
{
 void Serve();
}

public class Service : IService
{
 public void Serve()
 {
 Console.WriteLine("Service Called");

 //To Do: Some Stuff
 }
}

public class Client
{
 private IService _service;

 public Client(IService service)
 {
 this._service = service;
 }

 public void Start()
 {
 Console.WriteLine("Service Started");
 this._service.Serve();

 //To Do: Some Stuff
 }
}

使用Builder的实现:

class Program
{
 static void Main(string[] args)
 {
 client = new Client(new Service());
 client.Start();

 Console.ReadKey();
 }
}


依赖注入发生在构造函数中,通过放置Service实现IService接口。依赖通过Builder组装起来,Builder负责:

  1. 知道每个IService的类型。
  2. 根据请求,把抽象的IService喂给Client。

 

依赖注入 VS Service Locator

 

  1. 当使用service locator时,每个类都有一个对service locator的依赖。而依赖注入只在启动时调用一次,把依赖注入到main类中。
  2. service locator模式易用于现有的代码中,不用修改public的接口就可以松耦合。但是可读性比依赖入要差。
翻译自:
http://www.dotnet-tricks.com/Tutorial/dependencyinjection/bSVa100413-Understanding-Inversion-of-Control,-Dependency-Injection-and-Service-Locator.html
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值