-
Notifications
You must be signed in to change notification settings - Fork 26
Description
Once a lot of a codebase has necessarily taken a dependency on Owned<T> so that StrongInject can wire everything up, many places remain that need to create their own Owned instances. This is handy for many tests and smaller executables in a project that don't really need StrongInject and can do their own wiring with a few calls.
Instead of: new Owned<SomePotentiallyLongTypeName>(value, () => { })
Friendly: Owned.WithoutDisposal(value)
Instead of: new Owned<SomePotentiallyLongTypeName>(value, value.Dispose)
Friendly: Owned.WithDisposal(value)
Instead of: new Owned<T>(value, () => (value as IDisposable)?.Dispose())
Friendly: Owned.WithDisposal(value)
Instead of: new Owned<SomeType>(value, () => { value.Dispose(); dependency1.Dispose(); dependency2.Dispose(); })
Friendly: Owned.WithDisposal(value, dependency1, dependency2) or
Friendly: Owned.WithDisposal(value, alsoDispose: new[] { dependency1, dependency2 })
Here's a rough draft for what I've already found useful, and I'm happy to do the implementation:
namespace StrongInject;
public static class Owned
{
/// <summary>
/// Nothing happens when the <see cref="Owned{T}"/> is disposed, even if <paramref name="value"/>
/// is disposable.
/// </summary>
public static Owned<T> WithoutDisposal<T>(T value)
{
return new(value, dispose: null);
}
/// <summary>
/// <para>
/// When the <see cref="Owned{T}"/> is disposed, <paramref name="value"/> is disposed. If
/// <paramref name="value"/> does not implement <see cref="IDisposable"/>, the behavior is
/// the same as <see cref="WithoutDisposal{T}(T)"/>.
/// </para>
/// </summary>
public static Owned<T> WithDisposal<T>(T value)
{
// T is not constrained to IDisposable. If it was, call sites using generic types would be penalized.
return new(value, dispose: value is IDisposable disposable
? disposable.Dispose
: null);
}
/// <summary>
/// <para>
/// When the <see cref="Owned{T}"/> is disposed, <paramref name="value"/> is disposed first and then
/// the items in <paramref name="alsoDispose"/> are disposed in the order they appear.
/// </para>
/// <para>
/// If <paramref name="value"/> does not implement <see cref="IDisposable"/>, the items in
/// <paramref name="alsoDispose"/> will still be disposed.
/// </para>
/// </summary>
public static Owned<T> WithDisposal<T>(T value, params IDisposable[] alsoDispose)
{
return new(value, dispose: () =>
{
(value as IDisposable)?.Dispose();
foreach (var disposable in alsoDispose)
disposable.Dispose();
});
}
}An AsyncOwned static class would be similar.