首页 > 解决方案 > 具有通用服务和存储库代码的 .NET Core 依赖注入错误

问题描述

我正在尝试将我在所有项目中在 .NET 框架中使用的通用代码模板移动到 .NET Core,并且在 .NET Core 中的依赖注入时遇到了一些问题。

这是我的代码:

API 控制器:

[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
    private readonly IProductService _productService;

    public ProductController(IProductService productService)
    {
        _productService = productService;
    }

    [HttpGet]
    public IActionResult GetAll()
    {
        var products = _productService.GetAll();

        return Ok(products);
    }
}

产品服务:

public class ProductService : ServiceBase<Product, BaseRepository<Product>>, IProductService
{
    public ProductService(BaseRepository<Product> rep) : base(rep)
    {
    }
}

产品服务:

public interface IProductService : IServiceBase<Product>
{
}

服务基础:

public interface IServiceBase<TEntity>
{
    IEnumerable<TEntity> GetAll();
}

服务基地:

public abstract class ServiceBase<TEntity, TRepository> : IServiceBase<TEntity>
        where TEntity : class
        where TRepository : BaseRepository<TEntity>
{
    public TRepository Repository;

    public ServiceBase(BaseRepository<TEntity> rep)
    {
        Repository = (TRepository)rep;
    }

    public IEnumerable<TEntity> GetAll()
    {
        return Repository.GetAll();
    }
}

基础存储库:

public class BaseRepository<T> : IBaseRepository<T> where T : class
{
    private readonly DatabaseContext _dbContext;

    public BaseRepository(DatabaseContext dbContext)
    {
        _dbContext = dbContext;
    }

    public IEnumerable<T> GetAll()
    {
        return _dbContext.Set<T>();
    }
}

IBase 存储库:

public interface IBaseRepository<T> where T : class
{
    IEnumerable<T> GetAll();
}

数据库上下文:

public class DatabaseContext : DbContext
{
    public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
    {
    }

    public DbSet<Product> Products { get; set; }
}

启动文件:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DatabaseContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
            x => x.MigrationsAssembly("AdministrationPortal.Data")));

        services.AddTransient<IProductService, ProductService>();

        services.AddControllers();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

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

当我尝试使用 F5(或绿色播放按钮)启动 API 项目时出现错误:

System.AggregateException:“无法构造某些服务(验证服务描述符时出错“ServiceType:AdministrationPortal.Interfaces.Services.IProductService Lifetime:Transient ImplementationType:AdministrationPortal.Core.Services.ProductService”:无法解析服务类型'AdministrationPortal.Repositories.Repositories.BaseRepository`1[AdministrationPortal.Domain.Entities.Product]' 同时尝试激活'AdministrationPortal.Core.Services.ProductService'。)'

任何帮助表示赞赏!

标签: c#.netentity-framework.net-core

解决方案


您的ProductService班级正在尝试解决 的依赖关系BaseRepository<Product>,但您尚未在服务提供者中注册它。在您的Startup课程中,您可以简单地注册该类型,它应该可以工作:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<DatabaseContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
        x => x.MigrationsAssembly("AdministrationPortal.Data")));

    services.AddTransient<IProductService, ProductService>();
    services.AddTransient<BaseRepository<Product>>(); // <----- This is needed

    services.AddControllers();
}

或者,您可以将 注册BaseRepository<>为一个开放的泛型,它将使用它给出的任何类型来解析:

services.AddTransient(typeof(BaseRepository<>));

推荐阅读