Назначение постоянного объекта в конструкторе контроллера, который использует DI в ASP.NET Core
Так что, возможно, было несколько способов сформулировать этот вопрос, но это достаточно ясно. У меня есть обычная библиотека классов, отдельная от моего веб-проекта (которая построена на Angular2 и Asp.Net Core), и я должен сохранять ее состояние "основного объекта" на протяжении всего жизненного цикла веб-приложения. Моя проблема в том, что класс такого объекта делает доступ к базе данных, и мне пришлось использовать DI для доступа к правильному DBContext из приложения Angular2.
private Building building = null;
public AddDoorController(AutoListDbContext context) {
building = new Building(context);
}
Тем не менее, я должен настаивать building
состояние, но из того, что я мог собрать до сих пор, серверные классы для облегчения сохранения состояния (такие как HttpContext
, TempData
и т. д.) не доступны в области конструктора. Я хотел бы сохранить эти данные на стороне сервера, наверняка должен быть способ обойти это, не так ли?
1 ответ
Контексты EF (и должны быть) ограничены запросом. Это означает, что вы можете внедрить их только во что-то другое с помощью области запроса / переходного процесса. Поскольку контекст создается и уничтожается много раз за время жизни приложения, вы не можете внедрить его в объект с одной областью действия, который будет создан только один раз.
Если у вас есть синглтон, в котором вам абсолютно необходим доступ к контексту, вы можете вместо этого ввести IServiceCollection
и использовать шаблон локатора службы, то есть:
var context = services.GetService<MyContext>();
Однако вам нужно выполнять это каждый раз, когда вы получаете доступ к контексту. Другими словами, не сохраняйте это в переменную или поле экземпляра, так как он будет расположен в какой-то момент. В общем случае следует избегать шаблона поиска служб, поскольку он может привести к разного рода проблемам, но иногда у вас нет выбора.
Тем не менее, вполне возможно, что вам на самом деле не нужен синглтон. Вещи как HttpContext
больше не статики в ASP.NET Core. Если вам нужен доступ к HttpContext
, вам просто нужно ввести IHttpContextAccessor
, Как видно из названия, это позволяет вам получить доступ к текущему HttpContext
пример.
Кроме того, состояние, которое необходимо сохранить между запросами, должно быть сохранено, то есть фактически сохранено в какое-то постоянное хранилище, такое как SQL Server или Redis. В связи с этим вы можете настроить распределенный кеш, а затем использовать его для сохранения состояния вашего объекта, поскольку распределенный кеш (при настройке) будет использовать SQL Server или Redis в качестве основы. Это также позволяет вам избежать необходимости в singleton-scope, поскольку вы всегда можете просто извлечь объект из распределенного кэша, когда вам это нужно.