我的 DbContext 是如何处置的?

XBi*_*13X 5 c# dispose entity-framework-4 asp.net-mvc-3 dbcontext

我在将单体 ASP.NET MVC 应用程序拆分为 N 层应用程序时遇到了很大的困难。在以下示例中,在第一次调用_messageRepo.Create()期间,会引发异常,表明DbContext无法使用,因为它已被释放。

我看不到这是如何发生的,并且尝试中断Dispose()方法实际上并不会导致应用程序在调试期间中断。

基本结构如下:

  • 控制器注入了它们使用的每个服务的实例 //即: public MyController(IMessageService messageService)
  • 服务包含任何所需的存储库实例(即:_messageRepository
  • 存储库使用MyContext的实例( DbContext的子类)
  • 这些实例会在需要时重建,如下例所示

    using(var context = new MyContext())
    {
        _messageRepo = new MessageRepository(context);
        _idRepo = new IdentityRepository(context);
    
        var status = _messageRepo.GetStatus(Int32.Parse(message.To));
        message.To = status.Header.From.Name;
        message.ToHash = Obfuscate.SaltAndHash(message.To);
        message.Subject = "RE:" + status.Header.Subject;
    
        var toUser = _idRepo.Get(message.To);
        var fromUser = _idRepo.Get(_userName);
        var rawMessage = new Message()
        {
            Content = message.Content,
            Attachments = GetAttachments(message.AttachmentIds)
        };
        var header = new MessageHeader()
        {
            To = toUser,
            From = fromUser,
            Subject = message.Subject
        };
        _messageRepo.Create(new MessageStatus()
        {
            CreatedAt = DateTime.Now,
            IsRead = false,
            IsSpam = false,
            IsTrash = false,
            Message = rawMessage,
            Header = header,
            Owner = header.To
        });
        _messageRepo.Create(new MessageStatus()
        {
            CreatedAt = DateTime.Now,
            IsRead = false,
            IsSpam = false,
            IsTrash = false,
            Message = rawMessage,
            Header = header,
            Owner = header.From
        });
        context.Commit();
        Email.SendNewMessageNotification(fromUser.Email, toUser.Email);
    }
    
    Run Code Online (Sandbox Code Playgroud)

存储库方法是 LINQ 单行代码,使用代码优先方法通过实体框架从数据库检索模型。

这种做法有什么问题吗?我一开始确实让 MyContext 实现了 IUnitOfWork,但我删除了它,直到我得到这个不太复杂的方法的功能。

此外,我使用 IoC 框架 (AutoFac) 来加载这些接口实现的实例。如果这是问题所在,那么我需要改变我的逻辑以适应 AutoFac?

//in Global.asax.cs
builder.RegisterType<PonosContext>().As<PonosContext>().InstancePerHttpRequest();

//Example repo constructor
public MessageRepository(PonosContext context)
{
    _db = context;
}
Run Code Online (Sandbox Code Playgroud)

Tim*_*ols 3

当你使用 IoC 容器时,你不应该调用容器管理的服务的 new 。在此示例中,您不应使用:

using(var context = new MyContext())
_messageRepo = new MessageRepository(context);
_idRepo = new IdentityRepository(context);
Run Code Online (Sandbox Code Playgroud)

您的依赖项应该被注入(例如通过构造函数)。

如何向 AutoFac 注册您的存储库?也许您将存储库配置为单例?当存储库重新用于第二个 http 请求时,这可能会导致处置异常。