Я создаю веб-API с ASP.NET Core 2.1. У меня есть контроллеры, к которым пользователь может получить доступ через HTTP-запросы. Затем контроллеры вызывают классы обслуживания. Я пытаюсь внедрить свой DbContext в свой собственный класс обслуживания, но всякий раз, когда я это делаю, я получаю ответ 500 с сервера. В моем классе запуска у меня есть
services.AddDbContext<CatalogueContext>(options => options.UseSqlServer(_config.GetConnectionString("DefaultConnection")));
Если я помещу это в класс контроллера, все будет работать
private readonly ITrackServices _service;
private readonly CatalogueContext _dbContext;
public TrackController(ITrackServices service, CatalogueContext dbContext)
{
_service = service;
_dbContext = dbContext;
}
Но я не хочу вводить dbContext в контроллер. Если я удалю эту инъекцию из контроллера и попробую то же самое в своем классе обслуживания, как это
private readonly CatalogueContext _dbContext;
public TrackService(CatalogueContext dbContext)
{
_dbContext = dbContext;
}
это не работает. Поэтому, когда я пытаюсь получить доступ к конечной точке, которая использует TrackService, я получаю 500 с сервера.
TrackService
регистрируется как синглтон:
services.AddSingleton<ITrackServices, TrackService>();
Я не знаю, что я делаю неправильно. Должен ли я реализовать какой-то интерфейс в TrackService, чтобы включить внедрение зависимостей или что?
@juunas: Спасибо. Я использовал services.AddSingleton<ITrackServices, TrackService>(); Я изменил то, что вы сказали, и теперь это работает.
Какую ошибку вы получаете? Опубликуйте текст исключения полный, возвращенный Exception.ToString()
. Это включает в себя любые внутренние исключения и стек вызовов, который привел к исключению. Это покажет, в чем заключается настоящая проблема. Незарегистрированная зависимость? Или ObjectDisposedException, которое, вероятно, вызвано тем, что ITrackServices
является одноэлементным, когда DbContext находится в области действия?
Краткий ответ: никогда не используйте DbContext из синглтона.
@DavidG, по крайней мере, не напрямую
@PanagiotisKanavos Как бы вы сделали это косвенно?
@DavidG это задокументировано, как всегда, в месте неправильно: Фоновые задачи с размещенными службами в ASP.NET Core: использование службы с заданной областью в фоновой задаче. Поиск ссылок на документы становится настоящей проблемой.
@DavidG, однако, это техника discretion required
. Зачем использовать область синглтон для службы, если стоимость не оправдана?
@PanagiotisKanavos О, создаю свой собственный объем, попался, просто не знал, что ты имеешь в виду под «косвенно». Да, недавно мне приходилось делать это в нескольких местах, просто не потому, что это было из синглтона.
Вам также необходимо зарегистрировать сервис:
services.AddScoped<ITrackService, TrackService>();
Используете ли вы переходный, ограниченный или одноэлементный, зависит от того, какое время жизни имеют зависимости службы. Это не должно зависеть от сервисов с меньшим временем жизни.
ОП упоминает в комментариях, что сервис уже зарегистрирован как синглтон.
И они также сказали, что изменили то, что я сказал, и теперь это работает. Может быть ошибка проверки срока службы. Вы не должны использовать службы с ограниченной областью действия из синглетонов.
нет проблем с использованием сервисов с ограниченной областью действия из синглетонов. Правильный способ сделать это описан в документах и повторяющихся вопросах.
Хорошо, спасибо. Мне нужно больше узнать об этом. Тем временем я отмечу это как ответ, потому что он все равно решил мою проблему :)
Использование службы с ограниченной областью действия из синглтона через внедрение конструктора означает, что вы используете удаленную службу после выполнения запроса и удаления области действия. Конечно, вы можете создавать свои собственные области видимости или получать их через набор сервисов внутри метода.
Вы зарегистрировали сервис? например
services.AddScoped<ITrackService, TrackService>()