0

我正在使用 ASP.NET Core 2.2、GraphQL.NET、CosmosDB、EntityFrameworkCore (Microsoft.EntityFrameworkCore.Cosmos(2.2.4) 进行 API 开发项目。

在运行解决方案时,我看到一个错误:

无法从根提供程序解析“GraphQL.Resolvers.ICountriesResolver”,因为它需要范围服务“Query.Persistence.SampleDbContext”。

这是我的代码详细信息:

启动.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))));
} 

CountryResolver.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);
            }
        }
    }
}

谁能帮我解决这个问题?

4

1 回答 1

1

我快速创建了一个演示 .net core 3.0 Web 应用程序,并按照上面的说明进行了测试。然而,在我身边一切都很好。

CountryResolver 和 CountryService 类看起来不错。但是您没有发布您的 SampleDbContext 类。你可以检查一下。

这是我的代码片段:

启动.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; }
}

我的服务.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));
}

输出:

在此处输入图像描述

于 2019-10-21T09:40:02.317 回答