ASP.NET Core 8.0 MVC中如何在仓储中使用DbContext实现依赖注入
解决方案
你的核心问题在于手动实例化仓储类时没有传递构造参数,且当前的静态工厂模式没有利用ASP.NET Core的依赖注入(DI)容器来自动解析依赖。以下是具体的修复步骤:
1. 完善仓储类的构造函数
因为UserRepository继承自DbRepo,必须显式调用父类构造函数并传入AppDbContext:
public class UserRepository : DbRepo, IUser<User, User, string> { // 显式传递DbContext给父类 public UserRepository(AppDbContext context) : base(context) { } public async Task<bool> Create(User user) { try { if (!await IsExist(user)) { await db.AddAsync(user); } return db.SaveChanges() > 0; } catch (Exception) { return false; } } // 补充你原代码中调用的IsExist方法示例 private async Task<bool> IsExist(User user) { return await db.Users.AnyAsync(u => u.Id == user.Id); } }
2. 在DI容器中注册所有依赖
在Program.cs中注册AppDbContext、仓储接口与实现、业务服务:
// 注册数据库上下文(确保已配置连接字符串) builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 注册仓储接口与实现 builder.Services.AddScoped<IUser<User, User, string>, UserRepository>(); // 注册业务服务(替换静态类为实例类) builder.Services.AddScoped<UserService>();
3. 改造业务服务与工厂(二选一)
方案一:移除静态工厂,直接注入仓储
这是更符合ASP.NET Core DI设计的方式,无需保留DataAccessFactory:
public class UserService { private readonly IUser<User, User, string> _userRepo; // 通过构造函数注入仓储 public UserService(IUser<User, User, string> userRepo) { _userRepo = userRepo; } public async Task<bool> CreateUser(UserDTO newUser) { User user = UserMapping(newUser); return await _userRepo.Create(user); } // 补充DTO到实体的映射方法 private User UserMapping(UserDTO dto) { return new User { // 示例映射逻辑,根据你的实际字段调整 Id = dto.Id, Name = dto.Name }; } }
方案二:改造工厂以支持DI(若需保留工厂)
如果必须保留DataAccessFactory,需将其改为实例类并注入服务提供者:
public class DataAccessFactory { private readonly IServiceProvider _serviceProvider; public DataAccessFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IUser<User, User, string> UserData() { return _serviceProvider.GetRequiredService<IUser<User, User, string>>(); } }
同时在Program.cs注册工厂:
builder.Services.AddScoped<DataAccessFactory>();
然后改造UserService注入工厂:
public class UserService { private readonly DataAccessFactory _factory; public UserService(DataAccessFactory factory) { _factory = factory; } public async Task<bool> CreateUser(UserDTO newUser) { User user = UserMapping(newUser); return await _factory.UserData().Create(user); } private User UserMapping(UserDTO dto) { // 映射逻辑 } }
4. 控制器中注入业务服务
在控制器中通过构造函数注入UserService,调用其方法:
public class UserController : Controller { private readonly UserService _userService; public UserController(UserService userService) { _userService = userService; } [HttpPost] public async Task<IActionResult> Create(UserDTO dto) { bool result = await _userService.CreateUser(dto); // 根据结果返回对应视图或状态 return result ? RedirectToAction("Index") : View(dto); } }
关键要点
- 避免手动
new依赖类,所有依赖通过DI容器解析 - 静态类/方法不利于DI注入,建议改用实例类
- 仓储类必须显式实现构造函数,传递父类所需的
AppDbContext
内容的提问来源于stack exchange,提问作者Reyad
相关产品推荐
相关产品推荐

