前言
這幾天在對EasyCaching做支持.net core 3.0的調整。期間遇到下面這個錯誤。
System.NotSupportedException:“ConfigureServices returning an System.IServiceProvider isn't supported
針對這個問題,網上能找到比較多的資料是關於Autofac的,AspectCore的好像比較少。
下面就直接看看簡單的處理方法,也在AspectCore上面的Issue回復了。
ServiceProviderFactory的使用
在preview3之后,ConfigureServices
方法就不支持直接返回System.IServiceProvider
。
我們可以通過IHostBuilder
的 UseServiceProviderFactory
方法來覆蓋默認的工廠實現。
具體使用如下:
// 要引入這個命名空間
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
是可選的。