Home > OS >  AddSingleton doesn't work in my ASP.NET Core project
AddSingleton doesn't work in my ASP.NET Core project

Time:01-08

I have the problem that I want to add my service CourseService as Singleton and I want to add only once my initial data like this:

context.Courses.Add(new Course { ... });

But it turned out that every time when I upload my page with courses my initial data added again and again to my database. So I see the same courses on my page as much time as I upload this page. Can't understand where is the problem.

My interface:

public interface ICourseService
{
    IEnumerable<CourseDto> GetCourses();
    Task<IEnumerable<CourseDto>> GetCoursesAsync();
}

My service:

public class CourseService : BaseService<Course, CourseDto>, ICourseService
{
        public CourseService(IMapper mapper, DataContext context) : base(mapper,context)
        {
            context.Courses.Add(new Course { ... });
            context.Courses.Add(new Course { ... });
            context.SaveChanges();
        }

        public IEnumerable<CourseDto> GetCourses() { ... }

        public async Task<IEnumerable<CourseDto>> GetCoursesAsync() { ... }
}

My controller:

public class CourseController : Controller
{
        private readonly CourseService _courseService;

        public CourseController(CourseService courseService)
        {
            _courseService = courseService;
        }

        [Route("courses")]
        public async Task<IActionResult> GetCourses()
        {
            var courses = await _courseService.GetAllAsync();
            return View("CourseList", courses);
        }
}

And I added my service as Singleton in the method ConfigureServices:

services.AddSingleton<ICourseService, CourseService>();
services.AddEntityFrameworkSqlite().AddDbContext<DataContext>();

CodePudding user response:

AddDbContext by default adds context with Scoped lifetime, so it can't be resolved in singleton services. Possible workarounds:

  1. register ICourseService as scoped
  2. register context as scoped or transient (would not recommend)
  3. inject IServiceScopeFactory and use it to create scope and resolve context from the scope (on each method call), like in this answer

Personally I would go with the first approach.

Read more:

  • Related