日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

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

發布時間:2024/1/16 windows 32 coder
生活随笔 收集整理的這篇文章主要介紹了 聊一聊为什么我要整合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 的一張性能比拼圖

可見其實我們已經手握了一個高性能而且簡單易用易擴展的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的廣泛受眾和穩定性,可堪一用。
本文但圖一樂,請各位看官謹慎采納,有意見請留言。

總結

以上是生活随笔為你收集整理的聊一聊为什么我要整合Microsoft.Extensions.DependencyInjection和Castle.Core的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。