问题

如何使用 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. Redis持久化实践及灾难恢复模拟
  2. 【MM模块】Blocking Reasons 冻结原因
  3. 由于权限引起的Tomcat中项目某些页面访问不了
  4. [转]常用数字处理算法的Verilog实现
  5. webapp 中为span元素赋值
  6. 【Pytorch 】nn.functional.unfold()==>卷积操作中的提取kernel filter对应的滑动窗口
  7. 生命的力量--HAND OF HOPE
  8. 是什么造成了数据库的卡顿
  9. 仿百度,豆瓣读书文库阅读器
  10. GreenDao 工具类 --- 使用 Json 快速生成 Bean、表及其结构,炒鸡快!
  11. 大数据平台解决方案(PPT)
  12. (翻译)折叠菜单(Accordion Menu)
  13. 数学建模【系统评价决策模型(概论、案例分析-汽车选购、层次分析法、案例分析-职员晋升、动态加权综合评价法、案例分析-大气污染问题)】
  14. JAVA支付宝app端支付以及提现
  15. 荐书丨《好奇心的秘密》:一个针尖上可以站多少跳舞的小天使?
  16. HTML5: select标签
  17. java初学者必读-经验总结--经典!
  18. html导出excel合并单元格,JS导出EXCEL,动态设置单元格格式,合并单元格(横向或纵向)等操作...
  19. java 读取ascii码_JAVA ASCII码 读入字符串测试
  20. Android Kotlin-协程

热门文章

  1. PHP单例模式(精讲)
  2. Linux运维实战之DNS的高级配置(转发器、视图等)
  3. OpenStack开启亚洲之旅
  4. 全国计算机技术与软件专业技术资格(水平)考试基础知识
  5. 十个现象,识别程序员的“水份”
  6. C#多线程开发-任务并行库
  7. .NET 6 新特性 System.Text.Json 中的 Writeable DOM
  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定...
  9. asp.net core中使用cookie身份验证
  10. .NET Core加解密实战系列之——消息摘要与数字签名算法