Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
<ItemGroup>
<PackageVersion Include="FluentAssertions" Version="[7.2.0]" />
<PackageVersion Include="Light.GuardClauses" Version="13.0.0" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Neovolve.Logging.Xunit.v3" Version="7.1.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.1" />
<PackageVersion Include="xunit.v3" Version="2.0.3" />
</ItemGroup>
Expand Down
36 changes: 36 additions & 0 deletions Light.TemporaryStreams.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{048D0C61-6CF0-43E6-B7DB-1FDD8F791D57}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{DA93B299-75F5-4A49-B2A6-4A1247047E5E}"
ProjectSection(SolutionItems) = preProject
tests\Directory.Build.props = tests\Directory.Build.props
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Light.TemporaryStreams", "src\Light.TemporaryStreams\Light.TemporaryStreams.csproj", "{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Light.TemporaryStreams.Tests", "tests\Light.TemporaryStreams.Tests\Light.TemporaryStreams.Tests.csproj", "{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -62,6 +72,30 @@ Global
{4D6B4F48-1E4B-4ACA-9F32-829442DB5E56}.Release|x64.Build.0 = Release|Any CPU
{4D6B4F48-1E4B-4ACA-9F32-829442DB5E56}.Release|x86.ActiveCfg = Release|Any CPU
{4D6B4F48-1E4B-4ACA-9F32-829442DB5E56}.Release|x86.Build.0 = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|x64.ActiveCfg = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|x64.Build.0 = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|x86.ActiveCfg = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Debug|x86.Build.0 = Debug|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|Any CPU.Build.0 = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|x64.ActiveCfg = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|x64.Build.0 = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|x86.ActiveCfg = Release|Any CPU
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1}.Release|x86.Build.0 = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|x64.ActiveCfg = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|x64.Build.0 = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|x86.ActiveCfg = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Debug|x86.Build.0 = Debug|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|Any CPU.Build.0 = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|x64.ActiveCfg = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|x64.Build.0 = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|x86.ActiveCfg = Release|Any CPU
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -70,5 +104,7 @@ Global
{05D48EEC-A2AB-4143-9533-A633E7B25EA3} = {677E4EE1-7062-46AB-81FF-8D20E9316ED6}
{C86E6D31-A10A-4B61-B490-5A7AC4451BA5} = {048D0C61-6CF0-43E6-B7DB-1FDD8F791D57}
{4D6B4F48-1E4B-4ACA-9F32-829442DB5E56} = {DA93B299-75F5-4A49-B2A6-4A1247047E5E}
{61725DD8-D81C-4EC0-A0A1-63D96A87DAC1} = {048D0C61-6CF0-43E6-B7DB-1FDD8F791D57}
{93CCDAD2-A16A-4BA3-A805-4FC7C4B518C8} = {DA93B299-75F5-4A49-B2A6-4A1247047E5E}
EndGlobalSection
EndGlobal
13 changes: 13 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project>
<PropertyGroup>
<ParentPropsFile>$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))</ParentPropsFile>
</PropertyGroup>

<Import Project="$(ParentPropsFile)" />

<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IsAotCompatible>true</IsAotCompatible>
<RootNamespace>Light.TemporaryStreams</RootNamespace>
</PropertyGroup>
</Project>
3 changes: 2 additions & 1 deletion src/Light.TemporaryStreams.Core/Hashing/HashingPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public async ValueTask DisposeAsync()
public ValueTask<Stream> SetUpAsync(Stream innerStream, CancellationToken cancellationToken = default)
{
innerStream.MustNotBeNull();
Stream currentStream = innerStream;
cancellationToken.ThrowIfCancellationRequested();
var currentStream = innerStream;
for (var i = 0; i < HashCalculators.Length; i++)
{
currentStream = HashCalculators[i].CreateWrappingCryptoStream(currentStream, leaveWrappedStreamOpen: true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IsAotCompatible>true</IsAotCompatible>
<RootNamespace>Light.TemporaryStreams</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Light.GuardClauses" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ public sealed class TemporaryStreamErrorHandlerProvider
{
private readonly Action<TemporaryStream, Exception>? _errorHandler;


/// <summary>
/// Initializes a new instance of <see cref="TemporaryStreamErrorHandlerProvider" />.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions src/Light.TemporaryStreams/Light.TemporaryStreams.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Light.TemporaryStreams.Core\Light.TemporaryStreams.Core.csproj" />
</ItemGroup>

</Project>
29 changes: 29 additions & 0 deletions src/Light.TemporaryStreams/MicrosoftLoggingExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Microsoft.Extensions.Logging;

namespace Light.TemporaryStreams;

/// <summary>
/// Provides extension methods for <see cref="ILogger" /> that are specifically designed for use with the
/// <see cref="TemporaryStreamService" />.
/// </summary>
public static partial class MicrosoftLoggingExtensions
{
/// <summary>
/// Logs an error message when an exception occurs while deleting a temporary stream.
/// </summary>
/// <param name="logger">The logger to write the error message to.</param>
/// <param name="exception">The exception that occurred.</param>
/// <param name="temporaryStreamFilePath">The file path of the temporary stream.</param>
[LoggerMessage(
EventId = 1001,
Level = LogLevel.Error,
Message = "An error occurred while deleting the temporary stream '{TemporaryStreamFilePath}'"
)
]
public static partial void LogErrorDeletingTemporaryStream(
this ILogger logger,
Exception exception,
string temporaryStreamFilePath
);
}
71 changes: 71 additions & 0 deletions src/Light.TemporaryStreams/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
using System;
using Light.GuardClauses;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;

namespace Light.TemporaryStreams;

/// <summary>
/// Provides extension methods for <see cref="IServiceCollection" /> to register <see cref="TemporaryStreamService" />
/// and corresponding dependencies.
/// </summary>
public static class ServiceCollectionExtensions
{
/// <summary>
/// Adds the <see cref="TemporaryStreamService" /> to the specified <see cref="IServiceCollection" />.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection" /> to add the service to.</param>
/// <param name="createOptions">An optional delegate to create the <see cref="TemporaryStreamServiceOptions" />.</param>
/// <param name="integrateIntoMicrosoftExtensionsLogging">
/// When true, the <see cref="TemporaryStreamErrorHandlerProvider" /> returns a delegate which logs exceptions
/// that occur during the deletion of temporary streams to Microsoft.Extensions.Logging. If false, the provider
/// will simply return null and logging will occur against the .NET Trace.
/// </param>
/// <returns>The <see cref="IServiceCollection" /> so that additional calls can be chained.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="services" /> is null.</exception>
public static IServiceCollection AddTemporaryStreamService(
this IServiceCollection services,
Func<IServiceProvider, TemporaryStreamServiceOptions>? createOptions = null,
bool integrateIntoMicrosoftExtensionsLogging = true
)
{
services.MustNotBeNull();
if (createOptions is null)
{
services.TryAddSingleton<TemporaryStreamServiceOptions>();
}
else
{
services.TryAddSingleton(createOptions);
}

if (integrateIntoMicrosoftExtensionsLogging)
{
services.TryAddSingleton<TemporaryStreamErrorHandlerProvider>(
sp =>
{
var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
var logger = loggerFactory.CreateLogger(nameof(TemporaryStreamService));
return new TemporaryStreamErrorHandlerProvider(
(stream, exception) =>
logger.LogErrorDeletingTemporaryStream(
exception,
stream.GetUnderlyingFilePath()
)
);
}
);
}
else
{
services.TryAddSingleton<TemporaryStreamErrorHandlerProvider>(
_ => new TemporaryStreamErrorHandlerProvider(null)
);
}

services.TryAddSingleton<TemporaryStreamService>();
services.TryAddSingleton<ITemporaryStreamService>(sp => sp.GetRequiredService<TemporaryStreamService>());
return services;
}
}
40 changes: 40 additions & 0 deletions src/Light.TemporaryStreams/packages.lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"version": 2,
"dependencies": {
"net8.0": {
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg=="
},
"Microsoft.Extensions.Logging.Abstractions": {
"type": "Direct",
"requested": "[8.0.0, )",
"resolved": "8.0.0",
"contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
}
},
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
"requested": "[8.0.17, )",
"resolved": "8.0.17",
"contentHash": "x5/y4l8AtshpBOrCZdlE4txw8K3e3s9meBFeZeR3l8hbbku2V7kK6ojhXvrbjg1rk3G+JqL1BI26gtgc1ZrdUw=="
},
"light.temporarystreams.core": {
"type": "Project",
"dependencies": {
"Light.GuardClauses": "[13.0.0, )"
}
},
"Light.GuardClauses": {
"type": "CentralTransitive",
"requested": "[13.0.0, )",
"resolved": "13.0.0",
"contentHash": "mhlWUk0o+XibJgYuPlO9vQQpMmh4EAeDRFAac7pP6W3zmpjEeyUVGOiw+mdCxX469QQ2rkMYjWyHoDlZv599/w=="
}
}
}
}
23 changes: 23 additions & 0 deletions tests/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project>
<PropertyGroup>
<ParentPropsFile>$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))</ParentPropsFile>
</PropertyGroup>

<Import Project="$(ParentPropsFile)" />

<PropertyGroup>
<OutputType>Exe</OutputType>
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
<RootNamespace>Light.TemporaryStreams</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="FluentAssertions" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static async Task HashArray_ShouldThrow_WhenObtainHashFromAlgorithmWasNot
[Fact]
public static async Task ObtainHashFromAlgorithm_ShouldThrow_WhenNothingWasWrittenToUnderlyingCryptoStream()
{
await using CopyToHashCalculator calculator = SHA3_512.Create();
await using CopyToHashCalculator calculator = SHA1.Create();

// ReSharper disable once AccessToDisposedClosure -- delegate called before calculator is disposed of
var act = () => calculator.ObtainHashFromAlgorithm();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
<RootNamespace>Light.TemporaryStreams</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.runner.visualstudio" />
<PackageReference Include="FluentAssertions" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Light.TemporaryStreams.Core\Light.TemporaryStreams.Core.csproj" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\src\Light.TemporaryStreams\Light.TemporaryStreams.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Neovolve.Logging.Xunit.v3" />
</ItemGroup>

<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
Loading