聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core

这篇具有很好参考价值的文章主要介绍了聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

如果用到动态代理,大家可能会有几种选择,排到前列的是Autofac+Castle、AspectCore和DoraInterception,
我将从我当时研究的经历,以及我遇到的场景,为大家展示下
聊一聊我为什么要费时费力的整合Microsoft.Extensions.DependencyInjection和Castle.Core

当时遇到的场景

直接上源码

  public interface IEventHandler
  {
      Task<bool> HandleAsync(IEvent @event);

      bool CanHandle(IEvent @event);
  }

  public interface IEventHandler<T> : IEventHandler
      where T : class, IEvent
  {
      Task<bool> HandleAsync(T @event);

      bool IEventHandler.CanHandle(IEvent @event) => @event.GetType() == typeof(T);//语言特性:默认实现 2024-1-15 10:23:10

      Task<bool> IEventHandler.HandleAsync(IEvent @event) => CanHandle((T)@event) //语言特性:默认实现 2024-1-15 10:23:10
          ? HandleAsync((T)@event)
          : Task.FromResult(false);
  }

public interface IEvent
{
     public long Id { get; set; }
     public DateTime OccurredOn { get; set; }
}

如上所示的接口定义了一个事件处理接口,其中HandleAsync方法是事件处理的入口,CanHandle方法用于判断事件是否可以处理,在程序解耦、异步、削峰填谷等场景中,如上的接口可以有很多的应用,也可以扩展到内存级别、RabbitMQ、Redis、Kafka、RocketMQ等中间件的适配的事件处理器,以提供更强大的性能和更丰富的应用场景。所以说这是一个比较通用的场景。
我们将为该处理器提供一个检查幂等的拦截器( Idempotent)

AspectCore

事件定义如下

 public class CatchLoggingOccurredEvent : IEvent
 {
     protected CatchLoggingOccurredEvent()
     {
         OccurredOn = DateTime.Now;
     }

     public CatchLoggingOccurredEvent(long id)
         : this()
     {
         Id = id;
     }

     public long Id { get; set; }
     public DateTime OccurredOn { get; set; }
 }

事件处理器及Aspecore定义的特性

/// <summary>
/// 
/// </summary>
public class CatchLoggingOccurredEventHandler
: IEventHandler<CatchLoggingOccurredEvent>
{
    [Idempotent]
    public async virtual Task<bool> HandleAsync(CatchLoggingOccurredEvent @event)
    {
        await Console.Out.WriteLineAsync($"{nameof(CatchLoggingOccurredEventHandler)}处理事件:\t事件【{@event.Id}】@@@@@@发生于【{@event.OccurredOn}】");
        return true;
    }
}
 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
 internal class IdempotentAttribute
     : AbstractInterceptorAttribute
 {
     public override async Task Invoke(AspectContext context, AspectDelegate next)
     {
         var logger = context.ServiceProvider.GetRequiredService<ILogger<IdempotentAttribute>>();
         logger.LogInformation("幂等检查");
         await next(context);
     }
 }

执行
报错如下
System.TypeLoadException:“Declaration referenced in a method implementation cannot be a final method. Type: 'AspectCore.DynamicGenerated.CatchLoggingOccurredEventHandler'. Assembly: 'AspectCore.DynamicProxy.Generator, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.”
应该是AspectCore认为我的handle方法为一个不可覆写的方法所以抛错,该问题我已提issue至 https://github.com/dotnetcore/AspectCore-Framework/issues/319 等待解决

DoraInterception

 /// <summary>
 /// 
 /// </summary>
 public class CatchLoggingOccurredEventHandler
 : IEventHandler<CatchLoggingOccurredEvent>
 {
     private readonly ILogger<CatchLoggingOccurredEventHandler> _logger;

     public CatchLoggingOccurredEventHandler(ILogger<CatchLoggingOccurredEventHandler> logger)
     {
         _logger = logger;
     }

     [Idempotent]
     public async virtual Task<bool> HandleAsync(CatchLoggingOccurredEvent message)
     {
         await Console.Out.WriteLineAsync($"{nameof(CatchLoggingOccurredEventHandler)}处理事件:\t事件【{message.Id}】@@@@@@发生于【{message.OccurredOn}】");
         return true;
     }
 }
 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
internal class IdempotentAttribute
    : InterceptorAttribute
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="invocationContext"></param>
    /// <returns></returns>
    public async ValueTask InvokeAsync(InvocationContext invocationContext)
    {
        var logger = invocationContext.InvocationServices.GetRequiredService<ILogger<IdempotentAttribute>>();
        logger.LogInformation("幂等检查");
        await invocationContext.ProceedAsync();
    }
}

执行 报错如下:Dora.Interception.InterceptionException:“It fails to generate proxy class. (69,130): error CS0234: 命名空间“Microsoft.Extensions”中不存在类型或命名空间名“Logging”(是否缺少程序集引用?) (69,220): error CS0012: 类型“ILogger<>”在未引用的程序集中定义。必须添加对程序集“Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60”的引用。”
dorainterception 使用 SourceGenerator,这个技术处理的复杂度比较高,根据报错是 处理器中依赖的Logging组件无法解析,这个问题比较严重,因为依赖注入这个太重要了。该问题见于 pr https://github.com/jiangjinnan/Dora/pull/13

Autofac+Castle

为什么不想使用Autofac,笔者的考虑是Autofac虽然功能繁多,但是其实真正实际能用到的功能少之又少,大部分的功能都可以自己扩展出来。
借用下 https://github.com/dadhi/DryIoc 的一张性能比拼图
聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core

可见其实我们已经手握了一个高性能而且简单易用易扩展的ioc框架,合并要去另寻他处,如果因为AOP技术选型的原因,选择了autofac+Castle,那何不试下 整合 Microsoft.Extensions.DependencyInjection和Castle.Core

综上

截止发稿为止,已经将本系列文章的研究成果总结至 https://github.com/gainorloss/microsoft-castle.git,并以发nuget至 https://www.nuget.org/packages/CastleCore.Extensions.DependencyInjection/1.1.0,
基准测试结果差强人意。castle代理的性能是原生的几百倍分之一,考虑到castle的广泛受众和稳定性,可堪一用。
本文但图一乐,请各位看官谨慎采纳,有意见请留言。文章来源地址https://www.toymoban.com/news/detail-790270.html

到了这里,关于聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 什么是“ Microsoft网络实时检查服务”(NisSrv.exe),为什么它在我的PC上运行?

    Windows 10 includes Windows Defender, which protects your PC against viruses and other threats. The “Microsoft Network Realtime Inspection Service” process, also known as NisSrv.exe, is part of Microsoft’s antivirus software. Windows 10包含Windows Defender,可保护您的PC免受病毒和其他威胁的侵害。 “ Microsoft网络实时检查服务”

    2024年02月03日
    浏览(61)
  • 为什么通过SMB打开群晖的Microsoft Office文件时无法进行编辑?

    症状 您的Microsoft Office文件(如Word,Excel,PowerPoint)在您尝试打开时已被锁定,无法编辑。 诊断 以下可能是原因之一: 文件已在另一个客户端设备上打开。 另一个用户正在编辑同一文件。 Windows正在尝试读取文件信息。 解决方案 可以尝试以下任何方法来解锁文件。 请检查

    2024年02月05日
    浏览(43)
  • 【报错】在浏览器输入localhost为什么启动的是Microsoft的IIS windows首页?

    在浏览器输入localhost为什么启动的是Microsoft的IIS windows首页 windows11设置的是iis服务自动启动,重启电脑后会自己启动。

    2024年02月13日
    浏览(31)
  • 聊一聊synchronized

    在 Java 中, synchronized 可以用于实现线程同步,有以下几种常见的使用方式: 修饰代码块:将 synchronized 放在代码块的前面, 例如: 在这种方式下,会为给定的对象 obj 获取锁,在代码块执行期间,只有持有该锁的线程才能进入代码块执行。 修饰方法:将 sync

    2024年01月22日
    浏览(50)
  • 聊一聊大模型

    事情还得从ChatGPT说起。 2022年12月OpenAI发布了自然语言生成模型ChatGPT,一个可以基于用户输入文本自动生成回答的人工智能体。它有着赶超人类的自然对话程度以及逆天的学识。一时间引爆了整个人工智能界,各大巨头也纷纷跟进发布了自家的大模型,如:百度-文心一言、科

    2024年02月05日
    浏览(48)
  • 聊一聊 TLS/SSL

    哈喽大家好,我是咸鱼 当我们在上网冲浪的时候,会在浏览器界面顶部看到一个小锁标志,或者网址以 \\\"https://\\\" 开头 这意味着我们正在使用 TLS/SSL 协议进行安全通信。虽然它可能看起来只是一个小小的锁图标和一个 “https” ,但实际上,这个协议在保护我们的在线隐私和安

    2024年02月08日
    浏览(44)
  • 聊一聊AIGC

    “UGC不存在了”——借鉴自《三体》 ChatGPT 的横空出世将一个全新的概念推上风口——AIGC( AI Generated Content)。 GC即创作内容(Generated Content),和传统的UGC、PGC,OGC不同的是,AIGC的创作主体由人变成了人工智能。 xGC PGC:Professionally Generated Content,专业生产内容 UGC:User G

    2024年02月10日
    浏览(53)
  • 聊一聊模板方法模式

    统一抽取,制定规范; 模板方法模式,又叫模板模式,属于23种设计模式中的 行为型模式 。在抽象类中公开定义了执行的方法,子类可以按需重写其方法,但是要以抽象类中定义的方式调用方法。总结起来就是: 定义一个操作的算法结构,而将一些步骤延迟到子类中。在不

    2024年02月04日
    浏览(41)
  • 聊一聊Vue和Ts

    1 前言 Vue3 已经正式发布了一段时间了,各种生态已经成熟。最近使用 taro+vue3 重构冷链的小程序,经过了一段时间的开发和使用,有了一些自己的思考。 总的来说,Vue3 无论是在底层原理还是在实际开发过程中,都有了很大的进步。 从源码层面来说,使用 Proxy 代替 Object.d

    2023年04月08日
    浏览(62)
  • 聊一聊适配器模式

    接口不能用?行,我帮你适配 适配器模式(Adapter),是23种设计模式中的 结构型模式 之一;它就像我们电脑上接口不够时,需要用到的拓展坞,起到转接的作用。它可以将新的功能和原先的功能连接起来,使由于需求变动导致不能用的功能,重新利用起来。 上图的Mac上,只

    2024年02月04日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包