I am working on API development project using ASP.NET Core 2.2, GraphQL.NET , CosmosDB, EntityFrameworkCore (Microsoft.EntityFrameworkCore.Cosmos(2.2.4).
On running the solution, I see an error :
Cannot resolve 'GraphQL.Resolvers.ICountriesResolver' from root provider because it requires scoped service 'Query.Persistence.SampleDbContext'.
Here goes my code details:
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);
}
}
}
}
Can anyone help me here to fix this issue?
I quickly created a demo .net core 3.0 web application, and tested as you showed above. However, everything was fine at my side.
The CountriesResolver and CountryService classes seem good. But you did not post your SampleDbContext class. You may have a check of it.
Here are my code snippets:
Startup.cs
CosmosDBContext.cs
For convenience, I just tested with Cosmos DB SQL API. But, it should not affect the DI:
MyService.cs
MyResolver.cs
And In my HomeController, I just:
The output: