聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

前言

前文排版比较糟糕,这次我们使用vscode来写本文,,各位看客请见谅。

上文描述了 ServiceDescriptor 的三种构造形式,这决定了我们之后获取原始对象要考虑的场景,至于如何获取暂且不表,在实现细节部分我们会详细阐述。

本文将阐述 _ProxyGenerator_的一些细节,以便各位看客更好理解 Castle 在各种场景下 如何选择合适的接口去构建代理对象(以下全称为代理对象或者 proxy

代理对象的构建方法

大体分成两种方式 一种是具体类 一种是根据接口生成代理对象,每种内部都会区分是否传入原始对象 看方法签名 WithTarget 即需要传入 原始对象,WithoutTarget 即不需要传入原始对象,

  • ProxyGenerator.CreateClassProxy
  • ProxyGenerator.CreateInterfaceProxy

示例说明

接下来我们以几种示例来介绍各个接口的使用情况

  • 假设已知 一个接口 ISampleService 和一个实现类 SampleService
public class SampleService : ISampleService
{
public virtual Task ShowAsync()
{
return Task.CompletedTask;
}
} public interface ISampleService
{
Task ShowAsync();
} public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
Console.WriteLine("Interceptor ended...");
}
}

具体类

我们想对 SampleService 进行代理生成 因为 SampleService 具有无参构造,所以我们可以这样

var generator=new ProxyGenerator();
var proxy = generator.CreateClassProxy(typeof(SampleService), new Interceptor());

假设 SampleService 有参数构造函数

public class SampleService : ISampleService
{
private readonly ILogger<SampleService> _logger;
public SampleService(ILogger<SampleService> logger)
{
_logger=logger;
}
public Task ShowAsync()
{
return Task.CompletedTask;
}
}
```,那么我们就可以这样
``` csharp
var generator=new ProxyGenerator();
var sampleSvc=sp.GetRequiredService<SampleService>();
var proxy = generator.CreateClassProxyWithTarget(typeof(SampleService),sampleSvc, new Interceptor());

细心的朋友可能发现这时候我们引入了一个变量 而我们并未定义,

这时候我们添加如下代码:

    var services=new ServiceCollection();
services.AddLogging();//此处添加日志服务 伪代码 以便获取ILogger<SampleService>
services.AddSingleton<ProxyGenerator>(sp=>new ProxyGenerator());
servies.TryAddTransient<SampleService>();
var sp=services.BuildServiceProvider();

接口

使用以上代码示例,假设我们要对 ISampleService 进行代理生成,那么我们就可以这样

services.TryAddTransient<ISampleService, SampleService>();//注入阶段添加以下代码以便获取ISampleService
var generator=sp.GetRequiredService<ProxyGenerator>();
var proxy=generator.CreateInterfaceProxyWithoutTarget(typeof(ISampleService),new Interceptor());//因为没有传入 原始对象,所以依然要求我们是一个无参构造的实现 TODO:可自行验证

看下原始定义

假设我们获取了 _ISampleService_的实例

var  sampleSvc=sp.GetRequiredService<ISampleService>();
var proxy = generator.CreateInterfaceProxyWithTarget(typeof(ISampleService),sampleSvc, new Interceptor());

可以发现 接口代理 和具体类代理 基本相似

细心的可以注意到 SampleService.ShowAsync 很反常的 加了个关键字 virtual,想知道为什么,这里我们借用 Castle 的文档 https://github.com/castleproject/Core/blob/master/docs/dynamicproxy-introduction.md 有兴趣的朋友可以自行查询

总结

说到这里,我们已经基本了解了 castle构建动态代理的基本方法,接下来我们来总结一下代理对象的构建方法。 先区分目标是类还是接口,类的代理方法要求关键字virtual,无参构造可以使用 CreateClassProxy,有参数可以先获取到原始对象,传入 CreateClassProxyWithTarget;

接口同,无原始对象 CreateInterfaceProxyWithoutTarget ,有原始对象 CreateInterfaceProxyWithTarget

代码太多有点枯燥,本文先到这边。

聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)的更多相关文章

  1. DotNetCore跨平台~一起聊聊Microsoft.Extensions.DependencyInjection

    写这篇文章的心情:激动 Microsoft.Extensions.DependencyInjection在github上同样是开源的,它在dotnetcore里被广泛的使用,比起之前的autofac, ...

  2. 解析 Microsoft.Extensions.DependencyInjection 2.x 版本实现

    项目使用了 Microsoft.Extensions.DependencyInjection 2.x 版本,遇到第2次请求时非常高的内存占用情况,于是作了调查,本文对 3.0 版本仍然适用. 先说结论 ...

  3. 使用诊断工具观察 Microsoft.Extensions.DependencyInjection 2.x 版本的内存占用

    目录 准备工作 大量接口与实现类的生成 elasticsearch+kibana+apm asp.net core 应用 请求与快照 Kibana 上的请求记录 请求耗时的分析 请求内存的分析 第2次 ...

  4. Microsoft.Extensions.DependencyInjection 之三:展开测试

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  5. Microsoft.Extensions.DependencyInjection 之三:反射可以一战(附源代码)

    目录 前文回顾 IServiceCallSite CallSiteFactory ServiceProviderEngine CompiledServiceProviderEngine Dynamic ...

  6. Microsoft.Extensions.DependencyInjection 之二:使用诊断工具观察内存占用

    目录 准备工作 大量接口与实现类的生成 elasticsearch+kibana+apm asp.net core 应用 请求与快照 Kibana 上的请求记录 请求耗时的分析 请求内存的分析 第2次 ...

  7. Microsoft.Extensions.DependencyInjection 之一:解析实现

    [TOC] 前言 项目使用了 Microsoft.Extensions.DependencyInjection 2.x 版本,遇到第2次请求时非常高的内存占用情况,于是作了调查,本文对 3.0 版本仍 ...

  8. 使用 Microsoft.Extensions.DependencyInjection 进行依赖注入

    没有 Autofac DryIoc Grace LightInject Lamar Stashbox Unity Ninject 的日子,才是好日子~~~~~~~~~~ Using .NET Core ...

  9. MvvmLight + Microsoft.Extensions.DependencyInjection + WpfApp(.NetCore3.1)

    git clone MvvmLight失败,破网络, 就没有直接修改源码的方式来使用了 Nuget安装MvvmLightLibsStd10 使用GalaSoft.MvvmLight.Command命名 ...

  10. Microsoft.Extensions.DependencyInjection中的Transient依赖注入关系,使用不当会造成内存泄漏

    Microsoft.Extensions.DependencyInjection中(下面简称DI)的Transient依赖注入关系,表示每次DI获取一个全新的注入对象.但是使用Transient依赖注 ...

随机推荐

  1. Vue2系列(lqz)——Vue生命期钩子、组件

    文章目录 Vue声明期钩子 组件 1 fetch和axios 1.1 fetche使用 1.2 axios的使用 2 计算属性 2.1 通过计算属性实现名字首字母大写 2.2 通过计算属性重写过滤案例 ...

  2. VS Code SSH

    VS Code SSH 连接需要下载 VS Code Server,这是因为 VS Code Server 是在远程服务器上运行的,而不是在本地计算机上运行的.每次连接到不同的远程服务器时,都需要下载 ...

  3. idea修改默认maven配置

    idea修改默认maven配置 方法一 (不推荐) 打开project.default.xml文件,在其中加入如下几行配置. 代码如下 保存修改之后新建一个maven项目查看效果 方法二 新增Proj ...

  4. 基于SpringBoot+Netty实现即时通讯(IM)功能

    简单记录一下实现的整体框架,具体细节在实际生产中再细化就可以了. 第一步 引入netty依赖 SpringBoot的其他必要的依赖像Mybatis.Lombok这些都是老生常谈了 就不在这里放了 &l ...

  5. mapState、mapGetters、mapMutations、mapActions学习

    https://next.vuex.vuejs.org/zh/guide/state.html#mapstate-%E8%BE%85%E5%8A%A9%E5%87%BD%E6%95%B0 https: ...

  6. Python 批量合并图片到word文档

    这段代码是一个用Python编写的功能,它将指定文件夹中的所有图片插入到Word文档中并保存.以下是代码的主要步骤和功能: 导入必要的库 Python中的docx库用于操作Word文档,glob库用于 ...

  7. 「译文」Google SRE 二十年的经验教训

    ️URL: https://sre.google/resources/practices-and-processes/twenty-years-of-sre-lessons-learned/ ✍️Au ...

  8. Python 既是解释型语言,也是编译型语言

    哈喽大家好,我是咸鱼 不知道有没有小伙伴跟我一样,刚开始学习 Python 的时候都听说过 Python 是一种解释型语言,因为它在运行的时候会逐行解释并执行,而 C++ 这种是编译型语言 不过我今天 ...

  9. Java中的对象到底是什么

    对象是现实世界中的一切物体(实体,或能够定义的东西) Smalltalk是第一个成功的面向对象的语言 在编程世界中,对象通过类来实例化:同一个类型的对象可以接受相同的消息 状态+行为+标识=对象 每个 ...

  10. DFS深搜小谈

    前几天有人跟我说,啊,说dfs一搜搜着搜着就把自己搜蒙了,说一写dfs就要dfs(int a,int b,int c),括号里面放一堆东西.啊今天我要澄清一下,dfs其实没有你想的那么复杂. dfs这 ...