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:
- register
ICourseService
as scoped - register context as scoped or transient (would not recommend)
- 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: