Как утилизируется мой DbContext? - PullRequest
3 голосов
/ 28 февраля 2012

У меня возникают большие трудности с разделением моего монолитного приложения 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);
    }
    

Методы хранилища - это однострочники LINQ, которые извлекают модели из базы данных через Entity Framework с использованием подхода, основанного на коде.

Что-то не так с этим подходом? Сначала у MyContext был реализован IUnitOfWork, но я удалял его до тех пор, пока не получу этот менее сложный метод.

Кроме того, я использую фреймворк IoC (AutoFac) для загрузки экземпляров этих реализаций интерфейса. Если это проблема, то что мне нужно изменить в моей логике, чтобы приспособить AutoFac?

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

//Example repo constructor
public MessageRepository(PonosContext context)
{
    _db = context;
}

Ответы [ 2 ]

2 голосов
/ 28 февраля 2012

Когда вы используете контейнер IoC, вы никогда не должны вызывать новый сервис, управляемый контейнером.В этом примере вы не должны использовать:

using(var context = new MyContext())
_messageRepo = new MessageRepository(context);
_idRepo = new IdentityRepository(context);

Ваши зависимости должны быть введены (например, конструктором).

Как вы регистрируете свои репозитории в AutoFac?Может быть, у вас есть ваши репозитории, сконфигурированные как синглтон?Это может вызвать исключение утилизации, когда хранилище повторно используется для второго http-запроса.

0 голосов
/ 28 февраля 2012

DataContexts не должны жить слишком долго :) Они должны быть созданы и расположены близко к их использованию.

Не передавайте один и тот же экземпляр между разными репозиториями.Если вы хотите обернуть несколько операций в одну транзакцию, посмотрите на TransactionScope

...