ASP.NET Core依赖注入系列教程之控制反转(IoC)

前言

ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了“标准化”,我们将这些标准化的组件称为服务,ASP.NET在内部专门维护了一个DI容器来提供所需的服务。要了解这个DI容器以及现实其中的服务提供机制,我们先得知道什么是DI(Dependence Injection),而一旦我们提到DI,又不得不说IoC(Inverse of Control)。

一、流程控制的反转

我听到很多人将IoC说成是一种“面向对象的设计模式”,但在我个人看来IoC不能算作一种“设计模式”,其自身也与“面向对象”没有直接的关系。很多人之所以不能很准确地理解IoC源于他们忽略了一个最根本的东西,那就是IoC这个短语。换句话说,很多人之所以对IoC产生了诸多误解是因为他们忽略了IoC的定义。

IoC的全名Inverse of Control,翻译成中文就是“控制反转”或者“控制倒置”。控制反转也好,控制倒置也罢,它体现的意思是控制权的转移,即原来控制权在A手中,现在需要B来接管。那么具体对于软件设计来说,IoC所谓的控制权的转移具有怎样的体现呢?要回答这个问题,就需要先了解IoC的C(Control)究竟指的是怎样一种控制,在我看来这里所谓的控制更多地体现为一种“流程的控制”。

我们通过一个具体事例来说明传统的设计在采用了IoC之后针对流程的控制是如何实现反转的。比如说我们现在设计一个针对Web的MVC类库,不妨将其命名为MvcLib。MvcLib提供了如下所示的API帮助我们完成整个HTTP请求流程中的主要任务。具体来说,ListenAndReceiveRequest方法启动一个监听器绑定到指定的地址进行请求的监听,接收到的请求通过一个Request对象返回。ActivateController方法根据接收到的请求解析并激活请求的目标Controller。ExecuteContrller方法执行激活的Controller并返回一个表示视图的View对象。RenderView最终将View对象转换成HTML并作为当前请求响应的内容。

 public static class MvcLib
 {
 public static Request ListenAndReceiveRequest(Uri address);
 public static Controller ActivateController (Request request);
 public static View ExecuteContrller(Controller controller);
 public static void RenderView(View view);
 } 

现在我们在这个MvcLib的基础上创建一个真正的MVC应用,那么除了按照MvcLib的规范自定义具体的Controller和View之外,我们还需要自行控制从请求的监听与接收、Controller的激活与执行以及View的最终呈现在内的整个流程,这样一个执行流程反映在如下所示的代码中。

 public class App
 {
 static void Main(string[] args)
 {
 Uri address = new Uri("http://localhost/mvcapp");
 while (true)
 {
 Request request = MvcLib.ListenAndReceiveRequest(address);
 Task.Run(()=> ProcessRequest(request));
 }
 }

 private static void ProcessRequest(Request request)
 {
 Controller controller = MvcLib.ActiveController(request);
 View view = MvcLib.ExecuteContrller(controller);
 MvcLib.RenderView(view);
 }
 }

这个例子体现了右如图所示的流程控制方式,即我们设计的类库(MvcLib)仅仅通过API的形式提供某种单一功能的实现,作为类库消费者的应用程序(App)则需要自行编排整个工作流程。如果从重用的角度来讲,这里被重用的仅限于实现某个环节单一功能的代码,编排整个工作流程的代码并没有得到重用。

当我们构建一个应用的时候,我们不仅仅是需要一个能够提供API的类库,实际上更理想的形式是直接在一个现有的框架上构架我们的应用。类库(Library)和框架(Framework)的不同之处在于,前者往往只是提供实现某种单一功能的API,而后者则针对一个目标任务对这些单一功能进行编排形成一个完整的流程,这个流程在一个引擎的驱动下被执行。

在我们上面演示MvcLib来说,使用它的应用程序需要自行控制整个HTTP请求的处理流程,实际上这是一个很“泛化”的工作流程,几乎所有的MVC应用均采用这样的流程监听、接收请求并最终对请求予以响应。如果我们将这个流程实现在一个MVC框架之中,由它构建的所有MVC应用就可以直接使用这个请求处理流程,而并不需要自行重复实现它。

现在我们将MvcLib从类库改造成一个框架,并姑且将其称为MvcFrame。如左图所示,MvcFrame的核心是一个被称为MvcEngine的执行引擎,它驱动一个编排好的工作流对HTTP请求进行一致性处理。如果我们利用MvcFrame构建一个具体的MVC应用,除了根据我们的业务需求定义相应的Controller和View之外,我们只需要初始化这个引擎并直接启动它即可。如果你曾经开发过ASP.NET MVC应用,你会发现ASP.NET MVC就是这么一个框架。

有了上面演示的这个例子作为铺垫,我们应该很容易理解IoC所谓的控制反转了。总的来说,IoC是我们设计框架所采用的设计思想,所谓的控制反转即是按照如右图所示的方式将原来实现在应用程序流程控制转移到框架中。被转移的是一个泛化的可重用的处理流程,所以IoC符合软件设计一个基本的原则,即重用性。

二、对流程的定制

我们采用IoC实现了流程控制从应用程序向框架自身的反转,但是这个被反转的仅仅是一个泛化的流程,任何一个具体的应用都可能需要对组成该流程的某些环节进行定制。如左图所示,我们将一个泛化的工作流程(A=>B=>C)被定义在框架之中,建立在该框架的两个应用需要对组成这个流程的某些环节进行定制。比如步骤A和C可以被App1重用,但是步骤B却需要被定制(B1),App2则重用步骤A和B,但是需要按照自己的方式(C2)处理步骤C。

IoC将对流程的控制从应用程序转移到框架之中,框架利用一个引擎驱动整个流程的执行。换句话说,应用程序无需关心该工作流程的细节,它只需要启动这个引擎即可。但是这个引擎一旦被启动,框架就会完全按照预先编排好的流程进行工作,如果应用程序希望整个流程按照自己希望的方式被执行,针对流程的定制一般在发生在启动引擎之前。

一般来说,框架会以相应的形式提供一系列的扩展点,应用程序则通过定义扩展的方式实现对流程某个环节的定制。在引擎被启动之前,应用程序将所需的扩展注册到框架之中。一旦引擎被正常启动,这些注册的扩展会自动参与到整个流程的执行过程中。

虽然应用程序是框架引擎的启动着,但是一旦引擎被启动之后它就丧失了对流程的控制,应用程序对流程的定制不是在执行过程中对框架的干预来完成的,而只需要在流程执行之前就将定制的部分准备好,框架自身在执行过程中会智能地选择它们。从这个意义上讲,IoC对流程的定制遵循着这样一个原则,即“Don't call us, we'll call you!”,它被称为好莱坞原则。

综上所述,IoC一方面通过流程控制从应用程序向框架的反转实现了针对流程自身的重用,另一方面采用“好莱坞原则”使得这个被重用的流程可能自由地被定制,这两个因素实际上决定了框架自身的价值。重用让框架不仅仅是为应用程序提供实现单一功能的API,而是提供一整套可执行的解决方案;可定制则使我们可以为不同的应用程序对框架进行定制,这无疑让框架可以使用到更多的应用之中。

三、 IoC模式

正如我们在上面提到过的,很多人将IoC理解为一种“面向对象的设计模式”,实际上IoC自身不仅与面向对象没有必然的联系,它也算不上是一种设计模式。一般来讲,设计模式提供了一种解决某种具体问题的方案,但是IoC既没有一个针对性的问题领域,其自身没有提供一种可实施的解决方案,所以我更加倾向于将IoC视为一种设计原则,实际上很多我们熟悉的设计模式背后采用了IoC原则。

模板方法(Template Method)

提到IoC,很多人首先想到的是DI,但是在我看来与IoC联系得最为紧密的则是另一种被称为“模板方法”的设计模式。模板方法模式与IoC的意图可以说完全一致,该模式主张将一个可复用的工作流程或者由多个步骤组成的算法定义成模板方法,组成这个流程或者算法的步骤则实现在相应的虚方法之中,模板方法根据流程先后调用这些虚方法。所有这些方法均定义在同一个类中,我们可以通过派生该类并重写相应的虚方法达到对流程定制的目的。

对于上面我们演示的这个MVC的例子,我们可以将整个请求处理流程实现在如下一个MvcEngine类中,请求的监听与接收、目标Controller的激活与执行以及View的呈现则分别定义在四个受保护的虚方法中,模板方法Start根据预定义的请求处理流程先后调用这四个方法。

 public class MvcEngine
 {
 public void Start(Uri address)
 {
 while (true)
 {
 Request request = this.OnListenAndReceiveRequest(address);
 Task.Run(() =>
 {
  Controller controller = this.OnActivateController(request);
  View view = this.OnExecuteContrller(controller);
  this.OnRenderView(view);
 });
 }
 }
 protected virtual Request OnListenAndReceiveRequest(Uri address) ;
 protected virtual Controller OnActivateController(Request request) ;
 protected virtual View OnExecuteContrller(Controller controller) ;
 protected virtual void OnRenderView(View view) ;
 }

对于具体的应用来说,如果定义在MvcEngine针对请求的处理方式完全符合它的要求,它只需要创建这个一个MvcEngine对象,然后指定一个对应的基地址调用模板方法Start开启这个MVC引擎即可。如果该MVC引擎处理请求的某个环节不能满足它的要求,它可以创建MvcEngine的派生类,并重写实现该环节的相应虚方法即可。比如说定义在某个应用程序中的Controller都是无状态的,它希望采用单例(Singleton)的方式重用已经激活的Controller以提高性能,那么它就可以按照如下的方式创建一个自定义的FoobarMvcEngine并按照自己的方式重写OnActivateController方法既可。

 public class FoobarMvcEngine : MvcEngine
 {
 protected override View OnExecuteContrller(Controller controller)
 {
 <<省略实现>>
 }
 }

模板方法如果结合“事件注册”往往可以使应用程序对流程的定制变得更加自由。如下面的代码片段所示,我们为Controller的激活与执行以及View的呈现定义了六个事件,它们分别在这个三个环节开始之前和结束之后被触发。这么一个MvcEngine可以直接被使用,应用程序只需要注册相应的事件完成对请求处理流程的定制。

 public class MvcEngine
 {
 //其他成员
 protected virtual Controller OnActivateController(Request request) ;
 protected virtual View OnExecuteContrller(Controller controller) ;
 protected virtual void OnRenderView(View view) ;

 public EventHandler<ControllerActivationEventArgs> ControllerActivating;
 public EventHandler<ControllerActivationEventArgs> ControllerActivated;
 public EventHandler<ControllerExecutionEventArgs> ControllerExecuting;
 public EventHandler<ControllerExecutionEventArgs> ControllerExecuted;
 public EventHandler<ViewRenderEventArgs> ViewRendering;
 public EventHandler<ViewRenderEventArgs> ViewRendered;
 }

工厂方法(Factory Method)

对于一个复杂的流程来说,我们倾向于将组成该流程的各个环节实现在相应独立的组件之中,那么针对流程的定制就可以通过提供不同组件的形式来实现。我们知道23种设计模式之中有一种重要的类型,那就是“创建型模式”,比如常用的“工厂方法”和“抽象工厂”,那么IoC所体现的针对流程的共享与定制可以通过它们来完成。

所谓的工厂方法,说白了就是在某个类中用于提供依赖对象的方法,这个方法可以是一个单纯的虚方法,也可以是具有默认实现的虚方法,至于方法声明的返回类型,可以是一个接口或者抽象类,也可以是未被封闭(Sealed)的具体类型。作为它的派生类型,它可以实现或者重写工厂方法以提供所需的具体对象。

同样以我们的MVC框架为例,我们让独立的对象来完成组成整个请求处理流程的四个核心环节。具体来说,我们分别定义了四个核心的类型(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)来分别负责请求监听与接收、Controller的激活、Controller的执行以及View的呈现。这四个对象按照如右图所示的顺序相互协作完成对请求的处理。

如下所示的Listener、ControllerActivator、ControllerExecutor和ViewGenderer这四个类型的简单定义。我们没有将它们定义成单纯的抽象类或者接口,而是未被封闭可以被继承的一般类型,定义其中的虚方法具有默认的实现。只有这些默认的实现方式无法满足应用程序具体需求的时候,我们才需要定义相应的派生类。

 public class Listener
 {
 public virtual Request Listen(Uri address) ;
 }

 public class ControllerActivator
 {
 public virtual Controller ActivateController(Request request) ;
 }

 public class ControllerExecutor
 {
 public virtual View ExecuteController(Controller controller) ;
 }

 public class ViewRenderer
 {
 public virtual void RenderView(View view) ;
 }

在作为MVC引擎的MvcEngine类中,我们定义了四个工厂方法(GetListener、GetControllerActivator、GetControllerExecutor和GetViewRenderer)来提供上述这四种类型的对象。这四个工厂方法均为具有默认实现的虚方法,它们默认提供上述四种类型的对象。在用于启动引擎的Start方法中,我们利用这些工厂方法提供的对象来具体完成请求处理流程的各个核心环节。

 public class MvcEngine
 {
 public void Start(Uri address)
 {
  while (true)
  {
  Request request = this.GetListener().Listen(address);
  Task.Run(() =>
  {
   Controller controller = this.GetControllerActivator()
   .ActivateController(request);
   View view = this.GetControllerExecutor()
   .ExecuteController(controller);
   this.GetViewRenderer().RenderView(view);
  });
  }
 }

 protected virtual Listener GetListener()
 {
  return new Listener();
 }

 protected virtual ControllerActivator GetControllerActivator()
 {
  return new ControllerActivator();
 }

 protected virtual ControllerExecutor GetControllerExecutor()
 {
  return new ControllerExecutor();
 }

 protected virtual ViewRenderer GetViewRenderer()
 {
  return new ViewRenderer();
 }
 }

对于具体的应用程序来说,如果需要对请求处理的某个环节进行定制,它需要将定制的操作实现在对应类型(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)的派生类中。在MvcEngine的派生类中,我们需要重写对应的工厂方法来提供被定制的对象。 比如上面提及的以单例模式提供目标Controller对象的实现就定义在SingletonControllerActivator类中,我们在派生于MvcEngine的FoobarMvcEngine类中重写了工厂方法GetControllerActivator使其返回一个SingletonControllerActivator对象。

 public class SingletonControllerActivator : ControllerActivator
 {
 public override Controller ActivateController(Request request)
 {
  <<省略实现>>
 }
 }

 public class FoobarMvcEngine : MvcEngine
 {
 protected override ControllerActivator GetControllerActivator()
 {
  return new SingletonControllerActivator();
 }
 }

上面我们采用工厂方法模式对MVC框架进行了重新设计,右图清晰地展示了该框架以MvcEngine为核心的相关组件之间的相互关系,同时也体现了采用派生MvcEngine(FoobarMvcEngine)具体的应用是如何通过重写工厂方法(GetControllerActivator)对框架实施定制的。

抽象工厂(Abstract Factory)

虽然工厂方法和抽象工厂均提供了一个“生产”对象实例的工厂,但是两者在设计上却有本质的不同。工厂方法利用定义在某个类型的抽象方法或者虚方法实现了针对单一对象提供方式的抽象,而抽象工厂在利用一个独立的接口或者类来实现对一组相关对象提供的抽象。

具体来说,我们需要定义一个独立的工厂接口或者抽象工厂类,并在其中定义多个的工厂方法来提供“同一系列”的多个相关对象。如果希望抽象工厂具有一组默认的“产出”,我们也可以将一个未被封闭的具体类作为抽象工厂,以虚方法形式定义的工厂方法将默认的对象作为返回值。我们根据实际的需要通过实现工厂接口或者继承抽象工厂类(不一定是抽象类)定义具体工厂类来提供一组定制的系列对象。

现在我们采用抽象工厂模式来改造我们的MVC框架。如下面的代码片段所示,我们定义了一个实例类EngineFactory作为创建MvcEngine所需四种对象(Listener、ControllerActivator、ControllerExecutor和ViewGenderer)的抽象工厂,定义其中的四个工厂方法的返回值体现了工厂默认的产出。我们在创建MvcEngine对象可以提供一个具体的EngineFactory对象(如果没有显式指定,MvcEngine默认使用的是一个自动创建的EngineFactory对象)。在用于启动引擎的Start方法中,MvcEngine利用EngineFactory来获取相应的对象协作完整对请求的处理流程。 对于我们采用抽象工厂改造后的MVC框架,以MvcEngine为核心的相关组件之间的关系体现在如左图所示的UML中。

 public class EngineFactory
 {
 public virtual Listener GetListener()
 {
  return new Listener();
 }

 public virtual ControllerActivator GetControllerActivator()
 {
  return new ControllerActivator();
 }

 public virtual ControllerExecutor GetControllerExecutor()
 {
  return new ControllerExecutor();
 }

 public virtual ViewRenderer GetViewRenderer()
 {
  return new ViewRenderer();
 }
 }

 public class MvcEngine
 {
 public EngineFactory Factory { get; private set; }

 public MvcEngine(EngineFactory factory = null)
 {
  this.Factory = factory ?? new EngineFactory();
 }

 public void Start(Uri address)
 {
  while (true)
  {
  Request request = this.Factory.GetListener().Listen(address);
  Task.Run(() =>
  {
   Controller controller = this.Factory.GetControllerActivator()
   .ActivateController(request);
   View view = this.Factory.GetControllerExecutor()
   .ExecuteController(controller);
   this.Factory.GetViewRenderer().RenderView(view);
  });
  }
 }
 } 

如果具体的应用程序需要采用上面定义的SingletonControllerActivator以单例的模式来激活目标Controller,我们可以按照如下的方式定义一个具体的工厂类FoobarEngineFactory。最终的应用程序将这么一个FoobarEngineFactory对象作为MvcEngine的EngineFactory。

 public class FoobarEngineFactory : EngineFactory
 {
 public override ControllerActivator GetControllerActivator()
 {
  return new SingletonControllerActivator();
 }
 }

 public class App
 {
 static void Main(string[] args)
 {
  Uri  address = new Uri("http://localhost/mvcapp");
  MvcEngine engine = new MvcEngine(new FoobarEngineFactory());
  Engine.Start(address);
 }
 }

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • ASP.NET Core依赖注入系列教程之服务的注册与提供

    前言 在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core中的DI容器体现为一个实现了IServiceProvider接口的对象. ServiceProvider与ServiceDescriptor 服务的注册与提供     利用ServiceProvider来提供服务     提供一个服务实例的集合     获取ServiceProvider自身对

  • 解读ASP.NET 5 & MVC6系列教程(7):依赖注入

    在前面的章节(Middleware章节)中,我们提到了依赖注入功能(Dependency Injection),ASP.NET 5正式将依赖注入进行了全功能的实现,以便开发人员能够开发更具弹性的组件程序,MVC6也利用了依赖注入的功能重新对Controller和View的服务注入功能进行了重新设计:未来的依赖注入功能还可能提供更多的API,所有如果还没有开始接触依赖注入的话,就得好好学一下了. 在之前版本的依赖注入功能里,依赖注入的入口有MVC中的IControllerFactory和Web A

  • 详解ASP.NET Core 在 JSON 文件中配置依赖注入

    前言 在上一篇文章中写了如何在MVC中配置全局路由前缀,今天给大家介绍一下如何在在 json 文件中配置依赖注入. 在以前的 ASP.NET 4+ (MVC,Web Api,Owin,SingalR等)时候,都是提供了专有的接口以供使用第三方的依赖注入组件,比如我们常用的会使用 Autofac.Untiy.String.Net 等,这些第三放依赖注入组件基本上都提供了一套配置注入或者配置生命周期的方式,除了直接配置到类里面之外,还提供了要么使用 xml 文件,要么使用 json 等,那么在新的

  • 详解ASP.NET Core 中的框架级依赖注入

    1.ASP.NET Core 中的依赖注入 此示例展示了框架级依赖注入如何在 ASP.NET Core 中工作. 其简单但功能强大,足以完成大部分的依赖注入工作.框架级依赖注入支持以下 scope: Singleton - 总是返回相同的实例 Transient - 每次都返回新的实例 Scoped - 在当前(request)范围内返回相同的实例 假设我们有两个要通过依赖注入来进行工作的工件: PageContext - 自定义请求上下文 Settings - 全局应用程序设置 这两个都是非常

  • 扩展ASP.NET MVC三层框架且使用StructureMap实现依赖注入1-Model层

    本篇文章将向大家介绍如何添加Service和Repository层并且使用StructureMap把Service层注入到Controller,把Repository注入到Service层.Service层主要是我们的业务逻辑层,这一层不和底层的Database打交道,和Database打交道的是Repository数据持久层.本篇文章通过使用StructureMap依赖注入使Controller,Service,Repository三层的耦合度降到最低. 本系统使用NorthWind开源数据,

  • ASP.NET Core依赖注入系列教程之控制反转(IoC)

    前言 ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化",我们将这些标准化的组件称为服务,ASP.NET在内部专门维护了一个DI容器来提供所需的服务.要了解这个DI容器以及现实其中的服务提供机制,我们先得知道什么是DI(Dependence Injection),而一旦我们提到DI,又不得不说IoC(Inverse of Control). 一.流程控

  • 详解asp.net core 依赖注入

    前言 好久没有写微博了,因为前段时间由于家庭原因决定从工作了3年多的北京转移到上海去.依赖注入在学习net core的时候也有写过类似的东西,只是实践的较少,结果来到上海新公司系统框架涉及到了这块知识点,所以在了解完自己的项目之后决定做一些相关的总结.接下来就让我们先来了解hewi依赖注入. 什么是依赖注入 依赖注入,全称是"依赖注入到容器", 容器(IOC容器)是一个设计模式,它也是个对象,你把某个类(不管有多少依赖关系)放入这个容器中,可以"解析"出这个类的实例

  • 理解ASP.NET Core 依赖注入(Dependency Injection)

    目录 依赖注入 什么是依赖注入 依赖注入有什么好处 ASP.NET Core内置的依赖注入 服务生存周期 服务释放 TryAdd{Lifetime}扩展方法 解析同一服务的多个不同实现 Replace && Remove 扩展方法 Autofac 服务解析和注入 构造函数注入 方法注入 属性注入 一些注意事项 框架默认提供的服务 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接收注入的对象实例即可. 微软官方文档-DI 依赖注入有什么好处 依赖

  • ASP.NET Core  依赖注入框架的使用

    目录 一.IoC框架 二.IoC-Autofac 三..NET Core中自带DI的使用 四.Autofac 使用 五.批量注入 前言: 还记得上篇文章中ASP.NET Core 依赖注入详细最后提及到,假如服务越来越多怎么处理呢,本篇文章将会带来解决办法.这篇是接上一篇文章的,概念方面的可以参考上一篇文章. 一.IoC框架 先说说常见的Ioc框架吧. Autofac: 目前net用的比较多,好多大佬的项目比较优先选择的框架. Ninject: 已经很少用了,还时在很早的文章中见过. Unity

  • ASP.NET Core 依赖注入详细

    目录 一.控制反转 二.好莱坞法则 三.流程控制 四.三种依赖注入方式 1.构造器注入 2.属性注入 3.方法注入 五.生命周期 六.ASP.Net Core 中自带的注入 前言: ASP.NET Core 应用在启动过程中会依赖各种组件提供服务,而这些组件会以接口的形式标准化,这些组件这就是我们所说的服务,ASP.NET Core框架建立在一个底层的依赖注入框架之上,它使用容器提供所需的服务.要了解依赖注入容器以及它的机制,我们需要了解什么是依赖注入. 一.控制反转 说道依赖注入就不得不提控制

  • ASP.NET Core依赖注入详解

    目录 一.什么是依赖注入 二.使用框架提供的服务 三.注册服务 四.生命周期 五.请求服务 六.设计你的依赖服务 ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core应用程序可以利用内置的框架服务将它们注入到启动类的方法中,并且应用程序服务能够配置注入.由ASP.NET Core提供的默认服务容器提供了最小功能集,并不是要取代其它容器. 一.什么是依赖注入 依赖注入(Dependency injection,DI)是一种实现对象及其合作者或依赖项之间松散耦合的技术.将类

  • ASP.NET Core依赖注入(DI)讲解

    ASP.NET Core的底层设计支持和使用依赖注入.ASP.NET Core 应用程序可以利用内置的框架服务将服务注入到启动类的方法中,并且应用程序服务也可以配置注入.由ASP.NET Core 提供的默认服务容器提供了最小功能集,并不是取代其他容器. 1.浅谈依赖注入 依赖注入(Dependency injection,DI)是一种实现对象和依赖者之间松耦合的技术,将类用来执行其操作的这些对象以注入的方式提供给该类,而不是直接实例化依赖项或者使用静态引用.一般情况,类会通过构造函数声明器2依

  • Angular 4依赖注入学习教程之简介(一)

    学习目录 Angular 4 依赖注入教程之一 依赖注入简介 Angular 4 依赖注入教程之二 组件服务注入 Angular 4 依赖注入教程之三 ClassProvider的使用 Angular 4 依赖注入教程之四 FactoryProvider的使用 Angular 4 依赖注入教程之五 FactoryProvider配置依赖对象 Angular 4 依赖注入教程之六 Injectable 装饰器 Angular 4 依赖注入教程之七 ValueProvider的使用 Angular

  • ASP.NET Core依赖关系注入

    1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等老生常谈的概念,初学者很容易被这些概念搞晕(包括我在内),在学习Core依赖注入服务之前,下面让我们先了解下依赖倒置原则(DIP).依赖注入(DI).控制反转(IOC)等概念,然后再深入学习Core依赖注入服务. 2.依赖倒置原则(DIP) 高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口.通俗来讲,就是高层模块定义接口,低层模块负责实现.

随机推荐