.Net Core 依赖注入

  • 为什么要使用依赖注入框架
  • .Net Core DI
    • 核心类
    • 三种生命周期
    • 服务注册
      • 单例注册
      • 作用域注册
      • 瞬时注册
      • 直接注入实例
      • 工厂模式注册
      • 注册不同实例
      • 尝试注册
      • 移除和替换注册
      • 注册泛型模板
    • 使用依赖注入注意点
    • 实现 IDisposable 接口类型的释放
  • Autofac
    • 基于名称的注入
    • 属性注入
    • 子容器
    • 基于动态代理的 AOP

为什么要使用依赖注入框架

  • 借助依赖注入框架,将对象的创建交由容器管理,确保代码的可维护性和可扩展性。
  • .NET Core 的整个架构中,依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的。

.Net Core DI

.Net Core实现依赖注入两个包:

Microsoft.Extensions.DependencyInjection.Abstractions
Microsoft.Extensions.DependencyInjection

Microsoft.Extensions.DependencyInjection.Abstractions 为抽象包,Microsoft.Extensions.DependencyInjection 为具体实现包

核心类

IServiceCollection
ServiceDescriptor
IServiceProvider
IServiceScope

IServiceCollection 负责注册,作为Startup类中ConfigureServices方法的参数,使用其对对象进行注册。
ServiceDescriptor 负责注入服务元素的描述
IServiceProvider 负责提供实例
IServiceScope 负责实例的生命周期

三种生命周期

  • 瞬时 Transient:每次请求,都获取一个新的实例;即使同一个请求获取多次也会是不同的实例。
  • 作用域 Scoped: 每次请求,都获取一个新的实例;同一个请求获取多次会得到相同的实例,即一个http请求内唯一。
  • 单例 Singleton:每次都获取同一个实例。

服务注册

单例注册

 services.AddSingleton<IMyService, MyService>();

作用域注册

 services.AddScoped<IMyService, MyService>();

瞬时注册

 services.AddTransient<IMyService, MyService>();

直接注入实例

 services.AddScoped<IMyService>(new MyService());

工厂模式注册

 services.AddScoped<IMyService>(serviceProvider =>{return new MyService();});

注册不同实例

 services.AddScoped<IMyService>(new MyService());services.AddScoped<IMyService>(new MyService2());

MyService和MyService2均实现了IMyService接口,并且进行了注册;使用的时候,默认是用的最后注册的(MyService2);如果要使用MyService, 需要遍历,根据实际类型来判断。

[HttpGet]
public async Tash GetServiceList([FromServices] IEnumerable<IMyService> services)
{foreach (var service in services){if (service is MyService) //  if (service.GetType() == typeof(MyService)){// do sth}      }
}

尝试注册

 services.TryAddScoped<IMyService>(new MyService());services.TryAddEnumerable(ServiceDescriptor.Scoped<IMyService, MyService>());

尝试注册会先判断实例是否已经注册,若注册了则不再进行注册;尝试注册可以有效的避免服务重复注册。

移除和替换注册

 services.AddScoped<IMyService, MyService>();services.Replace(ServiceDescriptor.Singleton<IMyService, MyService2>());services.RemoveAll<IMyService>();

替换注册可以替换原有实例注册MyService为MyService2,RemoveAll则是移除所以实现了IMyService的注册实例。

注册泛型模板

 services.AddScoped(typeof(IGenericService<>), typeof(GenericService<>));

使用依赖注入注意点

  • 避免通过静态属性的方式访问容器对象
  • 避免在服务内部使用 GetService 方式来获取实例
  • 避免使用静态属性存储单例,应该使用容器管理单例对象
  • 避免在服务中实例化依赖对象,应该使用依赖注入来获得依赖对象
  • 避免向单例的类型注入范围的类型

实现 IDisposable 接口类型的释放

  • DI 只负责释放由其创建的对象实例
  • DI 在容器或子容器释放时,释放由其创建的对象实例
  • 避免手动创建实现了 IDisposable 对象,应该使用容器来管理其生命周期

Autofac

Autofac的功能比.Net Core 的原生依赖注入更丰富,具体表现在:

  • 基于名称的注入
  • 属性注入
  • 子容器
  • 基于动态代理的 AOP

基于名称的注入

public void ConfigureContainer(ContainerBuilder builder)
{builder.RegisterType<MyService>().Named<IMyService>("s1");builder.RegisterType<MyService2>().Named<IMyService>("s1");
}

从IoC容器中使用ResolveNamed获取:

var s1 = container.ResolveNamed<IMyService>("s1");
var s2 = container.ResolveNamed<IMyService>("s2");

属性注入

使用PropertiesAutowired方法支持属性注入:

builder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired();

子容器

builder.RegisterType<MyService>().InstancePerMatchingLifetimeScope("myscope");

使用

var autofacContainer = app.ApplicationServices.GetAutofacRoot();
using (var myscope = autofacContainer.BeginLifetimeScope("myscope"))
{var service1 = myscope.Resolve<MyService>();using (var scope = myscope.BeginLifetimeScope()){var service2 = scope.Resolve<MyService>();Console.WriteLine($"service1=service2:{service1 == service2}");}
}

基于动态代理的 AOP

需要引用包:Autofac.Extras.DynamicProxy
先实现一个拦截器继承 IInterceptor

    public class MyInterceptor : IInterceptor{public void Intercept(IInvocation invocation){Console.WriteLine($"Intercept before,Method:{invocation.Method.Name}");invocation.Proceed();Console.WriteLine($"Intercept after,Method:{invocation.Method.Name}");}}

注册

builder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors();

这里实现了基于接口的拦截,也可以实现基于类的拦截;基于类的拦截时,方法需要定义为虚方法。

.Net Core 依赖注入相关推荐

  1. everythingtoolbar.dll”或它的一个依赖项。_ASP.NET Core依赖注入最佳实践、提示和技巧...

    译者前言 本文译自ABP框架的开发博客<ASP.NET Core Dependency Injection Best Practices, Tips & Tricks>一文(原作者 ...

  2. 探索 .NET Core 依赖注入的 IServiceProvider

    在上一篇文章中,我们学习了Microsoft.Extensions.DependencyInjection中的IServiceCollection,包括服务注册转换为ServiceDescriptor ...

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

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

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

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

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

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

  6. .net core依赖注入

    .net core依赖注入小结 #依赖注入介绍 .net core 中依赖注入是必不可少的一项必学内容,官方介绍为:依赖注入是一种软件设计模式,指一个或多个依赖(或服务)被注入,或通过引用传递,传入一 ...

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

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

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

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

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

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

最新文章

  1. 用模板实现单例模式(线程安全)、模板方式实现动态创建对象
  2. 开源 免费 java CMS - FreeCMS1.5 标签 guestbookPage
  3. 什么是 PureMVC 框架(提供下载)
  4. python 搜索二维矩阵
  5. 我的数据分析全系列教程,记录着那些大学奋斗的时光
  6. java9 opens与exports的区别
  7. 如何删除打印队列中的任务
  8. 微信收款播报器提示服务器断开,微信收款语音提醒开启后收不到语音提醒怎么办? 专家详解...
  9. 肿瘤全外显子--记录
  10. 鸿蒙os2021升级日程,消息称华为EMUI 11.1三月上线:更... - @是Ustinian鸭 的微博精选 - 微博国际站...
  11. 抖音:对比去年6月蓝V账号数量增长44.6倍 投稿量增长211倍
  12. 使用matplotlib绘制3D图像时插入图片
  13. 【三维人脸识别】matlab读取.wrl三维图像文件
  14. 生日快乐的代码_贺渝同学生日快乐!
  15. 初等数论——欧几里得算法
  16. python将base64格式数据转换为图片
  17. 欧尼酱讲JVM(13)——本地方法栈
  18. JAVA毕设项目新型药物临床信息管理系统(java+VUE+Mybatis+Maven+Mysql)
  19. 用LaTeX制作幻灯片(slide)
  20. 审计所需的计算机知识,2018注册会计师《审计》知识点:对信息技术的考虑

热门文章

  1. Windows 将”管理员取得所有权“加入右键菜单
  2. 4020. 【雅礼联考DAY02】Revolution
  3. C++实现超分辨率 IDN
  4. 华为服务器pe启动不了系统还原,华为服务器bios设置u盘启动
  5. 删除链表中重复的结点(穿针引线法)——剑指Offer
  6. php oci已经打开但是没有启用,php.ini明明开启了oci但是仍旧提示Call to undefined function o...
  7. elasticsearch和head 配置x-pack访问登录控制
  8. sqlserver修改decimal类型的长度
  9. 比价寄快递v1.0.24
  10. python的变量需要声明赋值才能使用_Python变量的定义和使用