Является ли хорошей практикой передача уже созданного свойства в оператор использования? - PullRequest
2 голосов
/ 27 сентября 2019

Я столкнулся с этим вопросом, когда выполнял рефакторинг некоторого моего кода, который сильно зависел от шаблона Disposable.

У меня действительно есть поле только для чтения DbContext, которое инициализируется в конструкторе.Теперь мне было интересно, могу ли я просто передать поле в блок использования, чтобы правильно расположить его.Или мне нужно избавиться от поля и инициализации, чтобы просто инициализировать его внутри каждого блока с использованием

protected readonly DbContext _context;

public Repository(DbContext context)
{
    _context = context;
}

public Task<T> GetAsync(Guid id)
{
    using (_context)
    {
        return _context.Set<T>().FindAsync(new CancellationToken(), id);
    }
}

Я ожидаю правильного применения шаблона Dispose

1 Ответ

5 голосов
/ 27 сентября 2019

Я вижу две потенциальные проблемы:

  1. Когда вы выходите из блока using, объект удаляется.Если вы затем попытаетесь использовать его повторно, вы можете получить куда-нибудь InvalidOperationException.
  2. Некоторые объекты не освобождают все свои управляемые ресурсы при утилизации.Они по-прежнему могут ссылаться на некоторые объекты большого размера, которые нельзя собирать, пока у вас есть ссылка на одноразовый объект.Пример: MemoryStream - когда вы утилизируете его, MemoryStream не ссылается на свой внутренний byte[] буфер.Это означает, что пока вы не ссылаетесь на сам поток, массив не может быть собран и фактически является утечкой памяти.

Так что, с моей точки зрения, было бы хорошо создать новый объект в using, так как он автоматически утилизирует его для вас, и отменяет ссылку на него, чтобы его можно было собрать.

Возможное решение может заключаться в том, чтобы вместо этого внедрить объект Factory и использовать его фабрикуметод создания одноразового объекта в начале блока using.

...