-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 0d35512
Showing
18 changed files
with
787 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
end_of_line = lf | ||
insert_final_newline = true | ||
indent_style = space | ||
indent_size = 4 | ||
trim_trailing_whitespace = true | ||
|
||
[*.{props,sln,targets}] | ||
indent_style = tab | ||
|
||
[*.{yml,yaml}] | ||
indent_size = 2 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* text=auto eol=lf | ||
*.sln text eol=crlf | ||
*.cs diff=csharp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
name: Build | ||
|
||
on: | ||
push: | ||
branches: [ main ] | ||
pull_request: | ||
branches: [ main ] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-dotnet@v3 | ||
- name: Restore dependencies | ||
run: dotnet restore /p:TreatWarningsAsErrors=true | ||
- name: Build | ||
run: dotnet build --no-restore /p:TreatWarningsAsErrors=true | ||
- name: Run Tests | ||
run: dotnet test --no-build | ||
nupkg: | ||
name: Generate NuGet Packages | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-dotnet@v3 | ||
name: Install Current .NET SDK | ||
- name: Generate NuGet Packages | ||
run: dotnet pack --configuration Release --output nupkg /p:TreatWarningsAsErrors=true | ||
- uses: actions/upload-artifact@v2 | ||
if: success() && github.ref == 'refs/heads/main' | ||
with: | ||
name: nupkg | ||
path: nupkg/* | ||
retention-days: 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
bin/ | ||
obj/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project> | ||
<PropertyGroup Label="Shared NuGet Metadata"> | ||
<Authors>Polyadic</Authors> | ||
<PackageLicenseExpression>MIT OR Apache-2.0</PackageLicenseExpression> | ||
<PackageProjectUrl>https://github.com/polyadic/dispownership</PackageProjectUrl> | ||
<Copyright>© Polyadic. All rights reserved.</Copyright> | ||
</PropertyGroup> | ||
<ItemGroup Label="Code Style"> | ||
<PackageReference Include="Messerli.CodeStyle" PrivateAssets="all" /> | ||
</ItemGroup> | ||
<PropertyGroup Label="Deterministic Builds and Source Link"> | ||
<PublishRepositoryUrl>true</PublishRepositoryUrl> | ||
<ContinuousIntegrationBuild Condition="'$(GITHUB_ACTIONS)' == 'true'">true</ContinuousIntegrationBuild> | ||
<EmbedUntrackedSources>true</EmbedUntrackedSources> | ||
</PropertyGroup> | ||
<ItemGroup Label="Deterministic Builds and Source Link"> | ||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All"/> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project> | ||
<PropertyGroup> | ||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> | ||
</PropertyGroup> | ||
<ItemGroup Label="Build Dependencies"> | ||
<PackageVersion Include="Messerli.CodeStyle" Version="2.2.0" /> | ||
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="1.1.1" /> | ||
</ItemGroup> | ||
<ItemGroup Label="Test Dependencies"> | ||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.2.0" /> | ||
<PackageVersion Include="xunit" Version="2.4.2" /> | ||
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<Project Sdk="Microsoft.Build.NoTargets/3.7.0"> | ||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<IncludeBuildOutput>false</IncludeBuildOutput> | ||
<ContentTargetFolders>contentFiles</ContentTargetFolders> | ||
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences> | ||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> | ||
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute> | ||
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking> | ||
<LangVersion>11.0</LangVersion> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="..\Dispownership\*.cs" Exclude="$(DefaultItemExcludes)" Link="%(FileName)%(Extension)" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<Compile Update="@(Compile)"> | ||
<Pack>true</Pack> | ||
<PackagePath>$(ContentTargetFolders)\cs\any\$(PackageId)\</PackagePath> | ||
</Compile> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
using System; | ||
using Xunit; | ||
|
||
namespace Dispownership.Test; | ||
|
||
public sealed class DisposableTest | ||
{ | ||
[Fact] | ||
public void DisposesInnerValueIfOwned() | ||
{ | ||
#pragma warning disable IDISP001 | ||
var value = new DisposableStub(); | ||
#pragma warning restore IDISP001 | ||
|
||
using (Disposable.Owned(value)) | ||
{ | ||
} | ||
|
||
Assert.True(value.Disposed); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotDisposeInnerValueIfBorrowed() | ||
{ | ||
#pragma warning disable IDISP001 | ||
var value = new DisposableStub(); | ||
#pragma warning restore IDISP001 | ||
|
||
using (Disposable.Borrowed(value)) | ||
{ | ||
} | ||
|
||
Assert.False(value.Disposed); | ||
} | ||
|
||
[Fact] | ||
public void DoesNotDisposeOwnedValueAfterMove() | ||
{ | ||
#pragma warning disable IDISP001 | ||
var value = new DisposableStub(); | ||
#pragma warning restore IDISP001 | ||
|
||
using (var disposable = Disposable.Owned(value)) | ||
{ | ||
_ = disposable.Take(); | ||
} | ||
|
||
Assert.False(value.Disposed); | ||
} | ||
|
||
[Fact] | ||
public void ThrowsWhenMovingAValueTwice() | ||
{ | ||
#pragma warning disable IDISP004 | ||
using var disposable = Disposable.Owned(new DisposableStub()); | ||
#pragma warning restore IDISP004 | ||
_ = disposable.Take(); | ||
Assert.Throws<InvalidOperationException>(() => disposable.Take()); | ||
} | ||
|
||
[Fact] | ||
public void ThrowsWhenMovingABorrowedValue() | ||
{ | ||
#pragma warning disable IDISP004 | ||
using var disposable = Disposable.Borrowed(new DisposableStub()); | ||
#pragma warning restore IDISP004 | ||
Assert.Throws<InvalidOperationException>(() => disposable.Take()); | ||
} | ||
|
||
private sealed class DisposableStub : IDisposable | ||
{ | ||
public bool Disposed { get; private set; } | ||
|
||
public void Dispose() => Disposed = true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<IsPackable>false</IsPackable> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<ProjectReference Include="..\Dispownership\Dispownership.csproj" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" /> | ||
<PackageReference Include="xunit" /> | ||
<PackageReference Include="xunit.runner.visualstudio" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.0.31903.59 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dispownership", "Dispownership\Dispownership.csproj", "{0FC69541-37D7-4E58-A80B-2E8B8217A906}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dispownership.Sources", "Dispownership.Sources\Dispownership.Sources.csproj", "{B3926389-9766-4C06-ADDF-C46C0FFFDEE2}" | ||
EndProject | ||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6FB7B031-CD30-4B19-A58C-23C4FE78FF0A}" | ||
ProjectSection(SolutionItems) = preProject | ||
.editorconfig = .editorconfig | ||
.gitattributes = .gitattributes | ||
.gitignore = .gitignore | ||
readme.md = readme.md | ||
EndProjectSection | ||
EndProject | ||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build Config", "Build Config", "{688F10E7-1CEB-412E-A9A8-8BD16F2BDED5}" | ||
ProjectSection(SolutionItems) = preProject | ||
Directory.Build.props = Directory.Build.props | ||
Directory.Packages.props = Directory.Packages.props | ||
global.json = global.json | ||
NuGet.config = NuGet.config | ||
EndProjectSection | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dispownership.Test", "Dispownership.Test\Dispownership.Test.csproj", "{A1F6A514-4CC2-49E8-B4CF-D731692EE463}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{0FC69541-37D7-4E58-A80B-2E8B8217A906}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{0FC69541-37D7-4E58-A80B-2E8B8217A906}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{0FC69541-37D7-4E58-A80B-2E8B8217A906}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{0FC69541-37D7-4E58-A80B-2E8B8217A906}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{B3926389-9766-4C06-ADDF-C46C0FFFDEE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{B3926389-9766-4C06-ADDF-C46C0FFFDEE2}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{B3926389-9766-4C06-ADDF-C46C0FFFDEE2}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{B3926389-9766-4C06-ADDF-C46C0FFFDEE2}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{A1F6A514-4CC2-49E8-B4CF-D731692EE463}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{A1F6A514-4CC2-49E8-B4CF-D731692EE463}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{A1F6A514-4CC2-49E8-B4CF-D731692EE463}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{A1F6A514-4CC2-49E8-B4CF-D731692EE463}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#pragma warning disable SA1201 | ||
#pragma warning disable IDE0005 // Disable unused usings warning if enabled in consuming project | ||
|
||
#if (NETSTANDARD2_1 || NET5_0_OR_GREATER) && DISPOWNERSHIP_ASYNC | ||
using System; | ||
using System.Threading.Tasks; | ||
|
||
namespace Dispownership; | ||
|
||
#if DISPOWNERSHIP_VISIBILITY_PUBLIC | ||
public | ||
#else | ||
internal | ||
#endif | ||
static class AsyncDisposable | ||
{ | ||
/// <summary>Creates a owned wrapper around a disposable i.e. the disposable will be disposed when the wrapper is disposed.</summary> | ||
public static AsyncDisposable<TDisposable> Owned<TDisposable>(TDisposable value) | ||
where TDisposable : IAsyncDisposable | ||
=> new(value, hasOwnership: true); | ||
|
||
/// <summary>Creates a borrowing wrapper around a disposable i.e. the disposable will not be disposed when the wrapper is disposed.</summary> | ||
public static AsyncDisposable<TDisposable> Borrowed<TDisposable>(TDisposable value) | ||
where TDisposable : IAsyncDisposable | ||
=> new(value, hasOwnership: false); | ||
} | ||
|
||
/// <summary>A wrapper around an <see cref="IAsyncDisposable"/> that either owns or borrows the value. | ||
/// Use <see cref="AsyncDisposable.Owned{TDisposable}"/> or <see cref="AsyncDisposable.Borrowed{TDisposable}"/> to create an instance of this wrapper.</summary> | ||
#if DISPOWNERSHIP_VISIBILITY_PUBLIC | ||
public | ||
#else | ||
internal | ||
#endif | ||
struct AsyncDisposable<TDisposable> : IAsyncDisposable | ||
where TDisposable : IAsyncDisposable | ||
{ | ||
private readonly TDisposable _inner; | ||
private bool _hasOwnership; | ||
|
||
internal AsyncDisposable(TDisposable inner, bool hasOwnership) | ||
{ | ||
_inner = inner; | ||
_hasOwnership = hasOwnership; | ||
} | ||
|
||
public TDisposable Value => _inner; | ||
|
||
/// <summary>Consumes the value leaving this wrapper without ownership. | ||
/// This is useful in scenarios where you want to create a disposable, do some work that might fail and then return it.</summary> | ||
/// <exception cref="InvalidOperationException">Thrown when this instance does not have ownership over the disposable.</exception> | ||
public TDisposable Take() | ||
{ | ||
if (!_hasOwnership) | ||
{ | ||
throw new InvalidOperationException( | ||
$"Value can only be consumed when owned. " + | ||
$"This error may occur if you call {nameof(Take)} more than once"); | ||
} | ||
|
||
_hasOwnership = false; | ||
return _inner; | ||
} | ||
|
||
#pragma warning disable IDISP007 | ||
public ValueTask DisposeAsync() | ||
=> _hasOwnership | ||
? (_inner?.DisposeAsync() ?? default) | ||
: default; | ||
#pragma warning restore IDISP007 | ||
} | ||
#endif |
Oops, something went wrong.