ASP.NET Core 1.1仓储模式中“对象未引用实例”问题求助
解决ASP.NET Core 1.1查询型仓储的空引用异常(Object reference not set to an instance of an object)
嘿,我帮你定位到问题根源了!你遇到的空引用错误,完全是代码里静态成员的错误设计导致的,咱们一步步来修复:
问题核心分析
你的代码里有两个致命问题:
- 静态
_context字段的误用:ASP.NET Core里的ApplicationDbContext是依赖注入的实例服务(通常是Scoped生命周期,每个请求一个实例),但你把它声明成了静态字段。如果仓储类没有被正确实例化,或者静态字段没被赋值,调用静态方法时_context就会是null。而且静态字段会长期持有DbContext,还会引发上下文状态混乱、连接泄漏等后续问题。 - 静态
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
相关产品推荐
相关产品推荐

