Skip to content

Instantly share code, notes, and snippets.

@berdon
Created April 28, 2017 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save berdon/3b568684a57f36c237e0546f61465da3 to your computer and use it in GitHub Desktop.
Save berdon/3b568684a57f36c237e0546f61465da3 to your computer and use it in GitHub Desktop.
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