You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型仓储模式CRUD服务优化与依赖注入整合咨询

优化泛型仓储服务并整合依赖注入

问题背景

我近期开发了一个采用泛型仓储模式实现CRUD操作的程序,目前只能通过静态类初始化服务,这种方式不够优雅。希望了解如何优化现有实现,并将其与依赖注入整合,替换当前的静态服务初始化方式。


现有代码实现

IBaseServices<T> 接口

namespace MyProject.DB.Services
{
    public interface IBaseServices<T>
    {
        Task CreateAsync(T entity);
        Task UpdateAsync(T entity);
        Task DeleteAsync(T entity);
        Task DeleteByIDAsync(int id);
        Task<T> GetByIDAsync(int id);
        Task<List<T>> GetAllAsync();
    }
}

BaseServices<T> 泛型基类

using Microsoft.EntityFrameworkCore; 
using MyProject.DB.Entitys;

namespace MyProject.DB.Services
{
    public class BaseServices<T> : IBaseServices<T> where T : BaseModel
    {
        private readonly DataContext _context;

        public BaseServices(DataContext context)
        {
            _context = context;
        }

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

        public async Task UpdateAsync(T entity)
        {
            T t = _context.Set<T>().Where(x => x.ID == entity.ID).First();

            if (t != null)
            {
                _context.Set<T>().Update(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task DeleteAsync(T entity)
        {
            T t = _context.Set<T>().Find(entity);

            if (t != null)
            {
                _context.Set<T>().Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task DeleteByIDAsync(int id)
        {
            T t = _context.Set<T>().Where(x => x.ID == id).First();

            if (t != null)
            {
                _context.Set<T>().Remove(t);
                await _context.SaveChangesAsync();
            }
        }

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

        public async Task<T> GetByIDAsync(int id)
        {
            return await _context.Set<T>().Where(x => x.ID == id).FirstOrDefaultAsync(); 
        }
    }
}

实体服务示例(以PriceServices为例)

using MyProject.DB.Entitys;

namespace MyProject.DB.Services
{
    public class PriceServices : BaseServices<Price> 
    {
        private readonly DataContext _context;

        public PriceServices(DataContext context) : base(context)
        {
            _context = context;
        }
    }
}

实体基类BaseModel

using System.ComponentModel.DataAnnotations;

namespace MyProject.DB.Entitys
{
    public class BaseModel
    {
        [Key]
        public int ID { get; set; }
    }
}

DataContext(待优化)

using Microsoft.EntityFrameworkCore;
using MyProject.DB.Entitys;

namespace MyProject.DB
{
    public class DataContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlServer(@"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=Vehicles;Integrated Security=True;");
        }

        public DbSet<Car> Cars { get; set; }
        public DbSet<Type> Types { get; set; }
        public DbSet<Price> Prices { get; set; }
    }
}

当前静态服务初始化方式

using MyProject.DB.Entitys;

namespace MyProject.DB.Services
{
    public static class MyServices
    {
        public static readonly DataContext context = new DataContext();
        public static readonly IBaseServices<Car> carServices = new CarServices(context);
        public static readonly IBaseServices<Type> typeServices = new TypeServices(context);
        public static readonly IBaseServices<Price> priceServices = new PriceServices(context);
    }
}

优化方案与依赖注入整合

1. 优化DataContext配置

把硬编码的连接字符串移到配置文件,通过构造函数注入DbContextOptions,符合DI规范:

修改DataContext

using Microsoft.EntityFrameworkCore;
using MyProject.DB.Entitys;

namespace MyProject.DB
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options)
        {
        }

        public DbSet<Car> Cars { get; set; }
        public DbSet<Type> Types { get; set; }
        public DbSet<Price> Prices { get; set; }
    }
}

在appsettings.json中添加连接字符串

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=Vehicles;Integrated Security=True;"
  }
}

2. 注册依赖注入服务

在项目启动类(如ASP.NET Core的Program.cs)中注册DataContext和泛型服务:

ASP.NET Core 6+ 注册方式

var builder = WebApplication.CreateBuilder(args);

// 注册DataContext
builder.Services.AddDbContext<DataContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// 注册泛型服务:两种方式可选
// 方式1:通用泛型注册,适用于无自定义逻辑的实体
builder.Services.AddScoped(typeof(IBaseServices<>), typeof(BaseServices<>));

// 方式2:针对有自定义逻辑的实体单独注册(会覆盖通用注册)
builder.Services.AddScoped<IBaseServices<Price>, PriceServices>();
builder.Services.AddScoped<IBaseServices<Car>, CarServices>();
builder.Services.AddScoped<IBaseServices<Type>, TypeServices>();

var app = builder.Build();

// ... 其他中间件配置

app.Run();

3. 优化BaseServices<T>实现

修复潜在问题,简化逻辑并提升性能:

using Microsoft.EntityFrameworkCore; 
using MyProject.DB.Entitys;

namespace MyProject.DB.Services
{
    public class BaseServices<T> : IBaseServices<T> where T : BaseModel
    {
        protected readonly DataContext _context;
        protected readonly DbSet<T> _dbSet;

        public BaseServices(DataContext context)
        {
            _context = context;
            _dbSet = context.Set<T>();
        }

        public async Task CreateAsync(T entity)
        {
            await _dbSet.AddAsync(entity);
            await _context.SaveChangesAsync();
        }

        public async Task UpdateAsync(T entity)
        {
            // 更安全的更新方式:查询后同步属性,避免覆盖未修改字段
            var existing = await _dbSet.FindAsync(entity.ID);
            if (existing != null)
            {
                _context.Entry(existing).CurrentValues.SetValues(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task DeleteAsync(T entity)
        {
            _dbSet.Remove(entity);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteByIDAsync(int id)
        {
            var entity = await _dbSet.FindAsync(id);
            if (entity != null)
            {
                _dbSet.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

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

        public async Task<T> GetByIDAsync(int id)
        {
            return await _dbSet.FindAsync(id);
        }
    }
}

4. 简化自定义实体服务

自定义服务无需重复声明_context,基类已处理:

using MyProject.DB.Entitys;

namespace MyProject.DB.Services
{
    public class PriceServices : BaseServices<Price> 
    {
        public PriceServices(DataContext context) : base(context)
        {
        }

        // 添加Price实体特有的业务方法
        public async Task<Price> GetLatestPriceAsync()
        {
            return await _dbSet.OrderByDescending(p => p.ID).FirstOrDefaultAsync();
        }
    }
}

5. 通过依赖注入使用服务

在控制器、业务类中通过构造函数注入服务:

控制器示例

using Microsoft.AspNetCore.Mvc;
using MyProject.DB.Entitys;
using MyProject.DB.Services;

namespace MyProject.Web.Controllers
{
    public class CarController : Controller
    {
        private readonly IBaseServices<Car> _carServices;

        public CarController(IBaseServices<Car> carServices)
        {
            _carServices = carServices;
        }

        public async Task<IActionResult> Index()
        {
            var cars = await _carServices.GetAllAsync();
            return View(cars);
        }
    }
}

业务类示例

using MyProject.DB.Entitys;
using MyProject.DB.Services;

namespace MyProject.Business
{
    public class CarBusinessService
    {
        private readonly IBaseServices<Car> _carServices;

        public CarBusinessService(IBaseServices<Car> carServices)
        {
            _carServices = carServices;
        }

        public async Task<List<Car>> GetActiveCarsAsync()
        {
            var allCars = await _carServices.GetAllAsync();
            return allCars.Where(c => c.IsActive).ToList();
        }
    }
}

6. 移除静态服务类

删除MyServices静态类,所有服务通过依赖注入获取,消除静态类带来的耦合性和测试障碍。


内容的提问来源于stack exchange,提问作者Silvers Raylie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:24:51