Невозможно разрешить GraphQL.Resolvers.ICountriesResolver от корневого поставщика, поскольку для этого требуется служба с областью действия Query.Persistence.SampleDbContext
Я работаю над проектом разработки API с использованием ASP.NET Core 2.2, GraphQL.NET, CosmosDB, EntityFrameworkCore (Microsoft.EntityFrameworkCore.Cosmos(2.2.4).
При запуске решения я вижу ошибку:
Невозможно разрешить GraphQL.Resolvers.ICountriesResolver от корневого поставщика, поскольку для этого требуется служба с областью действия 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))));
}
Страны Resolver.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);
}
}
}
}
Может ли кто-нибудь помочь мне решить эту проблему?
1 ответ
Я быстро создал демонстрационное веб-приложение.net core 3.0 и протестировал, как вы показали выше. Однако у меня все было хорошо.
Классы CountryResolver и CountryService кажутся хорошими. Но вы не разместили свой класс SampleDbContext. Вы можете проверить это.
Вот мои фрагменты кода:
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));
}
Выход: