zoukankan      html  css  js  c++  java
  • 简单探讨一下.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 是可选的。

  • 相关阅读:
    排序操作
    逻辑回归
    二叉树的建立以及相关操作,平衡二叉树
    【AMAD】cookiecutter-django -- 是一个构建Django项目的脚手架工具
    【AMAD】django-allauth
    【AMAD】django-formapi -- 一个DJANGO API框架,可使用签名request,可使用form作为API的验证工具
    【AMAD】django-cities -- 为Django项目提供国家,城市数据
    【AMAD】django-countries -- 为Django app的form提供country选项,为model提供CountryField
    【AMAD】django-social-auth -- 让django使用社交网络oauth鉴权变得极为轻松!
    每周分享第9期(2019.6.1)
  • 原文地址:https://www.cnblogs.com/catcher1994/p/11623567.html
Copyright © 2011-2022 走看看