繁体   English   中英

AspNetCore - 无法解析类型 X 的服务

[英]AspNetCore - Unable to resolve service for type X

启动我的 Asp.Net Core Mvc web 应用程序时出现此错误:

“某些服务无法构建(验证服务描述符时出错'ServiceType: Vepo.Application.IAddVeganItemToAppUseCase Lifetime: Transient ImplementationType: Vepo.Application.AddVeganItemToAppUseCase': Unable to resolve service for type 'Vepo.Data.GroceryItemGroceryStoresRepository' while试图激活“Vepo.Application.AddVeganItemToAppUseCase”。)”

所以看起来这部分是罪犯:

无法解析“Vepo.Data.GroceryItemGroceryStoresRepository”类型的服务。

在我的 Startup.cs 我有这个:

services.AddScoped(typeof(IGroceryItemGroceryStoresRepository), typeof(GroceryItemGroceryStoresRepository));
services.AddTransient<IAddVeganItemToAppUseCase, AddVeganItemToAppUseCase>(); 

有什么问题吗?

以下是所有相关代码:

IRepository.cs

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace Vepo.Data
{
    public interface IRepository<EntityType, IdType>
    {
        Task<EntityType> Save(EntityType entity);
        EntityType Fetch(IdType id);
        IEnumerable<EntityType> FetchAll();
        bool EntityExists(IdType id);
    }
}

ARepository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Vepo.Common.Utilities;
using Vepo.DataContext;
using Vepo.Domain;

namespace Vepo.Data
{
    [Serializable]
    public abstract class ARepository<EntityType, IdType> : IRepository<EntityType, IdType> where EntityType : ADomainEntity<IdType>
    {
        protected readonly VepoContext context;
        protected DbSet<EntityType> entities;
        protected string errorMessage = string.Empty;
        public ARepository(VepoContext context)
        {
            this.context = context;
            entities = context.Set<EntityType>();
        }

        public bool Compare<T>(T x, T y)
        {
            return EqualityComparer<T>.Default.Equals(x, y);
        }

        public virtual async Task<EntityType> Save(EntityType entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            if (NumberUtilities.IsNumber(entity.Id))
            {
                if (Convert.ToInt32(entity.Id) > 0)
                {
                    await context.SaveChangesAsync();
                } else {
                    await entities.AddAsync(entity);
                    await context.SaveChangesAsync();
                }
            }
            return entity;
        }

        public EntityType Fetch(IdType id)
        {
            return entities.SingleOrDefault(s => Compare<IdType>(s.Id, id));
        }

        public IEnumerable<EntityType> FetchAll()
        {
            return entities.AsEnumerable();
        }

        public void Delete(EntityType entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Remove(entity);
            context.SaveChanges();
        }
        public void Remove(EntityType entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            entities.Remove(entity);
        }

        public void SaveChanges()
        {
            context.SaveChanges();
        }

        public virtual bool EntityExists(IdType id)
        {
            return entities.Any(e => Compare<IdType>(e.Id, id));
        }
    }
}

IGroceryItemGroceryStoresRepository.cs:

using Vepo.Domain;

    namespace Vepo.Data
    {
        public interface IGroceryItemGroceryStoresRepository : IRepository<GroceryItemGroceryStore, int>
        {
            
        }
    }

GroceryItemGroceryStoresRepository.cs

using System;
using Microsoft.EntityFrameworkCore;
using Vepo.DataContext;
using Vepo.Domain;
using System.Linq;
using System.Threading.Tasks;

namespace Vepo.Data
{
    public class GroceryItemGroceryStoresRepository : ARepository<GroceryItemGroceryStore, int>, IGroceryItemGroceryStoresRepository
    {
        public GroceryItemGroceryStoresRepository(VepoContext context) : base(context)
        {
        }

        public override bool EntityExists(int id)
        {
            return context.GroceryItemGroceryStores.Any(e => e.VeganItemId == id);
        }

        public async override Task<GroceryItemGroceryStore> Save(GroceryItemGroceryStore entity)
        {
            ++entity.VeganItem.CurrentRevisionId;

            var toReturnVeganItem = entity.VeganItem;
            var toReturnEstablishment = entity.Establishment;
            
            context.GroceryItems.Add(entity.VeganItem);
            context.SaveChanges();
            
            context.Set<GroceryStore>().AddIfNotExists(entity.Establishment , x => x.PlaceId == entity.Establishment.PlaceId);
            context.SaveChanges();

            var establishmentId = context.GroceryStores.Single(a => a.PlaceId == entity.Establishment.PlaceId).Id;
            var veganItemId = context.GroceryItems.Single(a => a.Brand == entity.VeganItem.Brand && a.Name == entity.VeganItem.Name).Id;
            
            toReturnEstablishment.Id = establishmentId;
            toReturnVeganItem.Id = veganItemId;
            entity.VeganItemId = veganItemId;
            entity.EstablishmentId = establishmentId;
            
            entity.VeganItem = null;
            entity.Establishment = null;

            context.Set<GroceryItemGroceryStore>().AddIfNotExists(entity , x => x.VeganItemId == veganItemId && x.EstablishmentId == establishmentId);
            
            try
            {
                await context.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (EntityExists(entity.VeganItemId))
                {
                    throw;
                }
                else
                {
                    throw;
                }
            }

            entity.VeganItem = toReturnVeganItem;

            entity.Establishment = toReturnEstablishment;
            return entity;
        }
    }
}

IAddVeganItemToAppUseCase.cs

using System.Threading.Tasks;
using Vepo.Domain;

namespace Vepo.Application
{
    public interface IAddVeganItemToAppUseCase
    {
        Task<GroceryItemGroceryStore> Invoke(GroceryItemGroceryStore entity);
    }
}

AddVeganItemToAppUseCase.cs

using System.Threading.Tasks;
using Vepo.Data;
using Vepo.Domain;

namespace Vepo.Application
{
    public class AddVeganItemToAppUseCase : IAddVeganItemToAppUseCase
    {
        private GroceryItemGroceryStoresRepository repository;

        public AddVeganItemToAppUseCase(GroceryItemGroceryStoresRepository repository)
        {
            this.repository = repository;
        }

        public Task<GroceryItemGroceryStore> Invoke(GroceryItemGroceryStore entity)
        {
            return repository.Save(entity);
        }
    }
}

启动.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.EntityFrameworkCore;
using System.Text.Json.Serialization;
using Vepo.Domain;
using Vepo.DataContext;
using System;
using Vepo.Data;
using Vepo.Application;

namespace Vepo.Web
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services
            .AddDbContext<VepoContext>(opt =>
                opt
                .UseNpgsql(
                    Configuration
                    .GetConnectionString("DefaultConnection"))
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors()
                    .LogTo(Console.WriteLine));
            services.AddControllers().AddJsonOptions(opt =>
            {
                opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            });

            services.AddControllers().AddNewtonsoftJson(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

            services.AddMvc().AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve;
            });

            services.AddScoped(typeof(IGroceryItemGroceryStoresRepository), typeof(GroceryItemGroceryStoresRepository));
            services.AddTransient<IAddVeganItemToAppUseCase, AddVeganItemToAppUseCase>(); 
            services.AddSwaggerGen();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My Test1 Api v1");
            });
        }
    }
}

您将IGroceryItemGroceryStoresRepository注册为GroceryItemGroceryStoresRepository类型的接口,但是您在GroceryItemGroceryStoresRepository的构造函数中注入了AddVeganItemToAppUseCase 将 AddVeganItemToAppUseCase 的构造函数中注入的AddVeganItemToAppUseCase从具体类型更改为相应的接口注册,它应该可以工作。

public class AddVeganItemToAppUseCase : IAddVeganItemToAppUseCase
{
    private IGroceryItemGroceryStoresRepository repository;

    public AddVeganItemToAppUseCase(IGroceryItemGroceryStoresRepository repository)
    {
        this.repository = repository;
    }

    public Task<GroceryItemGroceryStore> Invoke(GroceryItemGroceryStore entity)
    {
        return repository.Save(entity);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM