简单探讨一下.NET Core 3.0使用AspectCore的新姿势

前言

这几天在对EasyCaching做支持.net core 3.0的调整。期间遇到下面这个错误。

System.NotSupportedException:“ConfigureServices returning an System.IServiceProvider isn't supported

针对这个问题,网上能找到比较多的资料是关于Autofac的,AspectCore的好像比较少。

下面就直接看看简单的处理方法,也在AspectCore上面的Issue回复了。

ServiceProviderFactory的使用

在preview3之后,ConfigureServices方法就不支持直接返回System.IServiceProvider

我们可以通过IHostBuilderUseServiceProviderFactory方法来覆盖默认的工厂实现。

具体使用如下:

// 要引入这个命名空间
using AspectCore.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            // for aspcectcore
            .UseServiceProviderFactory(new AspectCoreServiceProviderFactory())
        ;
}

到这里,我们“系统”级别的配置已经OK。也可以看看AspectCoreServiceProviderFactory的实现

[NonAspect]
public class AspectCoreServiceProviderFactory : IServiceProviderFactory<IServiceContainer>
{
    public IServiceContainer CreateBuilder(IServiceCollection services)
    {
        return services.ToServiceContainer();
    }

    public IServiceProvider CreateServiceProvider(IServiceContainer containerBuilder)
    {
        return containerBuilder.Build();
    }
}

就实现了IServiceProviderFactory<T>两个方法,十分的简单。

如果有特殊的AspectCore要求,好比实现一个简单的AOP,我们要把代码写那里呢?

下面还有另外一个主角 ConfigureContainer

ConfigureContainer的使用

我们只需要在Startup里面加一个ConfigureContainer方法就可以实现相应的扩展。

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
         // ...
    }
 
    public void ConfigureContainer(IServiceContainer builder)
    {
        // 这里就是熟悉的味道了。。。
        builder.Configure(config =>
        {            
            config.Interceptors.AddTyped<xxx>();
        });
    }

    public void Configure(IApplicationBuilder app)
    {
        // ...
    }
}

可以看到ConfigureContainer的参数是和AspectCoreServiceProviderFactory里面的类型T是一致的!

这里要注意一点,ConfigureContainer会在ConfigureServices之后执行,不小心会出现覆盖的情况,所以一定要特别注意,不要在这些地方进行Build操作!!并且Startup中只能有一个ConfigureContainer方法,ConfigureContainer方法只能有一个参数。

总结

知道这两个地方,加上AspectCore的基本用法,应该就可以在3.0中正常的使用AspectCore了。

其中 UseServiceProviderFactory 是必须的, ConfigureContainer 是可选的。

posted @   Catcher8  阅读(4945)  评论(15编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示