namespace InnovEnergy.Lib.Protocols.Modbus.Channels; public abstract class ConnectionChannel : Channel, IDisposable { private readonly Func _CloseAfterException ; private readonly Boolean _CloseAfterSuccessfulRead ; private readonly Boolean _CloseAfterSuccessfulWrite ; protected abstract T Open(); protected abstract void Close(T connection); protected abstract IReadOnlyList Read (T connection, Int32 nBytes); protected abstract void Write(T connection, IReadOnlyList data); private T? _Connection; protected ConnectionChannel(Boolean closeAfterSuccessfulRead = false, Boolean closeAfterSuccessfulWrite = false, Func? closeAfterException = null) { _CloseAfterSuccessfulRead = closeAfterSuccessfulRead; _CloseAfterSuccessfulWrite = closeAfterSuccessfulWrite; _CloseAfterException = closeAfterException ?? (_ => true); } public override IReadOnlyList Read(Int32 nBytes) { try { return Read(Connection, nBytes); } catch (Exception e) { if (_CloseAfterException(e)) Close(); throw; } finally { if (_CloseAfterSuccessfulRead) Close(); } } public override void Write(IReadOnlyList data) { try { Write(Connection, data); } catch (Exception e) { if (_CloseAfterException(e)) Close(); throw; } finally { if (_CloseAfterSuccessfulWrite) Close(); } } private T Connection => _Connection ??= Open(); private void Close() { if (_Connection is null) return; Close(_Connection); _Connection = default; } public void Dispose() => Close(); }