07 | 用Autofac增强容器能力:引入面向切面编程(AOP)的能力

如何获取没有命名的服务呢?

// Autofac 容器获取实例的方式是一组 Resolve 方法
var service = this.AutofacContainer.ResolveNamed<IMyService>("service2");
service.ShowCode(); // 获取没有命名的服务,把 namd 去掉即可
var servicenamed = this.AutofacContainer.Resolve<IMyService>();
servicenamed.ShowCode();

启动程序,输出如下:

MyServiceV2.ShowCode:44407631,NameService是否为空:True
MyService.ShowCode:61566768

接下来,讲解属性注入

// 属性注入,只需要在注册方法加上 PropertiesAutowired 即可
builder.RegisterType<MyNameService>();
builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired();

从服务里面获取它并且 ShowCode

var servicenamed = this.AutofacContainer.Resolve<IMyService>();
servicenamed.ShowCode();

启动程序,输出如下:

MyServiceV2.ShowCode:11318800,NameService是否为空:False

不为空,注册成功

接下来,演示 AOP 场景,它指的是在不期望改变原有类的情况下,在方法执行时嵌入一些逻辑,使得可以在方法执行的切面上任意插入逻辑

namespace DependencyInjectionAutofacDemo.Services
{
/// <summary>
/// IInterceptor 是 Autofac 的面向切面的最重要的一个接口,它可以把逻辑注入到方法的切面里面去
/// </summary>
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<MyInterceptor>();
// 注册 MyServiceV2,并且允许它属性注册 (PropertiesAutowired)
// 开启拦截器需要使用 InterceptedBy 方法,并且注册类型 MyInterceptor
// 最后还要执行一个开关 EnableInterfaceInterceptors 允许接口拦截器
builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors();

拦截器分两种类型,一种是接口拦截器,一种是类拦截器

常用的是接口拦截器,当服务类型是接口的时候,就需要使用这种方式

如果没有基于接口设计类,而是实现类的时候,就需要用类拦截器

类拦截器需要把方法设计为虚方法,这样子允许类重载的情况下,才可以拦截到具体的方法

启动程序,输出如下:

Intercept before,Method:ShowCode
MyServiceV2.ShowCode:31780825,NameService是否为空:True
Intercept after,Method:ShowCode

接下来看一下子容器的用法

// Autofac 具备给子容器进行命名的特性,可以把以服务注入到子容器中,并且是特定命名的子容器,这就意味着在其他的子容器是获取不到这个对象的
builder.RegisterType<MyNameService>().InstancePerMatchingLifetimeScope("myscope");

创建一个 myscope 的子容器

using (var myscope = AutofacContainer.BeginLifetimeScope("myscope"))
{
var service0 = myscope.Resolve<MyNameService>();
using (var scope = myscope.BeginLifetimeScope())
{
var service1 = scope.Resolve<MyNameService>();
var service2 = scope.Resolve<MyNameService>();
Console.WriteLine($"service1=service2:{service1 == service2}");
Console.WriteLine($"service1=service0:{service1 == service0}");
}
}

启动程序,输出如下:

service1=service2:True
service1=service0:True

这意味着在 myscope 子容器下面,不管再创建任何子容器的生命周期,得到的都是同一个对象

这样子的好处是当不期望这个对象在根容器创建时,又希望它在某一定的范围内时单例模式的情况下,可以使用这种方式

GitHub源码链接:

https://github.com/MingsonZheng/DotNetCoreDevelopmentActualCombat/tree/main/DependencyInjectionAutofacDemo

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。

如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。

.NET Core开发实战(第7课:用Autofac增强容器能力)--学习笔记(下)的更多相关文章

  1. 《Flask Web开发实战:入门、进阶与原理解析》 学习笔记

    一个视图函数可以绑定多个 URL 为了让互联网上的人都可以访问,需要安装程序的服务器有公网ip 如果过度使用扩展,在不需要 的地方引人,那么相应也会导致代码不容易维护 ,应该尽量从实际需求出发,只在需 ...

  2. 2月送书福利:ASP.NET Core开发实战

    大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...

  3. [ASP.NET Core开发实战]开篇词

    前言 本系列课程文章主要是学习官方文档,再输出自己学习心得,希望对你有所帮助. 课程大纲 本系列课程主要分为三个部分:基础篇.实战篇和部署篇. 希望通过本系列课程,能让大家初步掌握使用ASP.NET ...

  4. .NET Core开发实战(第11课:文件配置提供程序)--学习笔记

    11 | 文件配置提供程序:自由选择配置的格式 文件配置提供程序 Microsoft.Extensions.Configuration.Ini Microsoft.Extensions.Configu ...

  5. 2、SpringBoot接口Http协议开发实战8节课(1-6)

    1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...

  6. [ASP.NET Core开发实战]基础篇03 中间件

    什么是中间件 中间件是一种装配到应用管道,以处理请求和响应的组件.每个中间件: 选择是否将请求传递到管道中的下一个中间件. 可在管道中的下一个中间件前后执行. ASP.NET Core请求管道包含一系 ...

  7. [ASP.NET Core开发实战]基础篇02 依赖注入

    ASP.NET Core的底层机制之一是依赖注入(DI)设计模式,因此要好好掌握依赖注入的用法. 什么是依赖注入 我们看一下下面的例子: public class MyDependency { pub ...

  8. [ASP.NET Core开发实战]基础篇01 Startup

    Startup,顾名思义,就是启动类,用于配置ASP.NET Core应用的服务和请求管道. Startup有两个主要作用: 通过ConfigureServices方法配置应用的服务.服务是一个提供应 ...

  9. 2、SpringBoot接口Http协议开发实战8节课(7-8)

    7.SpringBoot2.x文件上传实战 简介:讲解HTML页面文件上传和后端处理实战 1.讲解springboot文件上传 MultipartFile file,源自SpringMVC 1)静态页 ...

  10. [ASP.NET Core开发实战]基础篇06 配置

    配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙.上传格式与大小限制等等. ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息. ASP.NET Core项 ...

随机推荐

  1. springboot2.0+dubbo-spring-boot-starter聚合项目打可执行的jar包

    springboot2.0+dubbo聚合项目打可执行的jar包 springboot2.0+dubbo-spring-boot-starter项目服务方打包和以前老版本的dubbo打包方式不一样,不 ...

  2. Servlet系列:(HttpServletRequest、HttpServletResponse、ServletContext、ServletConfig)详解

    HttpServletRequest HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service() ...

  3. mysql 查看数据库及表大小以及数据库扩容评估

    本文为博主原创,未经允许不得转载: 1.查看数据库数据存储的位置: show global variables like "%datadir%"; 2.查看数据库大小 2.1 in ...

  4. Angular系列教程之路由守卫

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  5. 【MLA】内存泄漏检查

    项目地址:skullboyer/MLA (github.com) 介绍 MLA 即 Memory Leak Analyzer,是一个排查内存泄漏的分析器 实现机制是在malloc时记录分配位置信息,在 ...

  6. RabbitMQ .net core 客户端 EasyNetQ 的使用

    依赖注入 var connectionConfiguration = new ConnectionConfiguration { Hosts = new List<HostConfigurati ...

  7. [转帖]oracle ZHS16GBK的数据库导入到字符集为AL32UTF8的数据库(转载+自己经验总结)

    字符集子集向其超集转换是可行的,如此例 ZHS16GBK转换为AL32UTF8. 导出使用的字符集将会记录在导出文件中,当文件导入时,将会检查导出时使用的字符集设置,如果这个字符集不同于导入客户端的N ...

  8. [转帖]/dev/random 和 /dev/urandom的一点备忘

    https://www.cnblogs.com/ohmygirl/p/random.html 1.  基本介绍 /dev/random和/dev/urandom是Linux系统中提供的随机伪设备,这两 ...

  9. [转帖]Oracle数据库下PreparedStatementCache内存问题解决方案

    https://github.com/alibaba/druid/wiki/Oracle%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8BPreparedStatementCac ...

  10. [转帖]tiup cluster scale-in

    https://docs.pingcap.com/zh/tidb/stable/tiup-component-cluster-scale-in tiup cluster scale-in 命令用于集群 ...