无法使用服务容器中的服务和默认值实例化类型 'MyProject.Response' 的构造函数
No constructor for type 'MyProject.Response' can be instantiated using services from the service container and default values
我正在使用 asp.net 核心 3.1 项目模板开发网站 API。没有编译错误。
这是我的代码详情:
Program.cs
public class Program
{
public static void Main(string[] args)
{
// Use the W3C Trace Context format to propagate distributed trace identifiers.
// See https://devblogs.microsoft.com/aspnet/improvements-in-net-core-3-0-for-troubleshooting-and-monitoring-distributed-apps/
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs
public class Startup
{
private readonly IConfiguration configuration;
private readonly IWebHostEnvironment webHostEnvironment;
/// <summary>
/// Initializes a new instance of the <see cref = "Startup"/> class.
/// </summary>
/// <param name = "configuration">The application configuration, where key value pair settings are stored. See
/// http://docs.asp.net/en/latest/fundamentals/configuration.html</param>
/// <param name = "webHostEnvironment">The environment the application is running under. This can be Development,
/// Staging or Production by default. See http://docs.asp.net/en/latest/fundamentals/environments.html</param>
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
this.configuration = configuration;
this.webHostEnvironment = webHostEnvironment;
}
/// <summary>
/// Configures the services to add to the ASP.NET Core Injection of Control (IoC) container. This method gets
/// called by the ASP.NET runtime. See
/// http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx
/// </summary>
public virtual void ConfigureServices(IServiceCollection services) =>
services
.AddCosmosDBConfiguration(configuration)
.AddAutoMapperConfiguration()
.AddCustomResponseCompression(configuration)
.AddCustomCors()
.AddCustomOptions(configuration)
.AddHttpContextAccessor()
.AddCustomRouting()
.AddCustomStrictTransportSecurity()
.AddCustomHealthChecks()
.AddServerTiming()
.AddControllers()
.AddCustomJsonOptions(webHostEnvironment)
.AddCustomMvcOptions(configuration)
.Services
.AddCustomGraphQL(configuration, webHostEnvironment)
.AddGraphQLResolvers()
.AddGraphQLResponse()
.AddProjectRepositories()
.AddProjectSchemas();
/// <summary>
/// Configures the application and HTTP request pipeline. Configure is called after ConfigureServices is
/// called by the ASP.NET runtime.
/// </summary>
public virtual void Configure(IApplicationBuilder application) =>
application
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x.UseServerTiming())
.UseForwardedHeaders()
.UseResponseCompression()
.UseFetchLocaleMiddleware()
.UseIf(
!this.webHostEnvironment.IsDevelopment(),
x => x.UseHsts())
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x.UseDeveloperExceptionPage())
.UseRouting()
.UseCors(CorsPolicyName.AllowAny)
.UseEndpoints(
builder =>
{
builder
.MapHealthChecks("/status")
.RequireCors(CorsPolicyName.AllowAny);
builder
.MapHealthChecks("/status/self", new HealthCheckOptions() { Predicate = _ => false })
.RequireCors(CorsPolicyName.AllowAny);
})
.UseWebSockets()
// Use the GraphQL subscriptions in the specified schema and make them available at /graphql.
.UseGraphQLWebSockets<MainSchema>()
// Use the specified GraphQL schema and make them available at /graphql.
.UseGraphQL<MainSchema>()
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x
// Add the GraphQL Playground UI to try out the GraphQL API at /.
.UseGraphQLPlayground(new GraphQLPlaygroundOptions() { Path = "/" })
// Add the GraphQL Voyager UI to let you navigate your GraphQL API as a spider graph at /voyager.
.UseGraphQLVoyager(new GraphQLVoyagerOptions() { Path = "/voyager" }));
}
Response.cs
public class Response
{
public object Data { get; set; }
public string StatusCode { get; set; }
public string ErrorMessage { get; set; }
public Response(object data)
{
StatusCode = "Success";
Data = data;
}
public Response(string statusCode, string errorMessage)
{
StatusCode = statusCode;
ErrorMessage = errorMessage;
}
}
Startup.cs ConfigureServices
中提到的所有依赖项都可用。在验证 APIs 时,我收到 运行 时间错误,如下所述:
No constructor for type 'MyProject.Response' can be instantiated using services from the service container and default values.
响应 class 所需的依赖设置如下所述:
ProjectServiceCollectionExtensions.cs
namespace MyProject
{
public static class ProjectServiceCollectionExtensions
{
public static IServiceCollection AddGraphQLResponse(this IServiceCollection services) => services.AddScoped<Response>();
}
}
Resolver.cs
public class Resolver
{
public Response Response(object data)
{
return new Response(data);
}
public Response Error(GraphQLError error)
{
return new Response(error.StatusCode, error.ErrorMessage);
}
public Response AccessDeniedError()
{
var error = new AccessDeniedError();
return new Response(error.StatusCode, error.ErrorMessage);
}
public Response NotFoundError(string id)
{
var error = new NotFoundError(id);
return new Response(error.StatusCode, error.ErrorMessage);
}
}
国家Resolver.cs
using Author.Core.Framework.Utilities;
using Author.Query.New.API.GraphQL.Types;
using Author.Query.Persistence.DTO;
using Author.Query.Persistence.Interfaces;
using GraphQL.DataLoader;
using GraphQL.Types;
using Microsoft.AspNetCore.Http;
using System;
namespace MyProject.GraphQL.Resolvers
{
public class CountriesResolver : Resolver, ICountriesResolver
{
private readonly ICountryService _countryService;
private readonly IHttpContextAccessor _accessor;
private readonly IUtilityService _utilityService;
private readonly IDataLoaderContextAccessor _dataLoaderContextAccessor;
public CountriesResolver(ICountryService countryService, IHttpContextAccessor accessor, IUtilityService utilityService, IDataLoaderContextAccessor dataLoaderContextAccessor)
{
_countryService = countryService ?? throw new ArgumentNullException(nameof(countryService));
_accessor = accessor;
_utilityService = utilityService ?? throw new ArgumentNullException(nameof(utilityService));
_dataLoaderContextAccessor = dataLoaderContextAccessor;
}
public void Resolve(GraphQLQuery graphQLQuery)
{
var language = _accessor.HttpContext.Items["language"] as LanguageDTO;
graphQLQuery.FieldAsync<ResponseGraphType<CountryResultType>>("countriesresponse", resolve: async context =>
{
if (language != null)
{
var loader = _dataLoaderContextAccessor.Context.GetOrAddLoader("GetAllCountries", () => _countryService.GetAllCountriesAsync(language));
var list = await context.TryAsyncResolve(async c => await loader.LoadAsync());
return Response(list);
}
return null;
}
, description: "All Countries data");
graphQLQuery.FieldAsync<ResponseGraphType<CountryType>>("country", arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IntGraphType>>{Name = "countryId", Description = "id of the country"}), resolve: async context =>
{
var countryId = context.GetArgument<int>("countryId");
if (language != null && countryId > 0)
{
var loader = _dataLoaderContextAccessor.Context.GetOrAddLoader("GetCountry", () => _countryService.GetCountryAsync(language, countryId));
var countryDetails = await context.TryAsyncResolve(async c => await loader.LoadAsync());
return Response(countryDetails);
}
return null;
}
);
}
}
}
谁能提供指导帮助我解决这个问题
根据 Resolver
使用 Response
的方式,我认为 Response
不需要添加到 DI/IoC 容器中,因为 Resolver
本质上是一个 Response
工厂
如果 Response
没有显式地注入到任何地方,那么容器不需要知道它。无需将其添加到开头的容器中。
移除
//...
.AddGraphQLResponse() //<--SHOULD BE REMOVED
//...
来自 Startup.ConfigureServices
的扩展
我正在使用 asp.net 核心 3.1 项目模板开发网站 API。没有编译错误。
这是我的代码详情:
Program.cs
public class Program
{
public static void Main(string[] args)
{
// Use the W3C Trace Context format to propagate distributed trace identifiers.
// See https://devblogs.microsoft.com/aspnet/improvements-in-net-core-3-0-for-troubleshooting-and-monitoring-distributed-apps/
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs
public class Startup
{
private readonly IConfiguration configuration;
private readonly IWebHostEnvironment webHostEnvironment;
/// <summary>
/// Initializes a new instance of the <see cref = "Startup"/> class.
/// </summary>
/// <param name = "configuration">The application configuration, where key value pair settings are stored. See
/// http://docs.asp.net/en/latest/fundamentals/configuration.html</param>
/// <param name = "webHostEnvironment">The environment the application is running under. This can be Development,
/// Staging or Production by default. See http://docs.asp.net/en/latest/fundamentals/environments.html</param>
public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment)
{
this.configuration = configuration;
this.webHostEnvironment = webHostEnvironment;
}
/// <summary>
/// Configures the services to add to the ASP.NET Core Injection of Control (IoC) container. This method gets
/// called by the ASP.NET runtime. See
/// http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx
/// </summary>
public virtual void ConfigureServices(IServiceCollection services) =>
services
.AddCosmosDBConfiguration(configuration)
.AddAutoMapperConfiguration()
.AddCustomResponseCompression(configuration)
.AddCustomCors()
.AddCustomOptions(configuration)
.AddHttpContextAccessor()
.AddCustomRouting()
.AddCustomStrictTransportSecurity()
.AddCustomHealthChecks()
.AddServerTiming()
.AddControllers()
.AddCustomJsonOptions(webHostEnvironment)
.AddCustomMvcOptions(configuration)
.Services
.AddCustomGraphQL(configuration, webHostEnvironment)
.AddGraphQLResolvers()
.AddGraphQLResponse()
.AddProjectRepositories()
.AddProjectSchemas();
/// <summary>
/// Configures the application and HTTP request pipeline. Configure is called after ConfigureServices is
/// called by the ASP.NET runtime.
/// </summary>
public virtual void Configure(IApplicationBuilder application) =>
application
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x.UseServerTiming())
.UseForwardedHeaders()
.UseResponseCompression()
.UseFetchLocaleMiddleware()
.UseIf(
!this.webHostEnvironment.IsDevelopment(),
x => x.UseHsts())
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x.UseDeveloperExceptionPage())
.UseRouting()
.UseCors(CorsPolicyName.AllowAny)
.UseEndpoints(
builder =>
{
builder
.MapHealthChecks("/status")
.RequireCors(CorsPolicyName.AllowAny);
builder
.MapHealthChecks("/status/self", new HealthCheckOptions() { Predicate = _ => false })
.RequireCors(CorsPolicyName.AllowAny);
})
.UseWebSockets()
// Use the GraphQL subscriptions in the specified schema and make them available at /graphql.
.UseGraphQLWebSockets<MainSchema>()
// Use the specified GraphQL schema and make them available at /graphql.
.UseGraphQL<MainSchema>()
.UseIf(
this.webHostEnvironment.IsDevelopment(),
x => x
// Add the GraphQL Playground UI to try out the GraphQL API at /.
.UseGraphQLPlayground(new GraphQLPlaygroundOptions() { Path = "/" })
// Add the GraphQL Voyager UI to let you navigate your GraphQL API as a spider graph at /voyager.
.UseGraphQLVoyager(new GraphQLVoyagerOptions() { Path = "/voyager" }));
}
Response.cs
public class Response
{
public object Data { get; set; }
public string StatusCode { get; set; }
public string ErrorMessage { get; set; }
public Response(object data)
{
StatusCode = "Success";
Data = data;
}
public Response(string statusCode, string errorMessage)
{
StatusCode = statusCode;
ErrorMessage = errorMessage;
}
}
Startup.cs ConfigureServices
中提到的所有依赖项都可用。在验证 APIs 时,我收到 运行 时间错误,如下所述:
No constructor for type 'MyProject.Response' can be instantiated using services from the service container and default values.
响应 class 所需的依赖设置如下所述:
ProjectServiceCollectionExtensions.cs
namespace MyProject
{
public static class ProjectServiceCollectionExtensions
{
public static IServiceCollection AddGraphQLResponse(this IServiceCollection services) => services.AddScoped<Response>();
}
}
Resolver.cs
public class Resolver
{
public Response Response(object data)
{
return new Response(data);
}
public Response Error(GraphQLError error)
{
return new Response(error.StatusCode, error.ErrorMessage);
}
public Response AccessDeniedError()
{
var error = new AccessDeniedError();
return new Response(error.StatusCode, error.ErrorMessage);
}
public Response NotFoundError(string id)
{
var error = new NotFoundError(id);
return new Response(error.StatusCode, error.ErrorMessage);
}
}
国家Resolver.cs
using Author.Core.Framework.Utilities;
using Author.Query.New.API.GraphQL.Types;
using Author.Query.Persistence.DTO;
using Author.Query.Persistence.Interfaces;
using GraphQL.DataLoader;
using GraphQL.Types;
using Microsoft.AspNetCore.Http;
using System;
namespace MyProject.GraphQL.Resolvers
{
public class CountriesResolver : Resolver, ICountriesResolver
{
private readonly ICountryService _countryService;
private readonly IHttpContextAccessor _accessor;
private readonly IUtilityService _utilityService;
private readonly IDataLoaderContextAccessor _dataLoaderContextAccessor;
public CountriesResolver(ICountryService countryService, IHttpContextAccessor accessor, IUtilityService utilityService, IDataLoaderContextAccessor dataLoaderContextAccessor)
{
_countryService = countryService ?? throw new ArgumentNullException(nameof(countryService));
_accessor = accessor;
_utilityService = utilityService ?? throw new ArgumentNullException(nameof(utilityService));
_dataLoaderContextAccessor = dataLoaderContextAccessor;
}
public void Resolve(GraphQLQuery graphQLQuery)
{
var language = _accessor.HttpContext.Items["language"] as LanguageDTO;
graphQLQuery.FieldAsync<ResponseGraphType<CountryResultType>>("countriesresponse", resolve: async context =>
{
if (language != null)
{
var loader = _dataLoaderContextAccessor.Context.GetOrAddLoader("GetAllCountries", () => _countryService.GetAllCountriesAsync(language));
var list = await context.TryAsyncResolve(async c => await loader.LoadAsync());
return Response(list);
}
return null;
}
, description: "All Countries data");
graphQLQuery.FieldAsync<ResponseGraphType<CountryType>>("country", arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IntGraphType>>{Name = "countryId", Description = "id of the country"}), resolve: async context =>
{
var countryId = context.GetArgument<int>("countryId");
if (language != null && countryId > 0)
{
var loader = _dataLoaderContextAccessor.Context.GetOrAddLoader("GetCountry", () => _countryService.GetCountryAsync(language, countryId));
var countryDetails = await context.TryAsyncResolve(async c => await loader.LoadAsync());
return Response(countryDetails);
}
return null;
}
);
}
}
}
谁能提供指导帮助我解决这个问题
根据 Resolver
使用 Response
的方式,我认为 Response
不需要添加到 DI/IoC 容器中,因为 Resolver
本质上是一个 Response
工厂
如果 Response
没有显式地注入到任何地方,那么容器不需要知道它。无需将其添加到开头的容器中。
移除
//...
.AddGraphQLResponse() //<--SHOULD BE REMOVED
//...
来自 Startup.ConfigureServices