简单的注入器"由于在MVC验证期间已经处理了DbContext,因此无法完成操作"

Bri*_*ins 5 .net asp.net-mvc entity-framework fluentvalidation simple-injector

我有一个非常复杂的问题.我在ASP.NET MVC 5项目中使用FluentValidation.MVC.在其中,我使用存储库模式来检查用户的电子邮件地址是否不重复.问题不在于存储库模式; 这是存储库在运行时使用注入构造函数的实体框架上下文:

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

该应用程序使用这种方法,它工作得很好.SimpleInjector连接我的EF上下文,其范围限定为使用Per ASP.NET Web请求(包装HttpContext.Items).

Dim httpLifecycle = New SimpleInjector.Integration.Web.WebRequestLifestyle(True)
container.Register(of IEFContext, EFContext)(httpLifecycle)
Run Code Online (Sandbox Code Playgroud)

这里的应用没有问题,只是验证.当服务器收到post操作时,我得到的错误是"由于已经处理了DbContext,因此无法完成操作".看来我不能在FluentValidation属性中使用任何与EF相关的代码,该属性在每个Web请求的基础上使用EF上下文.验证属性没有什么特别之处,它可以:

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

因为存储在上面,因此上下文应该与之前的请求一起死亡HttpContext.Items.知道发生了什么事吗?我知道通过将True设置为WebRequestLifecycle,我会在请求结束时处理EF上下文.我认为这是可取的.

Ste*_*ven 5

我最好的选择是,该类的实例Val在 AppDomain (单例)期间被缓存,这意味着它的构造函数仅被调用一次,因此它只解析一个 single ISomeRepos,导致该存储库也被提升为单例(以及它的所有依赖项)。

快速修复很简单,将GetInstance调用移至委托内:

public Val()
{
    RuleFor(i => i.Email).Must((o, v) =>
    {
        repos = Container.GetInstance<ISomeRepos>();
        repos.HasDistinctEmail(o.ID, v);
    }
}
Run Code Online (Sandbox Code Playgroud)