前言

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





本文会简短一些,介绍下 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. Go语言系列——11-数组和切片、12-可变参数函数、13-Maps、14-字符串、15-指针、16-结构体、17-方法、18-接口(一)、19-接口(二)、19-自定义集合类型、20-并发入门

    文章目录 11-数组和切片 数组 数组的声明 数组是值类型 数组的长度 使用 range 迭代数组 多维数组 切片 创建一个切片 切片的修改 切片的长度和容量 使用 make 创建一个切片 追加切片元 ...

  2. LUSH & LUXURIOUS

    明亮色系Punchy & Bright 明亮.有着强烈对比的颜色更引人注目. 这种大胆的色彩组合要谨慎地利用,所以在明亮色系中的调和色一般用中性色. 其中不同的色彩饱和度,表现出不同的氛围和意 ...

  3. 虹科分享 | 一起聊聊Redis企业版数据库与【微服务误解】那些事儿!

    如今,关于微服务依然存在许多误解,企业盲目追求这种炫酷技术并不可取.同时,这种盲目行为对于希望用微服务来有效解决问题的公司很不利.不是说任何特定的技术都是缺乏实际价值的,如微服务.Kubernetes ...

  4. Dynamics CRM中自定义页面实现附件管理包含下载模板、上传、下载、删除

    前言 附件使用的Dynamics CRM平台本身的注释表annotation存储,将附件转换成二进制字节流保存到数据库中,因自带的注释在页面中显示附件不够直观,特做了一个单独的附件管理自定义页面,通过 ...

  5. RLChina2022公开课-博弈搜索算法

    序列决策 序列决策问题一般用马尔可夫决策模型进行描述 搜索算法的优化

  6. Python拆分列中文和 字符

    需求描述:我们日常实际的工作中经常需要把一列数据按中文和 数字或者字母单独拆分出来 导入所需的库: import pandas as pd 定义函数 extract_characters,该函数接受三 ...

  7. 测试技术:开源测试工具 jenkins、Sonar

    http://www.cnblogs.com/itech/archive/2011/11/23/2260009.html Jenkins入门总结 基于 Jenkins 快速搭建持续集成环境 https ...

  8. 记一个 Android 14 适配引发的Android 存储权限问题

    一.bug 背景 项目中有下面这样一段代码,在 Android T 版本运行正常,现在适配到 Android U 上之后,运行时 crash 了.... ... values.put(MediaSto ...

  9. excel对比两个文档,判断范围内的取值是否在另一个列表内存在(vlookup函数的使用)

    背景: sheet1表为原始数据: sheet2表为新的数据副本, 目标是查询sheet2列表中是否存在sheet1表的数据,并且标记出来,且获取sheet2列表的一些数据至sheet1列表中,补充D ...

  10. python列表之部分列表——切片

    目录 切片 全索引 半索引 负数索引 遍历切片 复制列表 切片 全索引 我们平常可能需要使用一个列表中的子列表,也就是部分元素,这个时候我们就需要用到切片这个功能啦 要创建切片,就如同range()函 ...