无法使用以下库来构建某些服务:NetCore.AutoRegisterDi

问题描述 投票:-1回答:1

我正在开发基于asp.net核心3.1 GraphQL的API。我使用下面的参考文章在API层中设置了自动DI配置,并使用了nuget包:NetCore.AutoRegisterDi

https://www.thereformedprogrammer.net/asp-net-core-fast-and-automatic-dependency-injection-setup/

这里有代码详细信息:

代码:

Startup.cs:

public virtual void ConfigureServices(IServiceCollection services) => services
                      .AddGraphQLResolvers()
                      .AddProjectRepositories();

ProjectServiceCollectionExtensions.cs

public static class ProjectServiceCollectionExtensions
{
    public static IServiceCollection AddProjectRepositories(this IServiceCollection services) => 
        services.RegisterAssemblyPublicNonGenericClasses(Assembly.GetAssembly(typeof(CommonService)))
                .Where(c => c.Name.EndsWith("Persistence"))
                .AsPublicImplementedInterfaces(ServiceLifetime.Scoped);

    public static IServiceCollection AddGraphQLResolvers(this IServiceCollection services) =>
       services
           .AddScoped<ICountriesResolver, CountriesResolver>()
           .AddScoped<ICountryGroupsResolver, CountryGroupsResolver>()
           .AddScoped<IDisclaimerResolver, DisclaimerResolver>();
}

上面的CommonService中是服务层的一部分,以持久性结尾。

CountriesResolver.cs

public class CountriesResolver : Resolver, ICountriesResolver
{
    private readonly ICountryService _countryService;
    private readonly IHttpContextAccessor _accessor;
    private readonly IDataLoaderContextAccessor _dataLoaderContextAccessor;
    public CountriesResolver(ICountryService countryService, IHttpContextAccessor accessor, IDataLoaderContextAccessor dataLoaderContextAccessor)
    {
        _countryService = countryService ?? throw new ArgumentNullException(nameof(countryService));
        _accessor = accessor;
        _dataLoaderContextAccessor = dataLoaderContextAccessor;
    }

    public void Resolve(GraphQLQuery graphQLQuery)
    {
        var language = _accessor.HttpContext.Items["language"] as LanguageDTO;
        graphQLQuery.FieldAsync<ResponseGraphType<CountryResultType>>("countriesresponse", arguments: new QueryArguments(new QueryArgument<IdGraphType>{Name = "pageNo", Description = "page number"}, new QueryArgument<IdGraphType>{Name = "pageSize", Description = "page size"}), resolve: async context =>
        {
            var pageNo = context.GetArgument<int>("pageNo") == 0 ? 1 : context.GetArgument<int>("pageNo");
            var pageSize = context.GetArgument<int>("pageSize") == 0 ? 100 : context.GetArgument<int>("pageSize");
            if (language != null)
            {
                var loader = _dataLoaderContextAccessor.Context.GetOrAddLoader("GetAllCountries", () => _countryService.GetAllCountriesAsync(language, pageNo, pageSize));
                var list = await context.TryAsyncResolve(async c => await loader.LoadAsync());
                return Response(list);
            }

            return null;
        }

        , description: "All Countries data");
    }
}

ICommonService.cs

using Author.Query.Persistence.DTO;
using System.Threading.Tasks;

namespace Author.Query.Persistence.Interfaces
{
    public interface ICommonService
    {
        LanguageDTO GetLanguageFromLocale(string locale);
        Task<LanguageDTO> GetLanguageFromLocaleAsync(string locale);
    }
}

CommonService.cs

namespace Author.Query.Persistence
{
    public class CommonService : ICommonService
    {
        private readonly AppDbContext _dbContext;
        private readonly IOptions<AppSettings> _appSettings;
        private readonly IMapper _mapper;
        private readonly ICacheService<Languages, LanguageDTO> _cacheService;
        public CommonService(AppDbContext dbContext, IOptions<AppSettings> appSettings, IMapper mapper, ICacheService<Languages, LanguageDTO> cacheService)
        {
            _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
            _appSettings = appSettings;
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
            _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService));
        }

        //public Languages GetLanguageFromLocale(string locale)
        public LanguageDTO GetLanguageFromLocale(string locale)
        {
            return GetLanguagesByFilter(GetFilterValues(locale, true).ToArray());
        }
    }
}

ICountryService.cs

namespace Author.Query.Persistence.Interfaces
{
    public interface ICountryService
    {
        Task<CountryResult> GetAllCountriesAsync(LanguageDTO language, int pageNo, int pageSize);
        Task<CountryDTO> GetCountryAsync(LanguageDTO language, int countryId);
    }
}

CountryService.cs

namespace Author.Query.Persistence
{
    public class CountryService : ICountryService
    {
        private readonly AppDbContext _dbContext;
        private readonly IOptions<AppSettings> _appSettings;
        private readonly ICacheService<Images, ImageDTO> _cacheService;
        public CountryService(TaxathandDbContext dbContext, IOptions<AppSettings> appSettings, ICacheService<Images, ImageDTO> cacheService)
        {
            _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
            _cacheService = cacheService ?? throw new ArgumentNullException(nameof(cacheService));
            _appSettings = appSettings;
        }

        public async Task<CountryResult> GetAllCountriesAsync(LanguageDTO language, int pageNo, int pageSize)
        {
            var localeLangId = language.LanguageId;
            var dftLanguageId = int.Parse(_appSettings.Value.DefaultLanguageId);
            // By default pick the localLanguage value
            var countries = await GetAllCountriesDataAsync(localeLangId, pageNo, pageSize);
            // If localLanguage data is not available then pull the data based on default language
            if (countries.Countries.Count == 0)
            {
                countries = await GetAllCountriesDataAsync(dftLanguageId, pageNo, pageSize);
            }

            return countries;
        }

        public async Task<CountryDTO> GetCountryAsync(LanguageDTO language, int countryId)
        {
            var localeLangId = language.LanguageId;
            var dftLanguageId = int.Parse(_appSettings.Value.DefaultLanguageId);
            //var country = new CountryDTO();
            // By default pick the localLanguage value
            var country = await GetCountryDetailsAsync(countryId, localeLangId);
            // If localLanguage data is not available then pull the data based on default language
            if (country == null)
            {
                country = await GetCountryDetailsAsync(countryId, dftLanguageId);
            }

            return country;
        }

        private async Task<CountryDTO> GetCountryDetailsAsync(int countryId, int languageId)
        {
            var images = await _cacheService.GetAllAsync("imagesCacheKey");
            var country = await _dbContext.Countries.AsNoTracking().FirstOrDefaultAsync(c => c.CountryId.Equals(countryId) && c.IsPublished.Equals(true) && c.LanguageId.Equals(languageId));
            if (country == null)
            {
                return null;
            }

            var countryDTO = new CountryDTO{Uuid = country.CountryId, PNGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(country.PNGImageId)).FilePath, SVGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(country.SVGImageId)).FilePath, DisplayName = country.DisplayName, DisplayNameShort = country.DisplayName, Name = Helper.ReplaceChars(country.DisplayName), Path = Helper.ReplaceChars(country.DisplayName), CompleteResponse = true};
            return countryDTO;
        }

        private async Task<CountryResult> GetAllCountriesDataAsync(int languageId, int pageNo, int pageSize)
        {
            var countryList = new CountryResult();
            var images = await _cacheService.GetAllAsync("imagesCacheKey");
            var countries = await _dbContext.Countries.Where(cc => cc.IsPublished.Equals(true) && cc.LanguageId.Equals(languageId)).Select(c => new
            {
            c.CountryId, c.DisplayName, c.PNGImageId, c.SVGImageId
            }

            ).OrderByDescending(c => c.CountryId).Skip((pageNo - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
            if (countries.Count == 0)
            {
                return null;
            }

            countryList.Countries.AddRange(countries.Select(co => new CountryDTO{Uuid = co.CountryId, PNGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.PNGImageId)).FilePath, SVGImagePath = images.FirstOrDefault(im => im.ImageId.Equals(co.SVGImageId)).FilePath, DisplayName = co.DisplayName, DisplayNameShort = co.DisplayName, Name = Helper.ReplaceChars(co.DisplayName), Path = Helper.ReplaceChars(co.DisplayName), CompleteResponse = true}));
            return countryList;
        }
    }
}

错误:

    System.AggregateException
      HResult=0x80131500
      Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Author.Query.New.API.GraphQL.Resolvers.ICountriesResolver Lifetime: Scoped ImplementationType: Author.Query.New.API.GraphQL.Resolvers.CountriesResolver': 
Unable to resolve service for type 'Author.Query.Persistence.Interfaces.ICountryService' while attempting to activate 'Author.Query.New.API.GraphQL.Resolvers.CountriesResolver'.) (Error while validating the service descriptor 'ServiceType: 
Author.Query.New.API.GraphQL.Resolvers.ICountryGroupsResolver Lifetime: Scoped ImplementationType: Author.Query.New.API.GraphQL.Resolvers.CountryGroupsResolver': Unable to resolve service for type 'Author.Query.Persistence.Interfaces.ICountryGroupService' while attempting to activate 'Author.Query.New.API.GraphQL.Resolvers.CountryGroupsResolver'.) (Error while validating the service descriptor 'ServiceType: Author.Query.New.API.GraphQL.Resolvers.IDisclaimerResolver Lifetime: Scoped ImplementationType: Author.Query.New.API.GraphQL.Resolvers.DisclaimerResolver': Unable to resolve service for type 'Author.Query.Persistence.Interfaces.IDisclaimerService' while attempting to activate 'Author.Query.New.API.GraphQL.Resolvers.DisclaimerResolver'.)
      Source=Microsoft.Extensions.DependencyInjection
      StackTrace:
       at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, ServiceProviderOptions options)
       at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
       at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
       at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
       at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
       at Microsoft.Extensions.Hosting.HostBuilder.Build()
       at Author.Query.New.API.Program.Main(String[] args) in /src/QueryStack/Author.Query.New.API/Program.cs:line 15

    Inner Exception 1:
    InvalidOperationException: Error while validating the service descriptor 'ServiceType: Author.Query.New.API.GraphQL.Resolvers.ICountriesResolver Lifetime: Scoped ImplementationType: 
Author.Query.New.API.GraphQL.Resolvers.CountriesResolver': 
Unable to resolve service for type 'Author.Query.Persistence.Interfaces.ICountryService' while attempting to activate 
'Author.Query.New.API.GraphQL.Resolvers.CountriesResolver'.

    Inner Exception 2:
    InvalidOperationException: Unable to resolve service for type 
'Author.Query.Persistence.Interfaces.ICountryService' while attempting to activate 
'Author.Query.New.API.GraphQL.Resolvers.CountriesResolver'.

谁能帮助我知道如何解决此问题?

dependency-injection c#-8.0 asp.net-core-3.1 graphql-dotnet netcore.autoregisterdi
1个回答
0
投票

错误表明:

无法解析类型的服务尝试激活时出现“ Author.Query.Persistence.Interfaces.ICountryService”'Author.Query.New.API.GraphQL.Resolvers.CountriesResolver'

ICountryService从未注册。 AddGraphQLResolvers仅注册ICountriesResolverICountryGroupsResolverIDisclaimerResolver

AddProjectRepositories方法仅注册名称​​以Persistence结尾的类,这些类出现在与CommonService相同的名称空间中。它从不注册CommonService本身。

必须注册服务,例如::>

services.AddScoped<ICommonService, CommonService>();
© www.soinside.com 2019 - 2024. All rights reserved.