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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:50:04