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

ASP.NET Core 1.1仓储模式中“对象未引用实例”问题求助

解决ASP.NET Core 1.1查询型仓储的空引用异常(Object reference not set to an instance of an object)

嘿,我帮你定位到问题根源了!你遇到的空引用错误,完全是代码里静态成员的错误设计导致的,咱们一步步来修复:

问题核心分析

你的代码里有两个致命问题:

  1. 静态_context字段的误用:ASP.NET Core里的ApplicationDbContext是依赖注入的实例服务(通常是Scoped生命周期,每个请求一个实例),但你把它声明成了静态字段。如果仓储类没有被正确实例化,或者静态字段没被赋值,调用静态方法时_context就会是null。而且静态字段会长期持有DbContext,还会引发上下文状态混乱、连接泄漏等后续问题。
  2. 静态GetAuthorList方法的设计错误:仓储模式本质是实例化使用的——因为它需要依赖DbContext实例,静态方法根本无法正确获取依赖注入的服务实例,这就是空引用的直接触发点。

修复步骤

1. 重构仓储类的设计

先定义仓储接口(符合面向接口编程的规范,方便后续扩展和替换),再把静态成员改成实例成员:

// 定义仓储接口(推荐做法,符合依赖注入原则)
public interface IAuthorRepository : IDisposable
{
    List<Author> GetAuthorList();
}

// 实现仓储类
public class AuthorRepository : IAuthorRepository
{
    // 改为实例只读字段,保证只能通过构造函数赋值
    private readonly ApplicationDbContext _context;

    // 构造函数注入DbContext,ASP.NET Core会自动提供实例
    public AuthorRepository(ApplicationDbContext context)
    {
        // 提前做空检查,避免后续隐式空引用
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    // 改为实例方法,依赖实例化后的_context
    public List<Author> GetAuthorList()
    {
        // 直接查询返回,不需要多余的List初始化操作
        return _context.Authors
            .Select(a => new Author 
            { 
                AuthorId = a.AuthorId, 
                AuthorName = a.AuthorName 
                // 补充你需要映射的其他字段
            })
            .ToList();
    }

    // 实现IDisposable接口,按需释放DbContext
    public void Dispose()
    {
        _context?.Dispose();
    }
}

2. 在Startup中注册仓储服务

打开Startup.cs,在ConfigureServices方法里添加仓储的依赖注入注册(和DbContext保持相同的Scoped生命周期):

public void ConfigureServices(IServiceCollection services)
{
    // 注册DbContext(你应该已经有这行代码)
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

    // 注册仓储服务
    services.AddScoped<IAuthorRepository, AuthorRepository>();

    // 其他服务注册代码...
}

3. 在控制器/服务中使用仓储

通过构造函数注入IAuthorRepository,然后调用实例方法即可:

public class AuthorsController : Controller
{
    private readonly IAuthorRepository _authorRepo;

    // 构造函数注入仓储实例
    public AuthorsController(IAuthorRepository authorRepo)
    {
        _authorRepo = authorRepo;
    }

    public IActionResult Index()
    {
        var authors = _authorRepo.GetAuthorList();
        return View(authors);
    }
}

额外注意事项

  • 永远不要用静态字段持有DbContext:DbContext是轻量级对象,ASP.NET Core的依赖注入会自动管理它的生命周期,静态持有只会带来各种问题。
  • 构造函数空检查很重要:提前捕获注入失败的情况,避免到运行时才抛出模糊的空引用异常。
  • 坚持面向接口的仓储模式:后续如果要更换数据访问实现(比如从SQL换成MongoDB),只需要修改实现类,不需要改动业务代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:01:09