问题

如何使用 ASP.NET Core 服务容器进行依赖注入?

答案

创建一个服务

public interface IGreetingService
{     string Greet(string to);
}

public class GreetingService : IGreetingService
{        public string Greet(string to){        return $"Hello {to}";}
}

然后可以在需要的时候注入,下面将此服务注入一个中间件(Middleware):

public class HelloWorldMiddleware
{       private readonly RequestDelegate _next;   

    public HelloWorldMiddleware(RequestDelegate next){_next = next;}  

    public async Task Invoke(HttpContext context, IGreetingService greetingService){         var message = greetingService.Greet("World (via DI)");   await context.Response.WriteAsync(message);}
}

使用此中间件的扩展方法(IApplicationBuilder):

public static class UseMiddlewareExtensions
{        public static IApplicationBuilder UseHelloWorld(this IApplicationBuilder app){        return app.UseMiddleware<HelloWorldMiddleware>();}
}

下面需要将此服务添加到ASP.NET Core的服务容器中,位于Startup.cs文件的ConfigureServices()方法:

public void ConfigureServices(IServiceCollection services)
{services.AddScoped<IGreetingService, GreetingService>();
}

然后在请求管道中(request pipeline)使用此中间件,位于Startup.cs文件的Configure()方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{app.UseHelloWorld();
}

运行,此时页面输出:

创建一个带输入参数的服务

如果你的服务需要更复杂的初始化参数,下面我们创建一个FlexibleGreetingService:

public class FlexibleGreetingService : IGreetingService
{       private readonly string _sayWhat;  

   public FlexibleGreetingService(string sayWhat){_sayWhat = sayWhat;}  

    public string Greet(string to){             return $"{_sayWhat} {to}";}
}

我们可以使用AddScoped的一个重载工厂方法来添加此服务到容器中:

public void ConfigureServices(IServiceCollection services)
{services.AddScoped<IGreetingService, FlexibleGreetingService>(factory =>{       return new FlexibleGreetingService("Hi");});
}

运行,此时页面输出:

如果是单件生命周期,还有一个接受服务实例的重载方法:

public void ConfigureServices(IServiceCollection services)
{services.AddSingleton<IGreetingService>(new FlexibleGreetingService("Hi "));
}

讨论

ASP.NET Core内置了一个轻量级的服务容器。我们可以在Startup.cs类的ConfigureServices()方法中配置需要的服务。这个方法在Configure()方法之前执行,所以我们可以在任意中间件使用之前配置的服务(包含MVC服务)。

依赖注入默认是通过公开构造函数来完成的,大多数情况下这是最佳实践。

服务的生命周期

服务容器管理着添加到服务器列表的生命周期。下面列出了添加服务的三种方法:

  • AddScoped():服务会在一个请求内部只创建一次。

  • AddTransient():服务会在每次需要时创建一次。

  • AddSingleton():服务会在第一次需要时创建一次,并在随后保持不变。

注:EF的生命周期应该是Scoped,我们可以通过IServiceCollection.AddDbContext来创建EF服务(内部也是作为Scoped实现)。

工厂方法

上面的方法都有一个重载方法来使用工厂方法来添加服务。对于需要复杂配置的服务这是很有用的。

这些方法的签名看起来如下所示:

AddScoped(Func<IServiceProvider, TService>)

框架提供的服务

ConfigureServices()接受的IServiceCollection参数拥有很多内置的服务(由框架提供),可以参考ASP.NET Core文档。

IServiceCollection有很多有用的扩展方法来添加常用服务,比如AddDbContext,AddIdentity,AddOptions和AddMvc。

销毁服务

服务容器会自动调用所有实现了IDisposable接口的服务类型,除了那些作为实例(而不是类型)添加的服务。

获取服务(Request Services)

尽管通过构造函数来注入服务被认为是最佳实践,我们依然可以通过IServiceProvider的GetService方法来获取服务。在中间件中IServiceProvider对象可以通过HttpContext来获取:

public async Task Invoke(HttpContext context)
{     var greetingService = context.RequestServices.GetService<IGreetingService>();    var message = greetingService.Greet("World (via GetService)");    await context.Response.WriteAsync(message);
}

注:需要添加Microsoft.Extensions.DependencyInjection引用才能上述使用GetService的泛型重载方法。

运行,此时页面输出:

原文地址:http://www.cnblogs.com/sanshi/p/7705617.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

ASP.NET Core 2.0 依赖注入相关推荐

  1. ASP.NET Core 中的依赖注入

    什么是依赖注入 软件设计原则中有一个依赖倒置原则(DIP),为了更好的解耦,讲究要依赖于抽象,不要依赖于具体.而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖 ...

  2. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理

    ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...

  3. ASP.NET Core MVC 之依赖注入 Controller

    ASP.NET Core MVC 控制器应通过构造函数明确地请求它们地依赖关系,在某些情况下,单个控制器地操作可能需要一个服务,在控制器级别上的请求可能没有意义.在这种情况下,也可以将服务作为  Ac ...

  4. ASP.NET Core MVC 之依赖注入 View

    ASP.NET Core 支持在试图中使用依赖注入.这将有助于提供视图专用的服务,比如本地化或者仅用于填充视图元素的数据.应尽量保持控制器和视图之间的关注点分离.视图所显示的大部分数据应该从控制器传入 ...

  5. ASP.NET Core 下的依赖注入(一)

    本文介绍利用 Microsoft.Extensions.Configuration.Binder.dll 来实现超级简单的注入. 1. appsettings.json 中定义配置 假设我们有如下配置 ...

  6. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  7. .Net Core 3.0依赖注入替换 Autofac

    今天早上,喜庆的更新VS2019,终于3.0正式版了呀~ 有小伙伴问了一句Autofac怎么接入,因为Startup.ConfigureServices不能再把返回值改成IServiceProvide ...

  8. 跟着老桂学ASP.NET Core 2.0

    .net core作为微软开发技术中跨平台的利器,2.0的发布已经有一段时间了,asp.net core是新一代微软的BS开发框架,同时兼容.net core和.net framework,它的出现, ...

  9. ASP.NET Core 2.0 : 七.一张图看透启动背后的秘密

    ASP.NET Core 2.0 : 七.一张图看透启动背后的秘密 原文: ASP.NET Core 2.0 : 七.一张图看透启动背后的秘密 为什么我们可以在Startup这个 "孤零零的 ...

最新文章

  1. 两个for还是一个for?
  2. 【项目管理】项目问题诊断
  3. [LeetCode] Valid Anagram - 字符串排序比较系列
  4. 程序员必须尽早作打算
  5. python单行注释的标记符_【转】Pyhton 单行、多行注释符号使用方法及规范
  6. 运行javac编译报错:仅当显式请求注释处理时才接受类名称“xxxxxx”
  7. 用sc命令查询系统状态
  8. 【小白冲冲冲!!!】37. ORBSLAM初始化时为什么要同时初始化H矩阵和F矩阵?
  9. SoapUI安装教程,亲测可用
  10. 左程云 Java 笔记--排序
  11. 磁盘被写保护怎么解除
  12. html5拖拽表单设计器,可视化表单设计器拖拽生成表单(原创)
  13. 生物特征识别的种族偏见,肤色偏见,性别偏见
  14. idea 创建springboot项目的资源文件application.yml的图标显示不正常
  15. 【HDOJ】1493 QQpet exploratory park
  16. win7 svchost.exe 占用内存cpu过高
  17. 【阿里云资讯】作战指挥系统碾压美军?!阿里双11破千亿背后的重大机密......
  18. 菜鸟学算法——动态规划(二)
  19. 卡西欧计算机维修,卡西欧tr350死机 通过原因寻找修理办法
  20. ps做出一个框,然后拉图片进去只显示框中得部分

热门文章

  1. react connect
  2. Partitioning Strategies
  3. centos 7 安装openstack kilo in three node
  4. Mysql 常用函数总结
  5. 【C#语言规范】从FxCop归纳出来的一些规范建议
  6. 500w 的引用类型和值类型到底有多大差异?
  7. Dapr云原生应用开发系列7:工作流集成
  8. Nexus:一站式私有仓库管理(NuGet、Maven、npm、Docker)
  9. 使用 Tye 辅助开发 k8s 应用竟如此简单(二)
  10. asp.net core监控—引入Prometheus(二)