Helper classes to reduce using() block hell in c#
// Old using() block hell | |
public async Task SendAsync(byte[] data, Delegate next) | |
{ | |
using (var stream = ...) | |
{ | |
using (var encryptStream = ...) | |
{ | |
using (var encodeStream = ...) | |
{ | |
using (var reader = ...) | |
{ | |
await next(...); | |
} | |
} | |
} | |
} | |
} | |
public async Task RecieveAsync(byte[] data, Delegate next) | |
{ | |
using (var stream = ...) | |
{ | |
using (var decodeStream = ...) | |
{ | |
using (var decryptStream = ...) | |
{ | |
using (var reader = ...) | |
{ | |
await next(...); | |
} | |
} | |
} | |
} | |
} | |
// Using the UsingBuilder | |
public async Task SendAsync(byte[] data, Delegate next) | |
{ | |
With.Using(() => new ...) | |
.Using(memoryStream => ...) | |
.Using(cryptoStream => ...) | |
.Using(base64Stream => ...) | |
.Then(async streamReader => await next(...)); | |
} | |
public async Task RecieveAsync(byte[] data, Delegate next) | |
{ | |
With.Using(() => new ...) | |
.Using(memoryStream => ...) | |
.Using(base64Stream => ...) | |
.Using(cryptoStream => ...) | |
.Then(async streamReader => await next(...)); | |
} |
public static class With | |
{ | |
public static UsingBuilder<TType> Using<TType>(Func<TType> disposable) where TType : IDisposable | |
{ | |
return new UsingBuilder<TType>(disposable.Invoke()); | |
} | |
public static UsingBuilder<TType> Using<TPType, TType>(this UsingBuilder<TPType> builder, Func<TPType,TType> disposable) where TPType : IDisposable where TType : IDisposable | |
{ | |
try | |
{ | |
return new UsingBuilder<TType>(builder._disposable, disposable.Invoke(builder._disposable)); | |
} | |
catch (Exception e) | |
{ | |
builder?.Dispose(); | |
throw; | |
} | |
} | |
} | |
public class UsingBuilder<TType> : IDisposable where TType : IDisposable | |
{ | |
internal readonly IDisposable _parent; | |
internal readonly TType _disposable; | |
public UsingBuilder(TType disposable) | |
{ | |
_disposable = disposable; | |
} | |
public UsingBuilder(IDisposable parent, TType disposable) | |
{ | |
_parent = parent; | |
_disposable = disposable; | |
} | |
public void Then(Action<TType> action) | |
{ | |
try | |
{ | |
action.Invoke(_disposable); | |
} | |
finally | |
{ | |
_disposable?.Dispose(); | |
} | |
} | |
public void Dispose() | |
{ | |
_parent?.Dispose(); | |
_disposable?.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment