肉夾饃(Rougamo)4.0.1 非同步方法變數除錯修復與IoC系列擴充套件

nigture發表於2024-09-02

肉夾饃(https://github.com/inversionhourglass/Rougamo),一款編譯時AOP元件,無需在應用啟動時進行初始化,也無需繁瑣的配置;支援所有種類方法(同步和非同步、靜態和例項、構造方法/屬性/普通方法);提供了簡單易上手的Attribute應用方式,同時還提供了類AspectJ表示式的批次應用規則。

4.0.1 更新內容

4.0版本釋出的文章評論 中,有朋友反饋了一個除錯時無法檢視方法內部變數值的問題。本次更新就是修復這個問題的,4.0.1不包含其他修改,對除錯時禁用肉夾饃的朋友沒有任何影響,可以酌情升級。

肉夾饃IoC/DI擴充套件

4.0.1本來是不準備發部落格的,內容一句話就結束了,不過又想到前段時間還發布了IoC擴充套件,索性就合在一起寫一篇部落格吧。

各位在使用肉夾饃時,最常遇到的問題可能就是如何與IoC互動了。現在主流的動態代理本身就需要IoC才能完成,所以動態代理在IoC互動方面具有天然的優勢,而肉夾饃編譯時完成不依賴IoC,所以與IoC的互動也不是很方便。但不方便並不是不能。此前已經有朋友在自己的專案中實現了IoC的訪問,比如Rougamo.OpenTelemetry, FreeSql。考慮到IoC的使用在現在已經非常普遍,所以新增了幾個常用IoC的擴充套件包。

目前只對最常用的兩個IoC元件提供了支援,一個是微軟官方的Microsoft.Extensions.DependencyInjection,另一個是Autofac,主要包含四個NuGet:

  • Rougamo.Extensions.DependencyInjection.AspNetCore
  • Rougamo.Extensions.DependencyInjection.GenericHost
  • Rougamo.Extensions.DependencyInjection.Autofac.AspNetCore
  • Rougamo.Extensions.DependencyInjection.Autofac

其中AspNetCore結尾的兩個NuGet專用於AspNetCore(廢話了哦),另外兩個NuGet用於通用主機(Generic Host)和Framework等場景。

版本號說明

在引用這些NuGet包時,你會發現他們都包含很多個版本,這並不是版本迭代更新快或者版本號設定錯了導致的,版本號有相應的規則,它們的主版本號跟隨對應IoC元件的NuGet主版本號。微軟官方的兩個擴充套件包的主版本號跟隨Microsoft.Extensions.*的主版本號(也是.NET SDK的版本),Autofac的兩個擴充套件包的主版本號跟隨Autofac的主版本號。

快速開始

下面直接用程式碼快速展示如何使用對應的擴充套件包。

Rougamo.Extensions.DependencyInjection.AspNetCore

// 註冊Rougamo(注:如果你不使用IoC/DI功能,Rougamo預設是不需要註冊操作的)
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    // ...省略其他步驟
    builder.Services.AddRougamoAspNetCore();
    // ...省略其他步驟
}

// 在切面型別中獲取IServiceProvider例項並使用
public class TestAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        // 使用擴充套件方法GetServiceProvider獲取IServiceProvider例項
        var services = context.GetServiceProvider();

        // 使用IServiceProvider
        var xxx = services.GetService<IXxx>();
    }
}

Rougamo.Extensions.DependencyInjection.GenericHost

// 註冊Rougamo(注:如果你不使用IoC/DI功能,Rougamo預設是不需要註冊操作的)
public static void Main(string[] args)
{
    var builder = Host.CreateDefaultBuilder();
    // ...省略其他步驟
    builder.ConfigureServices(services => services.AddRougamoGenericHost());
    // ...省略其他步驟
}

// 在切面型別中獲取IServiceProvider例項並使用
public class TestAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        // 使用擴充套件方法GetServiceProvider獲取IServiceProvider例項
        var services = context.GetServiceProvider();

        // 使用IServiceProvider
        var xxx = services.GetService<IXxx>();
    }
}

Rougamo.Extensions.DependencyInjection.Autofac.AspNetCore

// 註冊Rougamo(注:如果你不使用IoC/DI功能,Rougamo預設是不需要註冊操作的)
public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Host
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureContainer<ContainerBuilder>(builder =>
            {
                builder.RegisterRougamoAspNetCore();
            });
    
    // 註冊IHttpContextAccessor也是必須的
    builder.Services.AddHttpContextAccessor();
}

// 在切面型別中獲取ILifetimeScope例項並使用
public class TestAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        // 使用擴充套件方法GetAutofacCurrentScope獲取ILifetimeScope例項
        var scope = context.GetAutofacCurrentScope();

        // 使用ILifetimeScope
        var xxx = scope.Resolve<IXxx>();
    }
}

Rougamo.Extensions.DependencyInjection.Autofac

// 註冊Rougamo(注:如果你不使用IoC/DI功能,Rougamo預設是不需要註冊操作的)
public static void Main(string[] args)
{
    var builder = Host.CreateDefaultBuilder();
    
    builder
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
        .ConfigureContainer<ContainerBuilder>(builder =>
        {
            builder.RegisterRougamo();
        });
}

// 在切面型別中獲取IServiceProvider例項並使用
public class TestAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        // 使用擴充套件方法GetAutofacCurrentScope獲取ILifetimeScope例項
        var scope = context.GetAutofacCurrentScope();

        // 使用ILifetimeScope
        var xxx = scope.Resolve<IXxx>();
    }
}

比較早的Framework專案以及WinForm、WPF等專案可能並沒有使用通用主機(Generic Host),此時使用Rougamo.Extensions.DependencyInjection.Autofac將更加直接,初始化時建立ContainerBuilder後直接呼叫RegisterRougamo擴充套件方法即可。

var builder = new ContainerBuilder();
builder.RegisterRougamo();

更多

肉夾饃IoC/DI擴充套件更多的資訊請訪問 Rougamo.DI (https://github.com/inversionhourglass/Rougamo.DI),歡迎反饋建議和提交PR.

相關文章