ASP.NET Core 中通用存储库和特定服务的依赖注入问题

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

我正在开发一个 ASP.NET Core 项目,在该项目中我使用通用存储库模式和特定服务。我已经实现了以下接口和类:

共享接口:

namespace OPEG.Shared.Contracts
{
    public interface IEntity
    {
        int Id { get; set; }
    }

    public interface IEntityBaseRepository<T> where T : class, IEntity
    {
        Task<List<T>> GetAllAsync();
        Task<List<T>> GetAllAsync(params Expression<Func<T, object>>[] includeProperties);
        Task<T> GetByIdAsync(int id);
        Task AddAsync(T entity);
        Task AddRangeAsync(List<T> entities);
        Task UpdateAsync(int id, T entity);
        Task DeleteAsync(int id);
        Task DeleteRangeAsync(List<T> entities);
    }

    public interface IGradeService : IEntityBaseRepository<Grade>
    {
        Task<List<Subject>> GetAllSubjectsById(int id);
    }
}

API项目实施

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using OPEG.Shared.Contracts;
using System.Linq.Expressions;

namespace OPEG.Api.Services
{
    public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntity
    {
        private readonly OPEGContext _context;

        public EntityBaseRepository(OPEGContext context)
        {
            _context = context;
        }

        public async Task AddAsync(T entity)
        {
            await _context.Set<T>().AddAsync(entity);
            await _context.SaveChangesAsync();
        }

        public async Task<List<T>> GetAllAsync()
        {
            return await _context.Set<T>().ToListAsync();
        }

        public async Task<List<T>> GetAllAsync(params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> query = _context.Set<T>();
            query = includeProperties.Aggregate(query, (current, includeProp) => current.Include(includeProp));
            return await query.ToListAsync();
        }

        public async Task<T> GetByIdAsync(int id)
        {
            return await _context.Set<T>().FirstOrDefaultAsync(e => e.Id == id);
        }

        public async Task UpdateAsync(int id, T entity)
        {
            EntityEntry entityEntry = _context.Entry(entity);
            entityEntry.State = EntityState.Modified;
            await _context.SaveChangesAsync();
        }

        public async Task DeleteAsync(int id)
        {
            var entity = await _context.Set<T>().FirstOrDefaultAsync(e => e.Id == id);
            if (entity != null)
            {
                EntityEntry entityEntry = _context.Entry(entity);
                entityEntry.State = EntityState.Deleted;
                await _context.SaveChangesAsync();
            }
        }

        public async Task AddRangeAsync(List<T> entities)
        {
            await _context.Set<T>().AddRangeAsync(entities);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteRangeAsync(List<T> entities)
        {
            _context.Set<T>().RemoveRange(entities);
            await _context.SaveChangesAsync();
        }
    }

    public class GradeService : EntityBaseRepository<Grade>, IGradeService
    {
        private readonly OPEGContext _context;

        public GradeService(OPEGContext context) : base(context)
        {
            _context = context;
        }

        public async Task<List<Subject>> GetAllSubjectsById(int id)
        {
            return await _context.Subjects.Where(s => s.GradeId == id).ToListAsync();
        }
    }
}

Program.cs 中的 DI 注册:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<OPEGContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Generic repository registration
builder.Services.AddScoped(typeof(IEntityBaseRepository<>), typeof(EntityBaseRepository<>));

// Specific service registration
builder.Services.AddScoped<IGradeService, GradeService>();

var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

我在我的项目中使用 dotnet 8 框架、entityframeworkcore.sqlserver 和 entityframeworkcore.design 版本 9.0.0(最新)

问题: 当我运行项目时,在DI注册过程中遇到以下错误:

错误:

1.CS0738“GradeService”未实现接口成员“IGradeService.GetAllSubjectsById(int)”。 “GradeService.GetAllSubjectsById(int)”无法实现“IGradeService.GetAllSubjectsById(int)”,因为它没有匹配的“Task”返回类型。

2.CS0535“GradeService”未实现接口成员“IEntityBaseRepository.GetAllAsync(params Expression>[])”

我尝试过的: 已验证 IGradeService 在 GradeService 中正确实现。 确保使用正确的命名空间。 多次重建解决方案。 在 DI 容器中注册通用存储库和特定服务。 我需要什么帮助: 为什么在使用 DI 容器注册 GradeService 时会收到此 CS0535 和 CS0738 错误? 我的继承和接口实现方法对于 IEntityBaseRepository 和 IGradeService 是否正确? 如何在维护通用存储库模式的同时解决此 DI 问题?

c# dependency-injection repository-pattern
1个回答
0
投票

修改

IGradeService.cs
GetAllSubjectsById 为
IEntityBaseRepository<Grade>

继承
public interface IGradeService : IEntityBaseRepository<Grade>
{
    Task<List<Subject>> GetAllSubjectsById(int id);
}

并在

GradeService.cs
实施中:

public class GradeService : EntityBaseRepository<Grade>, IGradeService
{
    private readonly OPEGContext _context;

    public GradeService(OPEGContext context) : base(context)
    {
        _context = context;
    }

    public async Task<List<Subject>> GetAllSubjectsById(int id)
    {
        return await _context.Subjects.Where(s => s.GradeId == id).ToListAsync();
    }

}

确保

EntityBaseRepository
使用适合其界面的正确约束。

public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntity
{
    private readonly OPEGContext _context;

    public EntityBaseRepository(OPEGContext context)
    {
        _context = context;
    }

    public async Task AddAsync(T entity)
    {
        await _context.Set<T>().AddAsync(entity);
        await _context.SaveChangesAsync();
    }

    public async Task<List<T>> GetAllAsync()
    {
        return await _context.Set<T>().ToListAsync();
    }

    public async Task<List<T>> GetAllAsync(params Expression<Func<T, object>>[] includeProperties)
    {
        IQueryable<T> query = _context.Set<T>();
        query = includeProperties.Aggregate(query, (current, includeProp) => current.Include(includeProp));
        return await query.ToListAsync();
    }

    public async Task<T> GetByIdAsync(int id)
    {
        return await _context.Set<T>().FirstOrDefaultAsync(e => e.Id == id);
    }

    public async Task UpdateAsync(int id, T entity)
    {
        EntityEntry entityEntry = _context.Entry(entity);
        entityEntry.State = EntityState.Modified;
        await _context.SaveChangesAsync();
    }

    public async Task DeleteAsync(int id)
    {
        var entity = await _context.Set<T>().FirstOrDefaultAsync(e => e.Id == id);
        if (entity != null)
        {
            EntityEntry entityEntry = _context.Entry(entity);
            entityEntry.State = EntityState.Deleted;
            await _context.SaveChangesAsync();
        }
    }

    public async Task AddRangeAsync(List<T> entities)
    {
        await _context.Set<T>().AddRangeAsync(entities);
        await _context.SaveChangesAsync();
    }

    public async Task DeleteRangeAsync(List<T> entities)
    {
        _context.Set<T>().RemoveRange(entities);
        await _context.SaveChangesAsync();
    }
}

最后在 Program.cs 中注册依赖项,如下所示:

builder.Services.AddScoped(typeof(IEntityBaseRepository<>), typeof(EntityBaseRepository<>));
builder.Services.AddScoped<IGradeService, GradeService>();

上述内容将帮助您解决错误 CS0738 和 CS0535 错误中提到的问题,并拥有干净的通用存储库模式。

© www.soinside.com 2019 - 2024. All rights reserved.