依赖注入(DI)

摘自【老A】http://www.cnblogs.com/wow-xc/p/9027315.html

摘自【Jesse】http://www.jessetalk.cn/2017/11/06/di-in-aspnetcore/

  IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用“好莱坞原则”是应用程序以被动的方式实现对流程的定制。我们可以采用若干设计模式以不同的方式实现IoC,比如我们在上面介绍的模板方法、工厂方法和抽象工厂,接下来我们介绍一种更为有价值的IoC模式,即依赖注入(DI:Dependency Injection,以下简称DI)。

  DI 旨在实现针对服务对象的动态提供。具体来说,服务的消费者利用一个独立的容器(Container)来获取所需的服务对象,容器自身在提供服务对象的过程中会自动完成依赖的解析与注入。换句话说,由DI容器提供的这个服务对象是一个” 开箱即用”的对象,这个对象自身直接或者间接依赖的对象已经在初始化的工程中被自动注入其中了

  1. 依赖:当一个类需要另一个类协作来完成工作的时候就产生了依。比如我们在AccountController这个控制器需要完成和用户相关的注册、登录 等事情。其中的登录我们由EF结合Idnetity来完成,所以我们封装了一个EFLoginService。这里AccountController就有一个ILoginService的依


  这里有一个设计原则:依于抽象,而不是具体的实现。所以我们给EFLoginService定义了一个接口,抽象了LoginService的行为。

  2. 注入:注入体现的是一个IOC(控制反转的的思想)。

      为什么要反转呢?比如我们现在要把从EF中去验证登录改为从Redis去读,于是我们加了一个 RedisLoginService。这个时候我们只需要在原来注入的地方改一下就可以了。

  3. 容器:(1) 绑定服务与实例之间的关系; (2) 获取实例,并对实例进行管理(创建与销毁)

============================================

.NET Core DI

  在.NET Core中DI的核心分为两个组件:IServiceCollection和 IServiceProvider。(在Microsoft.Extensions.DependencyInjection命名空间下)

    • IServiceCollection 负责注册
    • IServiceProvider 负责提供实例
  .NET Core DI 为我们提供的实例生命周其包括三种:
    • Transient: 每一次GetService都会创建一个新的实例
    • Scoped:  在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)
    • Singleton :整个应用程序生命周期以内只创建一个实例 
  这有什么用?
      如果在Mvc中用过Autofac的InstancePerRequest的同学就知道,有一些对象在一个请求跨越多个Action或者多个Service、Repository,比如最常用的DBContext它可以是一个实例。即能减少实例初始化的消耗,还能实现跨Service事务的功能。(注:在ASP.NET Core中所有用到EF的Service 都需要注册成Scoped )  而实现这种功能的方法就是在整个reqeust请求的生命周期以内共用了一个Scope。

DI 在 ASP.NET Core 中的应用

  •  ASP.NET Core可以在 Startup.cs 的  ConfigureService 中配置 DI。
  • 一般可以通过构造函数或者属性来实现注入,但是官方推荐是通过构造函数。这也是所谓的显式依
  • 在View中需要用@inject 再声明一下,起一个别名。
  • HttpContext 下有一个 RequestedService 同样可以用来获取实例对象,不过这种方法一般不推荐??
  • 替换其它 IoC 容器,比如Autofac。

  

  为什么要替换掉默认的 DI容器?,替换之后有什么影响?.NET Core默认的实现对于一些小型的项目完全够用,甚至大型项目麻烦点也能用,但是会有些麻烦,原因在于只提供了最基本的AddXXXX方法来绑定实例关系,需要一个一个的添加。如果项目可能要添加好几百行这样的方法。
  如果熟悉Autofac的同学可能会这下面这样的代码有映象。这给我们带来了很多便利性。
builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>));
 
builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>));
 

猜你喜欢

转载自www.cnblogs.com/wow-xc/p/9027328.html