[英]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.