首页 > 其他分享 >聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(三)

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

时间:2024-01-12 22:22:23浏览次数:57  
标签:Core 拦截器 Console ... 聊一聊 Extensions invocation Interceptor public

前言

今天的第三篇,感觉没啥人看呀,难道没有兄弟跟我有同样的整合需求吗???手动image
image
image
本文会简短一些,介绍下 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();
}

输入如图所示:image

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执行了异步方法的拦截,再执行
image
image

此时引出 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

标签:Core,拦截器,Console,...,聊一聊,Extensions,invocation,Interceptor,public
From: https://www.cnblogs.com/gainorloss/p/17961711

相关文章

  • netcore webpi 通过signalr 给vue项目推送消息
     最近项目上需要做个服务给前端推消息,首先就想到了signalr,关于signalr详情可以参考微软官方文档(ASP.NETCoreSignalR概述|MicrosoftLearn),微软现在也有使用教程(ASP.NETCoreSignalR入门|MicrosoftLearn)微软教程是通过使用库管理器(LibMan)从unpkg 获取客户端库,如......
  • .NET Core MemoryCache缓存批量获取Key或者删除
    .NetCore下使用缓存,除了大家耳熟能详的Redis做分布式缓存外,本地内存缓存也会一起结合来使用,它存取更快,使我们的应用达到极致性能要求。这也是我们经常提到的3级或者4级缓存,每一层都有自己的使用场景,优缺点,结合业务特点来选择合适的才是王道。这里我们就使用Net原生的Microsoft......
  • 无涯教程-Redis - ZSCORE 命令函数
    RedisZSCORE命令返回键排序后的元素的得分,如果元素不存在于排序集中,或者键不存在,则返回nil。ZSCORE-返回值返回元素的分数值。ZSCORE-语法以下是RedisZSCORE命令的基本语法。redis127.0.0.1:6379>ZSCOREkeymemberZSCORE-示例redis127.0.0.1:6379>ZADDm......
  • 无涯教程-Redis - ZREMRANGEBYSCORE 命令函数
    RedisZREMRANGEBYSCORE命令删除存储在键中的排序集中的所有元素,这些元素的分数介于最小和最大(含)之间。ZREMRANGEBYSCORE-返回值返回删除的元素数量。ZREMRANGEBYSCORE-语法以下是RedisZREMRANGEBYSCORE命令的基本语法。redis127.0.0.1:6379>ZREMRANGEBYSCORE......
  • AWS IoT Core 实战指南
    AmazonWebServices(AWS)提供了全球范围内的托管服务,其中包括AWSIoTCore,专为连接和管理物联网设备而设计。这个实战指南将带你一步步了解如何使用AWSIoTCore来注册设备、提高安全性、进行通信以及利用设备影子功能。设备注册1.创建Thing(设备)在AWSIoT控制台中,创建一......
  • openGauss学习笔记-188 openGauss 数据库运维-常见故障定位案例-core问题定位
    openGauss学习笔记-188openGauss数据库运维-常见故障定位案例-core问题定位188.1磁盘满故障引起的core问题188.1.1问题现象TPCC运行时,注入磁盘满故障,数据库进程gaussdbcore掉,如下图所示。188.1.2原因分析数据库本身机制,在磁盘满时,Xlog日志无法进行写入,通过panic日志退......
  • 【THM】Burp Suite:Extensions(Burp Suite扩展·更新版)-学习
    本文相关的TryHackMe实验房间链接:https://tryhackme.com/room/burpsuiteextensions本文相关内容:了解如何使用Extensions模块来扩展BurpSuite的功能。简介在本文中,我们将学习BurpSuite的Extensions(扩展)功能模块,该功能允许开发人员为Burp框架创建附加模块。虽然在本文中并......
  • aspnetcore使用websocket实时更新商品信息
    先演示一下效果,再展示代码逻辑。中间几次调用过程省略。。。暂时只用到了下面四个项目1.产品展示页面中第一次通过接口去获取数据库的列表数据///<summary>///获取指定的商品目录///</summary>///<paramname="pageSize"></param>///<paramname="pageIndex"></p......
  • 第5章 在 ASP.NET Core Web 应用进程中使用 EF Core
    本章涵盖在ASP.NETCore中使用EFCore在ASP.NETCore中使用依赖注入在ASP.NET核心MVC操作中访问数据库使用EFCore迁移更新数据库使用async/await提高可扩展性在本章中,您将使用ASP.NETCore构建一个真正的Web应用进程,将所有内容集成在一起。当然,使用ASP.N......
  • 第4章 在业务逻辑中使用 EF Core
    本章涵盖了解业务逻辑及其对EFCore的使用从简单到复杂的三种业务逻辑审查每种类型的业务逻辑,包括优缺点添加一个步骤,用于在将数据写入数据库之前验证数据使用事务以菊花链方式连接代码串行实际应用进程旨在提供一组服务,从在计算机上保存简单的事物列表到类似管理核反应......