ASP.NET Core中AddSingleton失效:单例服务重复添加初始数据
问题分析与解决方案
问题根源
- 控制器注入类型不匹配:你注册的是
ICourseService的单例,但控制器直接注入具体类型CourseService,DI容器会为CourseService创建新实例(未注册其单例),导致每次请求都执行构造函数,重复添加数据。 - 未做数据存在性检查:构造函数中直接添加数据,即使服务是单例,也会在应用重启时重复添加;而当前每次刷新都添加的核心原因是服务实例未被复用。
- 单例依赖Scoped服务的风险:
CourseService是单例,但依赖的DataContext默认是Scoped生命周期,会导致上下文被长期持有,引发连接泄漏、状态混乱等潜在问题。
解决方案
1. 修正控制器注入方式
控制器改为注入接口ICourseService,确保使用注册的单例实例:
public class CourseController : Controller { private readonly ICourseService _courseService; public CourseController(ICourseService courseService) { _courseService = courseService; } [Route("courses")] public async Task<IActionResult> GetCourses() { var courses = await _courseService.GetCoursesAsync(); return View("CourseList", courses); } }
2. 添加数据前检查存在性
在服务构造函数中先查询数据库,仅当数据不存在时再添加:
public class CourseService : BaseService<Course, CourseDto>, ICourseService { public CourseService(IMapper mapper, DataContext context) : base(mapper,context) { // 替换为你的课程唯一标识字段(如名称、ID等) if (!context.Courses.Any(c => c.Name == "初始课程1")) { context.Courses.Add(new Course { Name = "初始课程1", ... }); } if (!context.Courses.Any(c => c.Name == "初始课程2")) { context.Courses.Add(new Course { Name = "初始课程2", ... }); } context.SaveChanges(); } public IEnumerable<CourseDto> GetCourses() { ... } public async Task<IEnumerable<CourseDto>> GetCoursesAsync() { ... } }
3. 优化初始化逻辑(推荐)
将初始数据添加逻辑移到应用启动阶段,避免单例服务持有Scoped上下文:
// 在Program.cs中,构建主机后执行初始化 var host = builder.Build(); using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; var context = services.GetRequiredService<DataContext>(); // 检查并添加初始数据 if (!context.Courses.Any(c => c.Name == "初始课程1")) { context.Courses.Add(new Course { Name = "初始课程1", ... }); } if (!context.Courses.Any(c => c.Name == "初始课程2")) { context.Courses.Add(new Course { Name = "初始课程2", ... }); } context.SaveChanges(); } host.Run();
4. 确认服务注册正确性
确保ICourseService和DataContext的注册配置正确:
services.AddSingleton<ICourseService, CourseService>(); services.AddDbContext<DataContext>(options => options.UseSqlite("你的SQLite连接字符串"));
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

