Simple injector "Operation could not be completed because the DbContext was deleted" during the MVC check

I have a rather difficult problem. I use FluentValidation.MVC in my ASP.NET MVC 5 project. In it I use the repository template to check if the user's email address is duplicated. The problem is not really in the repository template; this is what the repository uses the Entity Framework context entered into the constructor at runtime:

public class SomeRepository { //IEFContext is something I modified the T4 template to generate public SomeRepository(IEFContext context) { _context = context; } } 

The app uses this approach and it works great. SimpleInjector hooks up my EF context, which is designed to use the Per ASP.NET Web request (wraps HttpContext.Items objects).

 Dim httpLifecycle = New SimpleInjector.Integration.Web.WebRequestLifestyle(True) container.Register(of IEFContext, EFContext)(httpLifecycle) 

No problem with the app here, just a check. When the server receives the mail operation, the error I get is "The operation could not be completed because the DbContext was deleted." It seems like I cannot use any EF-related code in the FluentValidation attribute that uses the EF context for each web request. Nothing special about the validation attribute that does:

 public class Val : AbstractValidator<Entity> { public Val() { _repos = Container.GetInstance<ISomeRepos>(); RuleFor(i => i.Email).Must((o, v) => { _repos.HasDistinctEmail(o.ID, v); } } } 

The context was supposed to die with the previous request, as it is stored in HttpContext.Items . Any idea what is going on? I know by setting True to WebRequestLifecycle , I invoke the EF context to be deleted on request. I would think that would be desirable.

+5
source share
1 answer

It’s best that an instance of the Val class is cached all the time using AppDomain (singleton), which means that its constructor is called only once, and therefore it only allows one ISomeRepos , causing the repo to also ISomeRepos to a singleton (and with it and all its dependencies).

The quick fix is ​​simple, move the GetInstance call inside the delegate:

 public Val() { RuleFor(i => i.Email).Must((o, v) => { repos = Container.GetInstance<ISomeRepos>(); repos.HasDistinctEmail(o.ID, v); } } 
+4
source

Source: https://habr.com/ru/post/1215076/


All Articles