前言

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





本文会简短一些,介绍下 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. VideoCapture

    from xgoedu import XGOEDU import time #实例化edu XGO_edu = XGOEDU() XGO_edu.lcd_text(50,50,'hello',colo ...

  2. nittest单元测试框架—加载测试用例的3种方法以及测试报告存储管理

    项目结构 测试用例 import unittest class LoginTestCase(unittest.TestCase): def test_login_success(self): self ...

  3. 循序渐进介绍基于CommunityToolkit.Mvvm 和HandyControl的WPF应用端开发(8) -- 使用Converter类实现内容的转义处理

    在我们WPF应用端的时候,和WInform开发或者Vue前端开发一样,有时候也需要对内容进行转义处理,如把一些0,1数值转换为具体含义的文本信息,或者把一些布尔变量转换为是否等,都是常见的转换处理,本 ...

  4. 深入解析css-笔记

    前言 本文章是根据<深入解析CSS>一书所作的学习笔记,书中的知识点基本都概括在这.希望对您有帮助,另外本博客是通过word笔记文档导入,虽然后续对内容和代码相关进行了一些格式处理,但还是 ...

  5. dicker 常用命令(简洁版)

  6. RTMP协议学习——从握手到播放

    从客户端发起播放请求,到rtrmp视频流开始播放,大致经过了握手->建立连接->创建流->播放这几步比较重要的步骤.下面我将结合wireshark的抓包,对其中的每个流程进行分析和学 ...

  7. Netty源码学习4——服务端是处理新连接的&netty的reactor模式

    系列文章目录和关于我 零丶引入 在前面的源码学习中,梳理了服务端的启动,以及NioEventLoop事件循环的工作流程,并了解了Netty处理网络io重要的Channel ,ChannelHandle ...

  8. 玩转开源 | 搭建 Hugo 管理 Markdown 文档

    在工作.学习中,不可避免会要写一些文档:又或者想搭建个简单网站,记录和分享您的生活经验或知识:撰写这些文档中使用 markdown 是一个非常不错的选择,让我们更加聚焦在文档表达的内容上.实际上笔者的 ...

  9. 运维初级实践——Linux系统命令教程

    区块链运维工程师在Linux环境中常用的命令.快捷键,以及安装软件和文件管理的最佳实践. 1. 常用Linux命令 1.1 文件和目录操作 ls:列出目录内容 cd:更改目录 mkdir:创建新目录 ...

  10. GitHub、Google等镜像加速地址收集

    摘要 本文用于收集GitHub.Google等镜像/加速地址. GitHub GitHub加速地址一览 fastgithub Https://www.fastgithub.com/(推荐) 站源 地址 ...