Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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