У меня есть фильтр действий, который регистрирует запрос в базе данных.
Я использую обычный метод строительства инжектора.
public ServerLogFilterAttribute(OrderEntryContext context)
{
this.context = context;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
var descriptor = context.ActionDescriptor;
if (descriptor != null && descriptor.RouteValues.Count > 0)
{
var actionName = descriptor.RouteValues["action"];
var controllerName = descriptor.RouteValues["controller"];
if (context.HttpContext.User != null && context.HttpContext.User.Identity != null)
{
var claimsIdentity = context.HttpContext.User.Identity as ClaimsIdentity;
if (claimsIdentity != null && claimsIdentity.IsAuthenticated)
{
var username = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier).Value;
var userId = claimsIdentity.Claims.First(c => c.Type == "userId").Value;
var serverLog = new ServerLog()
{
AspNetUserId = userId,
Controller = controllerName,
Action = actionName,
TimeStamp = DateTime.Now
};
LoggerRepository loggerRepository = new LoggerRepository(this.context);
Task.Run(() => loggerRepository.InsertServerCallLog(serverLog));
}
}
}
base.OnActionExecuting(context);
}
Но это вызывает исключение во время SaveChanges ():
System.ObjectDisposedException
HResult=0x80131622
Message=Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.<SaveChangesAsync>d__48.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at GGL.OrderEntry.Data.OrderEntryContext.<SaveChangesAsync>d__251.MoveNext() in C:\Dev\GGL\GGL.OrderEntry\GGL.OrderEntry.Data\Context\OrderEntryContext.Partial.cs:line 306
Насколько я смог понять, проблема в том, что время жизни фильтра больше, чем время жизни контекста (для которого было установлено значение "Transient")
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
Как тогда мне вводить DbContext?