#asp.net-mvc #autofac
#asp.net-mvc #автофас
Вопрос:
Я хочу добавить некоторую фоновую обработку в свой ASP.NET Приложение MVC 5, более конкретно выполняющее некоторые длительные (5-10 секунд) запущенные задачи с HostingEnvironment.Элемент QueueBackgroundWorkItem. Теперь проблема, с которой я сталкиваюсь, заключается в том, что код выполняется «вне диапазона» и больше не привязан к запросу — Autofac избавляется от некоторых введенных зависимостей.
Вот часть кода:
[HttpPost, ActionName("Execute")]
public ActionResult ExecutePost(Guid taskguid, FormCollection values)
{
if (taskguid == default(Guid))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var model = _taskListService.GetTaskByGuid(taskguid);
if (TryUpdateModel(model.TaskObject as MissingCrossReferenceTask))
{
model.TaskObject.DependencyContainer = _dependencyContainer;
model.TaskObject.TaskListId = model.Id;
HostingEnvironment.QueueBackgroundWorkItem(ct => ExecuteTask(ct, model));
return RedirectToAction("Index", "Dashboard");
}
return View(model);
}
В приведенном выше коде DependencyContainer — это объект, содержащий ряд зависимостей, которые вводятся Autofac (репозитории и службы EF)
private void ExecuteTask(CancellationToken ct, TaskList model)
{
model.TaskObject.Execute();
}
Внутри этого метода выполнения MissingCrossReferenceTask (который находится в отдельной сборке от ASP.NET Проект MVC:
public bool Execute()
{
long tableId = DependencyContainer.CrossReferenceService.GetCrossReferenceTable(TableName).Id;
string currentValue = DependencyContainer.CrossReferenceService.GetValue(FromValue, tableId);
...
}
Первая строка выдает исключение: ObjectDisposedExcetion {«Экземпляр ObjectContext удален и больше не может использоваться для операций, требующих подключения».}
Так вот, я недостаточно хорошо знаю Autofac, чтобы найти наилучший способ обойти эту проблему. Можно ли каким-то образом повторно ввести ссылку непосредственно в метод executeTask? Если да, то каким образом?
Я был бы чрезвычайно признателен за любую помощь в этом. Это сводит меня с ума уже несколько дней…
Спасибо, Ник Голобородько
Ответ №1:
Я думаю, что отправка вопроса заставила меня взглянуть на проблему под несколько другим углом.
Я думаю, что нашел способ обойти это (другими словами — теперь все работает так, как мне бы хотелось). Я все еще не уверен, является ли этот подход лучшим в моей ситуации или есть какие-то невидимые проблемы с ним — я был бы очень признателен за любые комментарии по этой теме!
Я решил эту проблему следующим образом:
private void ExecuteTask(CancellationToken ct, TaskList model)
{
MvcApplication app = this.HttpContext.ApplicationInstance as MvcApplication;
using (var container = app.ContainerProvider.ApplicationContainer.BeginLifetimeScope(WebLifetime.Application))
{
model.TaskObject.DependencyContainer = container.Resolve<DependencyContainer>();
model.TaskObject.Execute();
}
}
(принято из решения, размещенного на этой странице: http://aboutcode.net/2010/11/01/start-background-tasks-from-mvc-actions-using-autofac.html )
Надеюсь, это сэкономит немного времени кому-то еще в будущем!