无法从根提供商解析 'GraphQL.Resolvers.ICountriesResolver',因为它需要范围内的服务 'Query.Persistence.SampleDbContext'
Cannot resolve 'GraphQL.Resolvers.ICountriesResolver' from root provider because it requires scoped service 'Query.Persistence.SampleDbContext'
我正在使用 ASP.NET Core 2.2、GraphQL.NET、CosmosDB、EntityFrameworkCore (Microsoft.EntityFrameworkCore.Cosmos(2.2.4).
关于运行的解决方案,我看到一个错误:
Cannot resolve 'GraphQL.Resolvers.ICountriesResolver' from root
provider because it requires scoped service
'Query.Persistence.SampleDbContext'.
这是我的代码详情:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
string serviceEndPoint = this.Configuration.GetValue<string>("CosmosDBEndpoint");
string authKeyOrResourceToken = this.Configuration.GetValue<string>("CosmosDBAccessKey");
string databaseName = this.Configuration.GetValue<string>("CosmosDBName");
services.AddEntityFrameworkCosmos();
services.AddDbContext<SampleDbContext>(options => options.UseCosmos(serviceEndPoint, authKeyOrResourceToken, databaseName, contextOptions =>
{
contextOptions.ExecutionStrategy(d => new CosmosExecutionStrategy(d));
}
));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
services.AddSingleton<IUtilityService, UtilityService>();
services.AddTransient<ICommonService, CommonService>();
services.AddTransient<ICountryService, CountryService>();
services.AddSingleton<CountryResultType>();
services.AddSingleton<GraphQLQuery>();
services.AddTransient<ICountriesResolver, CountriesResolver>();
services.AddSingleton<CountryType>();
services.AddSingleton<Response>();
services.AddScoped(typeof(ResponseGraphType<>));
services.AddScoped(typeof(ResponseListGraphType<>));
services.AddSingleton<IDataLoaderContextAccessor, DataLoaderContextAccessor>();
services.AddSingleton<DataLoaderDocumentListener>();
services.AddTransient<IAddressRepository, AddressRepository>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton<SampleSchema>();
var sp = services.BuildServiceProvider();
services.AddSingleton<ISchema>(new SampleSchema(new FuncDependencyResolver(type => sp.GetService(type))));
}
CountriesResolver.cs
public class CountriesResolver : Resolver, ICountriesResolver
{
private readonly ICountryService _countryService;
private readonly IHttpContextAccessor _accessor;
private readonly IUtilityService _utilityService;
public CountriesResolver(ICountryService countryService, IHttpContextAccessor accessor, IUtilityService utilityService)
{
_countryService = countryService;
_accessor = accessor;
_utilityService = utilityService;
}
public void Resolve(GraphQLQuery graphQLQuery)
{
graphQLQuery.Field<ResponseGraphType<CountryResultType>>("countriesresponse", resolve: context =>
{
var locale = _utilityService.GetLocale(_accessor.HttpContext.Request.Headers);
var list = _countryService.GetAllCountries(locale);
return Response(list);
}
, description: "All Countries data");
}
}
CountryService.cs
public class CountryService : ICountryService
{
private readonly SampleDbContext _dbContext;
private readonly ICommonService _commonService;
private readonly IOptions<AppSettings> _appSettings;
public CountryService(SampleDbContext dbContext, ICommonService commonService, IOptions<AppSettings> appSettings)
{
_dbContext = dbContext;
_commonService = commonService;
_appSettings = appSettings;
}
public async Task<CountryResult> GetAllCountries(string locale)
{
var result = new CountryResult();
var language = _commonService.GetLanguageFromLocale(locale);
var localeLangId = language.LanguageId;
var dftLanguageId = int.Parse(_appSettings.Value.DefaultLanguageId);
var dftDisplayName = await _dbContext.Countries.Where(cc => cc.IsPublished.Equals(true) && cc.LanguageId.Equals(dftLanguageId)).Select(df => df.DisplayNameShort).FirstOrDefaultAsync();
var countries = await (_dbContext.Countries.Where(cc => cc.IsPublished.Equals(true) && cc.LanguageId.Equals(localeLangId)).Join(_dbContext.Disclaimers.Where(dc => dc.LanguageId.Equals(localeLangId)), c => c.CountryId, d => d.DefaultCountryId, (c, d) => new CountryDTO{Uuid = c.CountryId, DisplayName = c.DisplayName ?? dftDisplayName, DisplayNameShort = c.DisplayName ?? dftDisplayName, ProviderName = d.ProviderName, ProviderTerms = d.ProviderTerms, Name = dftDisplayName, Path = dftDisplayName, CompleteResponse = true}).ToListAsync());
result.Countries = countries;
return result;
}
}
GraphQLQuery.cs
public class GraphQLQuery : ObjectGraphType
{
public GraphQLQuery(IServiceProvider serviceProvider)
{
var type = typeof(IResolver);
var resolversTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes()).Where(p => type.IsAssignableFrom(p));
foreach (var resolverType in resolversTypes)
{
var resolverTypeInterface = resolverType.GetInterfaces().Where(x => x != type).FirstOrDefault();
if (resolverTypeInterface != null)
{
var resolver = serviceProvider.GetService(resolverTypeInterface) as IResolver;
resolver.Resolve(this);
}
}
}
}
谁能帮我解决这个问题?
我快速创建了一个演示 .net core 3.0 web 应用程序,并按照您上面的方式进行了测试。然而,我这边一切都很好。
CountriesResolver 和 CountryService classes 看起来不错。但是您没有 post 您的 SampleDbContext class。你可以检查一下。
这是我的代码片段:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<CosmosDBContext>(options => options.UseCosmos(
"https://jackcosmos.documents.azure.com:443/",
"Y1tiY********lJurBg==",
"DB"
));
services.AddTransient<IMyService, MyService>();
services.AddTransient<IMyResolver, MyResolver>();
}
CosmosDBContext.cs
为方便起见,我刚刚使用 Cosmos DB SQL API 进行了测试。但是,它不应该影响 DI:
public class CosmosDBContext : DbContext
{
public CosmosDBContext(DbContextOptions<CosmosDBContext> options) : base(options)
{
}
public DbSet<Item> Items { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultContainer("Item");
}
}
public class Item
{
public Item(string key, string content) => (this.key, this.content) = (key, content);
public string id { get; set; } = Guid.NewGuid().ToString();
public string key { get; set; }
public string content { get; set; }
}
MyService.cs
public class MyService : IMyService
{
private CosmosDBContext _cosmosDbContext;
public MyService(CosmosDBContext cosmosDBContext)
{
_cosmosDbContext = cosmosDBContext;
}
public List<Item> GetByKey(string key)
{
return _cosmosDbContext.Items.Where(i => i.key.Equals(key)).ToList();
}
}
MyResolver.cs
public class MyResolver : IMyResolver
{
private IMyService _myService;
public MyResolver(IMyService myService)
{
_myService = myService;
}
public List<Item> Resolve(string key)
{
return _myService.GetByKey(key);
}
}
在我的 HomeController 中,我只是:
private IMyResolver _myResolver;
public HomeController(ILogger<HomeController> logger, CosmosDBContext cosmosDBContext, IMyResolver myResolver)
{
_myResolver = myResolver;
// Add one
cosmosDBContext.Database.EnsureCreated();
cosmosDBContext.Items.Add(new Item("aaa", "abcdefg"));
cosmosDBContext.SaveChanges(true);
_logger = logger;
}
public IActionResult Index()
{
var result = _myResolver.Resolve("aaa");
return Ok(JsonConvert.SerializeObject(result));
}
输出:
我正在使用 ASP.NET Core 2.2、GraphQL.NET、CosmosDB、EntityFrameworkCore (Microsoft.EntityFrameworkCore.Cosmos(2.2.4).
关于运行的解决方案,我看到一个错误:
Cannot resolve 'GraphQL.Resolvers.ICountriesResolver' from root provider because it requires scoped service 'Query.Persistence.SampleDbContext'.
这是我的代码详情:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
string serviceEndPoint = this.Configuration.GetValue<string>("CosmosDBEndpoint");
string authKeyOrResourceToken = this.Configuration.GetValue<string>("CosmosDBAccessKey");
string databaseName = this.Configuration.GetValue<string>("CosmosDBName");
services.AddEntityFrameworkCosmos();
services.AddDbContext<SampleDbContext>(options => options.UseCosmos(serviceEndPoint, authKeyOrResourceToken, databaseName, contextOptions =>
{
contextOptions.ExecutionStrategy(d => new CosmosExecutionStrategy(d));
}
));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
services.AddSingleton<IUtilityService, UtilityService>();
services.AddTransient<ICommonService, CommonService>();
services.AddTransient<ICountryService, CountryService>();
services.AddSingleton<CountryResultType>();
services.AddSingleton<GraphQLQuery>();
services.AddTransient<ICountriesResolver, CountriesResolver>();
services.AddSingleton<CountryType>();
services.AddSingleton<Response>();
services.AddScoped(typeof(ResponseGraphType<>));
services.AddScoped(typeof(ResponseListGraphType<>));
services.AddSingleton<IDataLoaderContextAccessor, DataLoaderContextAccessor>();
services.AddSingleton<DataLoaderDocumentListener>();
services.AddTransient<IAddressRepository, AddressRepository>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);
services.AddSingleton<SampleSchema>();
var sp = services.BuildServiceProvider();
services.AddSingleton<ISchema>(new SampleSchema(new FuncDependencyResolver(type => sp.GetService(type))));
}
CountriesResolver.cs
public class CountriesResolver : Resolver, ICountriesResolver
{
private readonly ICountryService _countryService;
private readonly IHttpContextAccessor _accessor;
private readonly IUtilityService _utilityService;
public CountriesResolver(ICountryService countryService, IHttpContextAccessor accessor, IUtilityService utilityService)
{
_countryService = countryService;
_accessor = accessor;
_utilityService = utilityService;
}
public void Resolve(GraphQLQuery graphQLQuery)
{
graphQLQuery.Field<ResponseGraphType<CountryResultType>>("countriesresponse", resolve: context =>
{
var locale = _utilityService.GetLocale(_accessor.HttpContext.Request.Headers);
var list = _countryService.GetAllCountries(locale);
return Response(list);
}
, description: "All Countries data");
}
}
CountryService.cs
public class CountryService : ICountryService
{
private readonly SampleDbContext _dbContext;
private readonly ICommonService _commonService;
private readonly IOptions<AppSettings> _appSettings;
public CountryService(SampleDbContext dbContext, ICommonService commonService, IOptions<AppSettings> appSettings)
{
_dbContext = dbContext;
_commonService = commonService;
_appSettings = appSettings;
}
public async Task<CountryResult> GetAllCountries(string locale)
{
var result = new CountryResult();
var language = _commonService.GetLanguageFromLocale(locale);
var localeLangId = language.LanguageId;
var dftLanguageId = int.Parse(_appSettings.Value.DefaultLanguageId);
var dftDisplayName = await _dbContext.Countries.Where(cc => cc.IsPublished.Equals(true) && cc.LanguageId.Equals(dftLanguageId)).Select(df => df.DisplayNameShort).FirstOrDefaultAsync();
var countries = await (_dbContext.Countries.Where(cc => cc.IsPublished.Equals(true) && cc.LanguageId.Equals(localeLangId)).Join(_dbContext.Disclaimers.Where(dc => dc.LanguageId.Equals(localeLangId)), c => c.CountryId, d => d.DefaultCountryId, (c, d) => new CountryDTO{Uuid = c.CountryId, DisplayName = c.DisplayName ?? dftDisplayName, DisplayNameShort = c.DisplayName ?? dftDisplayName, ProviderName = d.ProviderName, ProviderTerms = d.ProviderTerms, Name = dftDisplayName, Path = dftDisplayName, CompleteResponse = true}).ToListAsync());
result.Countries = countries;
return result;
}
}
GraphQLQuery.cs
public class GraphQLQuery : ObjectGraphType
{
public GraphQLQuery(IServiceProvider serviceProvider)
{
var type = typeof(IResolver);
var resolversTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes()).Where(p => type.IsAssignableFrom(p));
foreach (var resolverType in resolversTypes)
{
var resolverTypeInterface = resolverType.GetInterfaces().Where(x => x != type).FirstOrDefault();
if (resolverTypeInterface != null)
{
var resolver = serviceProvider.GetService(resolverTypeInterface) as IResolver;
resolver.Resolve(this);
}
}
}
}
谁能帮我解决这个问题?
我快速创建了一个演示 .net core 3.0 web 应用程序,并按照您上面的方式进行了测试。然而,我这边一切都很好。
CountriesResolver 和 CountryService classes 看起来不错。但是您没有 post 您的 SampleDbContext class。你可以检查一下。
这是我的代码片段:
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<CosmosDBContext>(options => options.UseCosmos(
"https://jackcosmos.documents.azure.com:443/",
"Y1tiY********lJurBg==",
"DB"
));
services.AddTransient<IMyService, MyService>();
services.AddTransient<IMyResolver, MyResolver>();
}
CosmosDBContext.cs
为方便起见,我刚刚使用 Cosmos DB SQL API 进行了测试。但是,它不应该影响 DI:
public class CosmosDBContext : DbContext
{
public CosmosDBContext(DbContextOptions<CosmosDBContext> options) : base(options)
{
}
public DbSet<Item> Items { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultContainer("Item");
}
}
public class Item
{
public Item(string key, string content) => (this.key, this.content) = (key, content);
public string id { get; set; } = Guid.NewGuid().ToString();
public string key { get; set; }
public string content { get; set; }
}
MyService.cs
public class MyService : IMyService
{
private CosmosDBContext _cosmosDbContext;
public MyService(CosmosDBContext cosmosDBContext)
{
_cosmosDbContext = cosmosDBContext;
}
public List<Item> GetByKey(string key)
{
return _cosmosDbContext.Items.Where(i => i.key.Equals(key)).ToList();
}
}
MyResolver.cs
public class MyResolver : IMyResolver
{
private IMyService _myService;
public MyResolver(IMyService myService)
{
_myService = myService;
}
public List<Item> Resolve(string key)
{
return _myService.GetByKey(key);
}
}
在我的 HomeController 中,我只是:
private IMyResolver _myResolver;
public HomeController(ILogger<HomeController> logger, CosmosDBContext cosmosDBContext, IMyResolver myResolver)
{
_myResolver = myResolver;
// Add one
cosmosDBContext.Database.EnsureCreated();
cosmosDBContext.Items.Add(new Item("aaa", "abcdefg"));
cosmosDBContext.SaveChanges(true);
_logger = logger;
}
public IActionResult Index()
{
var result = _myResolver.Resolve("aaa");
return Ok(JsonConvert.SerializeObject(result));
}
输出: