AspectCore-Framework icon indicating copy to clipboard operation
AspectCore-Framework copied to clipboard

.net 7.0 报错

Open hhm89106 opened this issue 3 years ago • 1 comments

.net 7.0 框架中使用 builder.Host.UseServiceContext();

An unhandled exception occurred while processing the request. InvalidOperationException: Failed to create instance of type 'Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionProvider'. Possible reason is cannot match the best constructor of type 'Microsoft.AspNetCore.Mvc.ApiExplorer.EndpointMetadataApiDescriptionProvider'. AspectCore.DependencyInjection.ServiceCallSiteResolver.ResolveTypeService(TypeServiceDefinition typeServiceDefinition)

hhm89106 avatar Nov 29 '22 14:11 hhm89106

相同的代码,.net 7.0、.net8.0中使用报错,.net 6.0中使用正常 InvalidOperationException: Failed to create instance of type 'Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionProvider'. Possible reason is cannot match the best constructor of type 'Microsoft.AspNetCore.Mvc.ApiExplorer.EndpointMetadataApiDescriptionProvider'.

    public class Program
    {
        public static void Main(string[] args)
        {
            WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
            builder.Host.UseServiceContext();//使用AspectCore
            builder.Services.AddControllers();
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            WebApplication app = builder.Build();
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.UseAuthorization();
            app.MapControllers();
            app.Run();
        }
    }

原因是[Microsoft.AspNetCore.Mvc.ApiExplorer.EndpointMetadataApiDescriptionProvider]在.NET6以上版本[我看的是.NET8]构造方法有更改:

public EndpointMetadataApiDescriptionProvider(EndpointDataSource endpointDataSource, IHostEnvironment environment, ParameterPolicyFactory parameterPolicyFactory, IServiceProviderIsService? serviceProviderIsService)

导致[AspectCore.DependencyInjection.ConstructorCallSiteResolver.TryResolve]方法中

……
                if (!_serviceTable.Contains(serviceType))
                {
                    if (!parameter.HasDefaultValue)//这里判断没有默认值返回了false
                    {
                        return false;
                    }
                    ……
                }
……

临时的解决方案:

        public class MyServiceProviderIsService(IServiceProvider serviceProvider) : IServiceProviderIsService
        {
            public bool IsService(Type serviceType)
            {
                object? service = serviceProvider.GetService(serviceType);
                bool result = service is not null;
                return result;
            }
        }
    public class Program
    {
        public static void Main(string[] args)
        {
            WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
            builder.Host.UseServiceContext();//使用AspectCore
            builder.Services.AddControllers();
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();
            builder.Services.TryAddSingleton<IServiceProviderIsService, MyServiceProviderIsService>();//加入这一行
            WebApplication app = builder.Build();
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }
            app.UseAuthorization();
            app.MapControllers();
            app.Run();
        }
    }

MateralCMX avatar Mar 05 '24 14:03 MateralCMX