聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)
2024/1/13 1:02:20
本文主要是介绍聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
聊一聊如何整合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(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解
- 2024-12-20利用Gemini构建处理各种PDF文档的Document AI管道