1. 前言

关于IoC模式(控制反转)和DI技术(依赖注入),我们已经见过很多的探讨,这里就不再赘述了。比如说必看的Martin Fowler《IoC 容器和 Dependency Injection 模式》,相关资料链接都附于文章末尾。其中我非常赞同Artech的说法"控制更多地体现为一种流程的控制",而依赖注入技术让我们的应用程序实现了松散耦合。

ASP.NET Core本身已经集成了一个轻量级的IOC容器,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可,常见方法如下

services.AddTransient<IApplicationService,ApplicationService>services.AddScoped<IApplicationService,ApplicationService>services.AddSingleton<IApplicationService,ApplicationService>

对于上述的三种DI注入方式,官方也给出了详细的解释,我来简单翻译一下

  • Transient
    Transient 服务在每次请求时被创建,它最好被用于轻量级无状态服务(如我们的Repository和ApplicationService服务)

  • Scoped
    Scoped 服务在每次请求时被创建,生命周期横贯整次请求

  • Singleton
    顾名思义,Singleton(单例) 服务在第一次请求时被创建(或者当我们在ConfigureServices中指定创建某一实例并运行方法),其后的每次请求将沿用已创建服务。如果开发者的应用需要单例服务情景,请设计成允许服务容器来对服务生命周期进行操作,而不是手动实现单例设计模式然后由开发者在自定义类中进行操作。

在这之后,我们便可以将服务通过构造函数注入或者是属性注入的方式注入到Controller,View(通过使用@inject),甚至是Filter中(以前使用Unity将依赖注入到Filter真是一种痛苦)。话不多说,先来体验一把

Tips:Startup.cs是什么,详见ASP.NET Core 介绍和项目解读

2. ASP.NET Core 中的DI方式

大多项目举例依赖注入的生命周期演示时,都会采取可变Guid来作为返回显示,此次示例也会这样处理。我们先定义一个IGuidAppService接口,里面定义基接口和三种注入模式的接口

    public interface IGuidAppService{                 Guid GuidItem();}   

    public interface IGuidTransientAppService : IGuidAppService{}    

    public interface IGuidScopedAppService : IGuidAppService{}   

     public interface IGuidSingletonAppService : IGuidAppService{}

同样的,在GuidAppService中定义其实现类。这里为了直观显示每次请求的返回值,采取如下代码

    public class GuidAppServiceBase : IGuidAppService    {             private readonly Guid _item;        public GuidAppServiceBase(){_item = Guid.NewGuid();}     

        public Guid GuidItem(){                    return _item;}}               public class GuidTransientAppService : GuidAppServiceBase, IGuidTransientAppService    {}               public class GuidScopedAppService : GuidAppServiceBase, IGuidScopedAppService    {}               public class GuidSingletonAppService : GuidAppServiceBase, IGuidSingletonAppService    {}

最后是Controller和View视图的代码

    # Controllerpublic class HomeController : Controller{            private readonly IGuidTransientAppService _guidTransientAppService; //#构造函数注入//private  IGuidTransientAppService _guidTransientAppService { get; } #属性注入private readonly IGuidScopedAppService _guidScopedAppService;             private readonly IGuidSingletonAppService _guidSingletonAppService;        public HomeController(IGuidTransientAppService guidTransientAppService,            IGuidScopedAppService guidScopedAppService, IGuidSingletonAppService guidSingletonAppService)        {_guidTransientAppService = guidTransientAppService;_guidScopedAppService = guidScopedAppService;_guidSingletonAppService = guidSingletonAppService;}             public IActionResult Index()           {ViewBag.TransientItem = _guidTransientAppService.GuidItem();ViewBag.ScopedItem = _guidScopedAppService.GuidItem();ViewBag.SingletonItem = _guidSingletonAppService.GuidItem();                    return View();}}    # Index View <div class="row"><div ><h2>GuidItem Shows</h2><h3>TransientItem: @ViewBag.TransientItem</h3><h3>ScopedItem: @ViewBag.ScopedItem</h3><h3>SingletonItem: @ViewBag.SingletonItem</h3></div>
</div>

之后我们打开两个浏览器,分别刷新数次,也只会发现“TransientItem”和“ScopedItem”的数值不断变化,“SingletonItem”栏的数值是不会有任何变化的,这就体现出单例模式的作用了,示例图如下

但是这好像还不够,要知道我们的Scoped的解读是“生命周期横贯整次请求”,但是现在演示起来和Transient好像没有什么区别(因为两个页面每次浏览器请求仍然是独立的,并不包含于一次中),所以我们采用以下代码来演示下(同一请求源)

# 新建GuidItemPartial.cshtml视图,复制如下代码,使用@inject注入依赖@using DependencyInjection.IApplicationService
@inject IGuidTransientAppService TransientAppService
@inject IGuidScopedAppService GuidScopedAppServic
@inject IGuidSingletonAppService GuidSingletonAppService<div class="row"><div><h2>GuidItem Shows</h2><h3>TransientItem: @TransientAppService.GuidItem()</h3><h3>ScopedItem: @GuidScopedAppServic.GuidItem()</h3><h3>SingletonItem: @GuidSingletonAppService.GuidItem()</h3></div></div># 原先的index视图@{ViewData["Title"] = "Home Page";
}@Html.Partial("GuidItemPartial")@Html.Partial("GuidItemPartial")

依然是 Ctrl+F5 调试运行,可以发现“ScopedItem”在同一请求源中是不会发生变化的,但是“TransientItem”依然不断变化,理论仍然是支持的

3. Autofac实现和自定义实现扩展方法

除了ASP.NETCore自带的IOC容器外,我们还可以使用其他成熟的DI框架,如Autofac,StructureMap等(笔者只用过Unity,Ninject和Castle,Castle也是使用ABP时自带的)。

3.1 安装Autofac

首先在project.json的dependency节点中加入Autofac.Extensions.DependencyInjection引用,目前最新版本是4.0.0-rc3-309

3.2 创建容器并注册依赖

在Startup.cs中创建一个public IContainer ApplicationContainer { get; private set; }对象,并把ConfigureServices返回类型改为IServiceProvider,然后复制以下代码进去,也可以实现相关功能

var builder = new ContainerBuilder();//注意以下写法builder.RegisterType<GuidTransientAppService>().As<IGuidTransientAppService>();
builder.RegisterType<GuidScopedAppService>().As<IGuidScopedAppService>().InstancePerLifetimeScope();
builder.RegisterType<GuidSingletonAppService>().As<IGuidSingletonAppService>().SingleInstance();builder.Populate(services);
this.ApplicationContainer = builder.Build();return new AutofacServiceProvider(this.ApplicationContainer);

值得注意的几点:

  1. 创建Autofac容器时不要忘了将ConfigureServices的返回值修改为IServiceProvider

  2. 对应ASP.NET Core提及的不同的生命周期,Autofac也定义了对应的扩展方法,如InstancePerLifetimeScope等,默认为Transient模式,包括EntityFramwork等Context也是该种模式

  3. Autofac Core不支持从View中注入,但是可以和ASP.NET Core自带IOC容器配合使用

  4. Autofac Core版本和传统的ASP.NET MVC项目版本的区别

4. 参考链接

  • IoC 容器和 Dependency Injection 模式

  • 控制反转—维基百科

  • DependencyInjection-GitHub

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

  • Dependency Injectionf!

原文地址:http://www.cnblogs.com/Wddpct/p/5764511.html


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

ASP.NET Core依赖注入解读amp;使用Autofac替代实现相关推荐

  1. ASP.NET Core依赖注入解读使用Autofac替代实现

    1. 前言 关于IoC模式(控制反转)和DI技术(依赖注入),我们已经见过很多的探讨,这里就不再赘述了.比如说必看的Martin Fowler<IoC 容器和 Dependency Inject ...

  2. ASP.NET Core依赖注入最佳实践,提示技巧

    分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...

  3. ASP.NET Core依赖注入深入讨论

    这篇文章我们来深入探讨ASP.NET Core.MVC Core中的依赖注入,我们将示范几乎所有可能的操作把依赖项注入到组件中. 依赖注入是ASP.NET Core的核心,它能让您应用程序中的组件增强 ...

  4. ASP.NET Core依赖注入容器中的动态服务注册

    介绍 在ASP.NET Core中,每当我们将服务作为依赖项注入时,都必须将此服务注册到ASP.NET Core依赖项注入容器.但是,一个接一个地注册服务不仅繁琐且耗时,而且容易出错.因此,在这里,我 ...

  5. ASP.NET Core 依赖注入-集成 Autofac

    概述 ASP.NET Core 支持依赖关系注入 (DI) 软件设计模式,这是一种在类及其依赖关系之间实现控制反转 (IoC) 的技术. 默认服务容器是 Microsoft.Extensions.De ...

  6. 【ASP.NET Core】ASP.NET Core 依赖注入

    一.什么是依赖注入(Denpendency Injection) 这也是个老身常谈的问题,到底依赖注入是什么? 为什么要用它? 初学者特别容易对控制反转IOC(Iversion of Control) ...

  7. 一文读懂Asp.net core 依赖注入(Dependency injection)

    一.什么是依赖注入 首先在Asp.net core中是支持依赖注入软件设计模式,或者说依赖注入是asp.net core的核心: 依赖注入(DI)和控制反转(IOC)基本是一个意思,因为说起来谁都离不 ...

  8. 全面理解 ASP.NET Core 依赖注入

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

  9. core控制器属性注入的用处_了解ASP.NET Core 依赖注入,看这篇就够了

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

最新文章

  1. 解决非controller使用@Autowired注解注入报错为java.lang.NullPointerException问题
  2. 分布式文件系统研究-fastDFS安装及配置文件说明
  3. Lambda标准格式
  4. python循环删除包含字符串_删除包含完全字符串的文件中的行(Python)
  5. 【数据结构与算法】数据结构与算法基本理论笔记
  6. 1月2日金象山滑雪(图片)
  7. C语言数组指针和指向数组的指针变量—数组名作函数参数.doc
  8. 深度学习在时空数据的应用
  9. python获取期货数据_【python量化】期货ML策略(一)数据获取
  10. windows安装OpenSSL
  11. 【无2022年聚合工艺考试模拟100题模拟考试平台操作
  12. MBA书籍推荐:打造商业思维,看这一本书就够了
  13. oracle 帮助文件,oracle chm帮助文件下载
  14. 奇偶数排序--整数数组的奇偶数分开(小米公司笔试题)
  15. Java趣味编程(二)
  16. Python-爬虫-requests库用语post登录
  17. flex:1 是什么意思
  18. 《百度apollo》规划一
  19. java怎么计算相隔多少天_java计算两个日期之间相差天数和相隔天数详解
  20. 计算方法实验(三):四阶龙格-库塔方法

热门文章

  1. js与Ajax实现浮动留言板(留言写入sqlserver数据库)
  2. 战神II导演 首席程序员访谈(转自www.npc6.com )
  3. Xamarin效果第四篇之CollectionView子项右侧布局
  4. 【分享】154页微软WPF官方手册(含.NETCore和.NET Framwork双版本)
  5. 我从大厂面试中学到的关于 C# 的知识
  6. ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()
  7. 如何提高Debug效率
  8. windows服务autofac注入quartz任务
  9. 接口幂等设计探索实践
  10. 【招聘(深圳)】轻岁 诚聘.NET Core开发