前言

今天的第三篇,感觉没啥人看呀,难道没有兄弟跟我有同样的整合需求吗???手动





本文会简短一些,介绍下 CastleCore 作为代理库的一些缺点甚至是硬伤

异步支持

先上代码

/// <summary>
/// 异常捕获、日志记录和耗时监控 拦截器 2024-1-12 21:28:22
/// </summary>
public class CatchLoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
//TODO:类注释所写的逻辑
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
Console.WriteLine("Interceptor ended...");
}
}

如上是一个最简单的 CastleCore 拦截器示例,为了该拦截器能在使用的时候可以直接标注在方法上使用,为我们做如下改动:

/// <summary>
/// 异常捕获、日志记录和耗时监控 拦截器 2024-1-12 21:28:22
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CatchLoggingInterceptor : Attribute, IInterceptor
{
public void Intercept(IInvocation invocation)
{
//TODO:类注释所写的逻辑
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
Console.WriteLine("Interceptor ended...");
}
} public class SampleService : ISampleService
{
[CatchLoggingInterceptor]
public virtual Task<string> ShowAsync()
{
Console.WriteLine(nameof(ShowAsync));
return Task.FromResult(nameof(ShowAsync));
}
} public interface ISampleService
{
[CatchLoggingInterceptor]
Task<string> ShowAsync();
}

使用代码如下

 public static async Task Main(string[] args)
{
var services = new ServiceCollection();
services.AddLogging();//此处添加日志服务 伪代码 以便获取ILogger<SampleService>
services.TryAddSingleton(sp => new ProxyGenerator());
services.TryAddTransient<SampleService>();
services.TryAddTransient<ISampleService, SampleService>();
var sp = services.BuildServiceProvider(); var generator = sp.GetRequiredService<ProxyGenerator>();
var instance = sp.GetRequiredService<SampleService>();
var proxy = generator.CreateClassProxyWithTarget(typeof(SampleService), instance, new CatchLoggingInterceptor()) as SampleService;
var name = await proxy.ShowAsync();
}

输入如图所示:

name也可以正常取到值,没问题

看下拦截器的定义 ,我们全部是同步方法,要知道dotnetcore下是推荐所有方法都是异步的, 我们对拦截器做如下改造:

public void Intercept(IInvocation invocation)
{
invocation.ReturnValue = IntercetpAsync(invocation);
} private async Task IntercetpAsync(IInvocation invocation)
{
//TODO:类注释所写的逻辑
await Console.Out.WriteLineAsync("Interceptor starting...");
Console.WriteLine("Interceptor starting...");
invocation.Proceed();
await Console.Out.WriteLineAsync("Interceptor ended...");
}

如上,拦截器里面使用Console.Out执行了异步方法的拦截,再执行



此时引出 Castle代理的致命的问题:拦截方法默认无法异步

针对此问题,官方也已显式标明,并提供了具体的解决办法

https://github.com/castleproject/Core/blob/master/docs/dynamicproxy-async-interception.md

这里我推荐 https://www.nuget.org/packages/stakx.DynamicProxy.AsyncInterceptor 的处理办法

其他缺点

  • 拦截器内如何可以使用ioc的生态获取已经有的各项功能服务
  • 某些场景下拦截器是需要传入常量 比方说,操作日志拦截,方法1 可能需要 Name="方法1",而方法二额需要 Name="方法2"

综上

上面三个缺点都是CastleCore 的硬伤,我们都要克服,后文会陆续解决这些问题,请各位看官拭目以待。写文很累,各位能不能dian点个star呢?您的鼓励会让我信心倍增,更新更快。

本文示例代码已上传至 https://gitee.com/gainorloss_259/microsoft-castle.git

聊一聊如何整合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. pandas -- DataFrame的级联以及合并操作

    博客地址:https://www.cnblogs.com/zylyehuo/ 开发环境 anaconda 集成环境:集成好了数据分析和机器学习中所需要的全部环境 安装目录不可以有中文和特殊符号 jup ...

  2. Django——后台添加的用户密码错误

    django项目中,当我们创建了user模型类,并生成了超级管理员,之后我们进入到admin后台页面中,添加一个用户,再去login页面登陆时,会提示我们 用户名或密码错误. 这时,我们第一时间会想到 ...

  3. frida动态插桩初探

    前言 近期碰到了分析app的需求,就学习了一下 frida的动态插桩技术.frida是一款轻量级HOOK框架,可用于多平台上,例如android.windows.ios等.frida分为两部分,服务端 ...

  4. 再学Blazor——扩展方法

    上篇提到 Blazor 组件的高级写法,是采用扩展方法对 HTML 元素和组件进行扩展,以便于书写组件结构和代码阅读.本篇主要介绍扩展方法实现的思路. 什么是扩展方法 要扩展哪个类 扩展方法的实现 1 ...

  5. Kubernetes文档支持的版本

    简介 https://kubernetes.io/zh-cn/docs/ 官方中文网站一共是可以阅读5个k8s版本的文档.这5个版本包括k8s最新版和最近的4个版本.例如当前最新版是1.28,那么文档 ...

  6. HTTP 和 RPC 的区别

    一句话概括 RPC代表:Feign.Dubbo RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便. HTTP 代表:RestTemplate.HttpClient HTTP 主 ...

  7. Prometheus+Grafana实现服务性能监控:windows主机监控、Spring Boot监控、Spring Cloud Alibaba Seata监控

    1.Prometheus介绍 Prometheus使用Go语言开发,中文名称叫:普罗 米修斯.Prometheus是一个开源系统最初在SoundCloud构建的监控和警报工具包.自 2012 年成立以 ...

  8. Vue 2.x源码学习:数据响应式改造

    内容乃本人学习Vue2源码的一点笔记,若有错误还望指正. 源码版本: vue: 2.6 vue-loader: 13.x vue-template-compiler: 2.6 相关学习笔记: rend ...

  9. markdown语法基本使用

    markdown 语法基本使用 目录 markdown 语法基本使用 各级标题 字体 引用 分隔线 图片 列表 表格 代码 超链接 各级标题 井号加上空格,几级标题用几个井号加上空格 字体 单星号引起 ...

  10. 🔥🔥Java开发者的Python快速进修指南:迭代器(Iterator)与生成器

    这一篇内容可能相对较少,但是迭代器在Java中是有用处的.因此,我想介绍一下Python中迭代器的使用方法.除了写法简单之外,Python的迭代器还有一个最大的不同之处,就是无法直接判断是否还有下一个 ...