Отключение IDisposable

109
08 февраля 2022, 00:10

Допустим, есть интерфейс IConnection. Он в своей иерархии имеет IDisposable.

Далее, есть класс, который реализует(Допустим, SqlConnection) IConnection.

Я создаю экземпляр этого класса и передаю его, как зависимости в 2 других класса, так как хочу, что бы они пользовались 1 соединением.

Проблема в том, что эти 2 объекта ничего не знают о том, что делят 1 соединение => они внутри себя могут реализовать IDisposable, где вызвать Dispose соединения => другой объект в один прекрасный момент крашнится из-за того, что соединение было закрыто.

На ум приходит создание Proxy, который будет вызывать пустой Dispose().

Есть еще какие-то варианты? Скажем, что бы не плодить прокси-классы.

Answer 1

Всё это не очень по нескольким причинам

  1. Дизайн. Наследование от IDisposable другим интерфейсом постулирует нам о необходимости реализации интерфейса как нечто, что имеет высвобождаемые ресурсы. Плохая идея думать, что все реализации интерфейса «соединение» должны высвобождать ресурсы (есть тесты, как минимум). Следовательно, реализация IDisposable это необходимость для конкретного класса (например, SqlConnection и т.д.), а не интерфейса.

  2. Существует композиция и аггрегация. При аггрегации время жизни вашего объекта определяет внешний контекст, а не класс где вы его используете (это свойство композиции). Вы описываете аггрегацию.

  3. Большинство контейнеров зависимостей реализуют правила 3R: Register, Resolve, Release. Это, в том числе, значит, что контейнер может вызвать Dispose после окончания времени жизни объекта (Scope)

Собственно, решение можно подсмотреть у любого контекста подобного рода, например EF, где контекст регистрируется один на запрос (PerRequest) в случае веба. Либо использует пул/фабрику. Конкретная реализация будет зависить от конкретного кода.

Answer 2

они внутри себя могут реализовать IDisposable, где вызвать Dispose

Если они это классы в которые заинжектили экземпляры IConnection, то высвобождать такой ресурс плохая практика, т.к. они их не порождали и понятия не имеют где они еще используются. В диспосе нужно высвобождать только ресурсы которые были созданы самим этим классом. Да и сейчас почти во всех DI-контейнерах можно задавать время жизни объектов.

READ ALSO
Scroll в RichTextBox и LinkLabel

Scroll в RichTextBox и LinkLabel

Вывожу в RichTextBox список LinkLabel-ов

86
Метод Рунге-Кутта 4-го порядка для CДУ C#

Метод Рунге-Кутта 4-го порядка для CДУ C#

Нужно решить систему из двух дифференциальных уравнений методом Рунге-Кутты 4-го порядка с коррекцией шага по правилу Рунге

131
Построение оптимального сплайна Безье (C#). Проблема с нахождением контрольных точек

Построение оптимального сплайна Безье (C#). Проблема с нахождением контрольных точек

Реализую свой метод интерполяции сплайна Безье дефекта 1Перед написанием кода вдохновлялся этим Построение оптимального сплайна Безье

65
выводит такую ошибку помогите -IndexOutOfRangeException: Array index is out of range в Unity

выводит такую ошибку помогите -IndexOutOfRangeException: Array index is out of range в Unity

пишу скрипт для unity, на движение колес машины при нажатии на кнопку она должна ехать но при запуске сцены выдаёт неприятную ошибку и я не знаю...

121