泛型仓储模式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
相关产品推荐
相关产品推荐

