diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 7f98da7f1a..575923d62c 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2023.3.0-eap08", + "version": "2023.3.2", "commands": [ "jb" ] @@ -27,4 +27,4 @@ ] } } -} +} \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d7442a3c9..eb3aab63b2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,10 +23,6 @@ concurrency: env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true DOTNET_CLI_TELEMETRY_OPTOUT: true - # The Windows runner image has PostgreSQL pre-installed and sets the PGPASSWORD environment variable to "root". - # This conflicts with the default password "postgres", which is used by ikalnytskyi/action-setup-postgres. - # Because action-setup-postgres forgets to update the environment variable accordingly, we do so here. - PGPASSWORD: "postgres" jobs: build-and-test: @@ -39,13 +35,15 @@ jobs: permissions: contents: read steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 - name: Setup PostgreSQL - uses: ikalnytskyi/action-setup-postgres@v4 + uses: ikalnytskyi/action-setup-postgres@v5 with: username: postgres password: postgres - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x @@ -105,6 +103,7 @@ jobs: [xml]$xml = Get-Content Directory.Build.props $configuredVersionPrefix = $xml.Project.PropertyGroup.JsonApiDotNetCoreVersionPrefix | Select-Object -First 1 + if ($configuredVersionPrefix -ne $versionPrefix) { Write-Error "Version prefix from git release tag '$versionPrefix' does not match version prefix '$configuredVersionPrefix' stored in Directory.Build.props." # To recover from this: @@ -128,6 +127,13 @@ jobs: run: | dotnet build --no-restore --configuration Release /p:VersionSuffix=$env:PACKAGE_VERSION_SUFFIX - name: Test + env: + # Override log levels, to reduce logging output when running tests in ci-build. + Logging__LogLevel__Microsoft.Hosting.Lifetime: 'None' + Logging__LogLevel__Microsoft.AspNetCore.Hosting.Diagnostics: 'None' + Logging__LogLevel__Microsoft.Extensions.Hosting.Internal.Host: 'None' + Logging__LogLevel__Microsoft.EntityFrameworkCore.Database.Command: 'None' + Logging__LogLevel__JsonApiDotNetCore: 'None' run: | dotnet test --no-build --configuration Release --collect:"XPlat Code Coverage" --logger "GitHubActions;summary.includeSkippedTests=true" - name: Upload coverage to codecov.io @@ -142,7 +148,7 @@ jobs: dotnet pack --no-build --configuration Release --output $env:GITHUB_WORKSPACE/artifacts/packages /p:VersionSuffix=$env:PACKAGE_VERSION_SUFFIX - name: Upload packages to artifacts if: matrix.os == 'ubuntu-latest' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: packages path: artifacts/packages @@ -165,7 +171,7 @@ jobs: Copy-Item -Recurse home/assets/* _site/styles/ - name: Upload documentation to artifacts if: matrix.os == 'ubuntu-latest' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: documentation path: docs/_site @@ -180,8 +186,10 @@ jobs: permissions: contents: read steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x @@ -196,7 +204,7 @@ jobs: run: | $inspectCodeOutputPath = Join-Path $env:RUNNER_TEMP 'jetbrains-inspectcode-results.xml' Write-Output "INSPECT_CODE_OUTPUT_PATH=$inspectCodeOutputPath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append - dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal + dotnet jb inspectcode JsonApiDotNetCore.sln --build --dotnetcoresdk=$(dotnet --version) --output="$inspectCodeOutputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:ContinuousIntegrationBuild=false --properties:RunAnalyzers=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal - name: Verify outcome shell: pwsh run: | @@ -233,8 +241,10 @@ jobs: permissions: contents: read steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x @@ -259,13 +269,13 @@ jobs: $baseCommitHash = git rev-parse HEAD~1 Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash in pull request." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN -f commits -a $headCommitHash -b $baseCommitHash --fail-on-diff --print-diff - name: CleanupCode (on branch) if: github.event_name == 'push' || github.event_name == 'release' shell: pwsh run: | Write-Output "Running code cleanup on all files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN --fail-on-diff --print-diff + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN --fail-on-diff --print-diff publish: timeout-minutes: 60 @@ -276,8 +286,10 @@ jobs: packages: write contents: write steps: + - name: Tune GitHub-hosted runner network + uses: smorimoto/tune-github-hosted-runner-network@v1 - name: Download artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Publish to GitHub Packages if: github.event_name == 'push' || github.event_name == 'release' env: diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5b1868eae5..eb0375769e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -24,7 +24,7 @@ jobs: language: [ 'csharp' ] steps: - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: dotnet-version: | 6.0.x @@ -32,12 +32,12 @@ jobs: - name: Git checkout uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/qodana.yml b/.github/workflows/qodana.yml index 9225d9f816..f1a64da824 100644 --- a/.github/workflows/qodana.yml +++ b/.github/workflows/qodana.yml @@ -22,12 +22,12 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} # to check out the actual pull request commit, not the merge commit fetch-depth: 0 # a full history is required for pull request analysis - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2023.2 + uses: JetBrains/qodana-action@v2023.3 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} - name: Upload results to artifacts on failure if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: qodana_results path: ${{ runner.temp }}/qodana/results diff --git a/Directory.Build.props b/Directory.Build.props index cdd3c5d232..0c2b51e13b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -27,6 +27,6 @@ false $(MSBuildThisFileDirectory)CodingGuidelines.ruleset $(MSBuildThisFileDirectory)tests.runsettings - 5.5.0 + 5.5.1 diff --git a/JsonApiDotNetCore.sln b/JsonApiDotNetCore.sln index e821d4175d..c555610364 100644 --- a/JsonApiDotNetCore.sln +++ b/JsonApiDotNetCore.sln @@ -10,11 +10,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig .gitignore = .gitignore + .github\workflows\build.yml = .github\workflows\build.yml CodingGuidelines.ruleset = CodingGuidelines.ruleset CSharpGuidelinesAnalyzer.config = CSharpGuidelinesAnalyzer.config Directory.Build.props = Directory.Build.props - tests.runsettings = tests.runsettings package-versions.props = package-versions.props + tests.runsettings = tests.runsettings EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{026FBC6C-AF76-4568-9B87-EC73457899FD}" diff --git a/JsonApiDotNetCore.sln.DotSettings b/JsonApiDotNetCore.sln.DotSettings index a945c3a40d..6e4e064588 100644 --- a/JsonApiDotNetCore.sln.DotSettings +++ b/JsonApiDotNetCore.sln.DotSettings @@ -54,6 +54,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); WARNING WARNING WARNING + DO_NOT_SHOW WARNING SUGGESTION HINT @@ -95,6 +96,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); SUGGESTION SUGGESTION WARNING + True SUGGESTION <?xml version="1.0" encoding="utf-16"?><Profile name="JADNC Full Cleanup"><XMLReformatCode>True</XMLReformatCode><CSCodeStyleAttributes ArrangeTypeAccessModifier="True" ArrangeTypeMemberAccessModifier="True" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="True" ArrangeBraces="True" ArrangeAttributes="True" ArrangeArgumentsStyle="True" ArrangeCodeBodyStyle="True" ArrangeVarStyle="True" ArrangeTrailingCommas="True" ArrangeObjectCreation="True" ArrangeDefaultValue="True" ArrangeNamespaces="True" ArrangeNullCheckingPattern="True" /><CssAlphabetizeProperties>True</CssAlphabetizeProperties><JsInsertSemicolon>True</JsInsertSemicolon><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><CorrectVariableKindsDescriptor>True</CorrectVariableKindsDescriptor><VariablesToInnerScopesDescriptor>True</VariablesToInnerScopesDescriptor><StringToTemplatesDescriptor>True</StringToTemplatesDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><ExplicitAnyTs>True</ExplicitAnyTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><AsInsteadOfCastTs>True</AsInsteadOfCastTs><HtmlReformatCode>True</HtmlReformatCode><AspOptimizeRegisterDirectives>True</AspOptimizeRegisterDirectives><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSMakeAutoPropertyGetOnly>True</CSMakeAutoPropertyGetOnly><CSArrangeQualifiers>True</CSArrangeQualifiers><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CssReformatCode>True</CssReformatCode><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSReorderTypeMembers>True</CSReorderTypeMembers><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSReformatInactiveBranches>True</CSReformatInactiveBranches></Profile> JADNC Full Cleanup @@ -154,6 +156,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$); WRAP_IF_LONG CHOP_ALWAYS CHOP_ALWAYS + WRAP_IF_LONG True True 2 diff --git a/WarningSeverities.DotSettings b/WarningSeverities.DotSettings index 5c641e606f..a0fae5acd2 100644 --- a/WarningSeverities.DotSettings +++ b/WarningSeverities.DotSettings @@ -69,6 +69,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -122,6 +123,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING @@ -196,6 +198,7 @@ WARNING WARNING WARNING + WARNING WARNING WARNING WARNING diff --git a/benchmarks/Program.cs b/benchmarks/Program.cs index 818b9ab5e5..b1e3307931 100644 --- a/benchmarks/Program.cs +++ b/benchmarks/Program.cs @@ -9,14 +9,13 @@ internal static class Program { private static void Main(string[] args) { - var switcher = new BenchmarkSwitcher(new[] - { + var switcher = new BenchmarkSwitcher([ typeof(ResourceDeserializationBenchmarks), typeof(OperationsDeserializationBenchmarks), typeof(ResourceSerializationBenchmarks), typeof(OperationsSerializationBenchmarks), typeof(QueryStringParserBenchmarks) - }); + ]); switcher.Run(args); } diff --git a/cleanupcode.ps1 b/cleanupcode.ps1 index 3ab4d620ae..b35d1cb215 100644 --- a/cleanupcode.ps1 +++ b/cleanupcode.ps1 @@ -28,17 +28,17 @@ if ($revision) { if ($baseCommitHash -eq $headCommitHash) { Write-Output "Running code cleanup on staged/unstaged files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN -f staged,modified VerifySuccessExitCode } else { Write-Output "Running code cleanup on commit range $baseCommitHash..$headCommitHash, including staged/unstaged files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN -f staged,modified,commits -a $headCommitHash -b $baseCommitHash + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --max-runs=5 --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN -f staged,modified,commits -a $headCommitHash -b $baseCommitHash VerifySuccessExitCode } } else { Write-Output "Running code cleanup on all files." - dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --verbosity=WARN + dotnet regitlint -s JsonApiDotNetCore.sln --print-command --skip-tool-check --jb --dotnetcoresdk=$(dotnet --version) --jb-profile="JADNC Full Cleanup" --jb --properties:Configuration=Release --jb --properties:RunAnalyzers=false --jb --verbosity=WARN VerifySuccessExitCode } diff --git a/inspectcode.ps1 b/inspectcode.ps1 index 14c3eb1736..aa816da5e9 100644 --- a/inspectcode.ps1 +++ b/inspectcode.ps1 @@ -10,7 +10,7 @@ if ($LastExitCode -ne 0) { $outputPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'jetbrains-inspectcode-results.xml') $resultPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'jetbrains-inspectcode-results.html') -dotnet jb inspectcode JsonApiDotNetCore.sln --dotnetcoresdk=$(dotnet --version) --build --output="$outputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal +dotnet jb inspectcode JsonApiDotNetCore.sln --dotnetcoresdk=$(dotnet --version) --build --output="$outputPath" --profile=WarningSeverities.DotSettings --properties:Configuration=Release --properties:RunAnalyzers=false --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=GlobalPerProduct -dsl=SolutionPersonal -dsl=ProjectPersonal if ($LastExitCode -ne 0) { throw "Code inspection failed with exit code $LastExitCode" diff --git a/package-versions.props b/package-versions.props index dd842f59f6..07bbfed960 100644 --- a/package-versions.props +++ b/package-versions.props @@ -7,16 +7,17 @@ 0.13.* - 34.0.* - 4.7.* + 35.2.* + 4.8.* 6.0.* 2.1.* 6.12.* 2.3.* - 1.3.* + 2.0.* 8.0.* 17.8.* - 2.5.* + 2.6.* + 2.5.* diff --git a/src/Examples/DapperExample/Controllers/OperationsController.cs b/src/Examples/DapperExample/Controllers/OperationsController.cs index 979e6c9cd7..6fe0eedd1d 100644 --- a/src/Examples/DapperExample/Controllers/OperationsController.cs +++ b/src/Examples/DapperExample/Controllers/OperationsController.cs @@ -6,11 +6,6 @@ namespace DapperExample.Controllers; -public sealed class OperationsController : JsonApiOperationsController -{ - public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } -} +public sealed class OperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields); diff --git a/src/Examples/DapperExample/Data/RotatingList.cs b/src/Examples/DapperExample/Data/RotatingList.cs index 67c19bea4a..278c34140a 100644 --- a/src/Examples/DapperExample/Data/RotatingList.cs +++ b/src/Examples/DapperExample/Data/RotatingList.cs @@ -16,16 +16,11 @@ public static RotatingList Create(int count, Func createElement) } } -internal sealed class RotatingList +internal sealed class RotatingList(IList elements) { private int _index = -1; - public IList Elements { get; } - - public RotatingList(IList elements) - { - Elements = elements; - } + public IList Elements { get; } = elements; public T GetNext() { diff --git a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs index 61421d7331..4352b6c552 100644 --- a/src/Examples/DapperExample/Repositories/ResultSetMapper.cs +++ b/src/Examples/DapperExample/Repositories/ResultSetMapper.cs @@ -166,14 +166,9 @@ public IReadOnlyCollection GetResources() return _primaryResourcesInOrder.DistinctBy(resource => resource.Id).ToList(); } - private sealed class IncludeElementWalker + private sealed class IncludeElementWalker(IncludeExpression include) { - private readonly IncludeExpression _include; - - public IncludeElementWalker(IncludeExpression include) - { - _include = include; - } + private readonly IncludeExpression _include = include; public IEnumerable BreadthFirstEnumerate() { diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/DeleteOneToOneStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/DeleteOneToOneStatementBuilder.cs index 5a1293d41b..3ea368b299 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/DeleteOneToOneStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/DeleteOneToOneStatementBuilder.cs @@ -6,13 +6,8 @@ namespace DapperExample.TranslationToSql.Builders; -internal sealed class DeleteOneToOneStatementBuilder : StatementBuilder +internal sealed class DeleteOneToOneStatementBuilder(IDataModelService dataModelService) : StatementBuilder(dataModelService) { - public DeleteOneToOneStatementBuilder(IDataModelService dataModelService) - : base(dataModelService) - { - } - public DeleteNode Build(ResourceType resourceType, string whereColumnName, object? whereValue) { ArgumentGuard.NotNull(resourceType); diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/DeleteResourceStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/DeleteResourceStatementBuilder.cs index 41794e8883..1910075a8c 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/DeleteResourceStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/DeleteResourceStatementBuilder.cs @@ -6,13 +6,8 @@ namespace DapperExample.TranslationToSql.Builders; -internal sealed class DeleteResourceStatementBuilder : StatementBuilder +internal sealed class DeleteResourceStatementBuilder(IDataModelService dataModelService) : StatementBuilder(dataModelService) { - public DeleteResourceStatementBuilder(IDataModelService dataModelService) - : base(dataModelService) - { - } - public DeleteNode Build(ResourceType resourceType, params object[] idValues) { ArgumentGuard.NotNull(resourceType); diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs index 7e444b45a1..5f8374df65 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/InsertStatementBuilder.cs @@ -6,13 +6,8 @@ namespace DapperExample.TranslationToSql.Builders; -internal sealed class InsertStatementBuilder : StatementBuilder +internal sealed class InsertStatementBuilder(IDataModelService dataModelService) : StatementBuilder(dataModelService) { - public InsertStatementBuilder(IDataModelService dataModelService) - : base(dataModelService) - { - } - public InsertNode Build(ResourceType resourceType, IReadOnlyDictionary columnsToSet) { ArgumentGuard.NotNull(resourceType); diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs index 3e3d48eb10..a082d3ecad 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/SqlQueryBuilder.cs @@ -8,7 +8,7 @@ namespace DapperExample.TranslationToSql.Builders; /// /// Converts s into SQL text. /// -internal sealed class SqlQueryBuilder : SqlTreeNodeVisitor +internal sealed class SqlQueryBuilder(DatabaseProvider databaseProvider) : SqlTreeNodeVisitor { private static readonly char[] SpecialCharactersInLikeDefault = [ @@ -26,7 +26,7 @@ internal sealed class SqlQueryBuilder : SqlTreeNodeVisitor _parametersByName = []; private int _indentDepth; @@ -35,11 +35,6 @@ internal sealed class SqlQueryBuilder : SqlTreeNodeVisitor Parameters => _parametersByName.Values.ToDictionary(parameter => parameter.Name, parameter => parameter.Value); - public SqlQueryBuilder(DatabaseProvider databaseProvider) - { - _databaseProvider = databaseProvider; - } - public string GetCommand(SqlTreeNode node) { ArgumentGuard.NotNull(node); @@ -488,14 +483,9 @@ private IDisposable Indent() return new RevertIndentOnDispose(this); } - private sealed class RevertIndentOnDispose : IDisposable + private sealed class RevertIndentOnDispose(SqlQueryBuilder owner) : IDisposable { - private readonly SqlQueryBuilder _owner; - - public RevertIndentOnDispose(SqlQueryBuilder owner) - { - _owner = owner; - } + private readonly SqlQueryBuilder _owner = owner; public void Dispose() { diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs index 4ccc5fec9a..712561528d 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateClearOneToOneStatementBuilder.cs @@ -6,13 +6,8 @@ namespace DapperExample.TranslationToSql.Builders; -internal sealed class UpdateClearOneToOneStatementBuilder : StatementBuilder +internal sealed class UpdateClearOneToOneStatementBuilder(IDataModelService dataModelService) : StatementBuilder(dataModelService) { - public UpdateClearOneToOneStatementBuilder(IDataModelService dataModelService) - : base(dataModelService) - { - } - public UpdateNode Build(ResourceType resourceType, string setColumnName, string whereColumnName, object? whereValue) { ArgumentGuard.NotNull(resourceType); diff --git a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs index 62fc3b7e20..a279ad45e5 100644 --- a/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs +++ b/src/Examples/DapperExample/TranslationToSql/Builders/UpdateResourceStatementBuilder.cs @@ -6,13 +6,8 @@ namespace DapperExample.TranslationToSql.Builders; -internal sealed class UpdateResourceStatementBuilder : StatementBuilder +internal sealed class UpdateResourceStatementBuilder(IDataModelService dataModelService) : StatementBuilder(dataModelService) { - public UpdateResourceStatementBuilder(IDataModelService dataModelService) - : base(dataModelService) - { - } - public UpdateNode Build(ResourceType resourceType, IReadOnlyDictionary columnsToUpdate, params object[] idValues) { ArgumentGuard.NotNull(resourceType); diff --git a/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs b/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs index 0f030debdb..b0ba38f3a5 100644 --- a/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs +++ b/src/Examples/DapperExample/TranslationToSql/DataModel/FromEntitiesDataModelService.cs @@ -12,7 +12,7 @@ namespace DapperExample.TranslationToSql.DataModel; /// /// Derives foreign keys and connection strings from an existing Entity Framework Core model. /// -public sealed class FromEntitiesDataModelService : BaseDataModelService +public sealed class FromEntitiesDataModelService(IResourceGraph resourceGraph) : BaseDataModelService(resourceGraph) { private readonly Dictionary _foreignKeysByRelationship = []; private readonly Dictionary _columnNullabilityPerAttribute = []; @@ -21,11 +21,6 @@ public sealed class FromEntitiesDataModelService : BaseDataModelService public override DatabaseProvider DatabaseProvider => AssertHasDatabaseProvider(); - public FromEntitiesDataModelService(IResourceGraph resourceGraph) - : base(resourceGraph) - { - } - public void Initialize(DbContext dbContext) { _connectionString = dbContext.Database.GetConnectionString(); diff --git a/src/Examples/DapperExample/TranslationToSql/Generators/ParameterGenerator.cs b/src/Examples/DapperExample/TranslationToSql/Generators/ParameterGenerator.cs index bd4df111fc..aaa328e68f 100644 --- a/src/Examples/DapperExample/TranslationToSql/Generators/ParameterGenerator.cs +++ b/src/Examples/DapperExample/TranslationToSql/Generators/ParameterGenerator.cs @@ -20,11 +20,5 @@ public void Reset() _nameGenerator.Reset(); } - private sealed class ParameterNameGenerator : UniqueNameGenerator - { - public ParameterNameGenerator() - : base("@p") - { - } - } + private sealed class ParameterNameGenerator() : UniqueNameGenerator("@p"); } diff --git a/src/Examples/DapperExample/TranslationToSql/Generators/TableAliasGenerator.cs b/src/Examples/DapperExample/TranslationToSql/Generators/TableAliasGenerator.cs index 39d5d9d702..a63bfdc01a 100644 --- a/src/Examples/DapperExample/TranslationToSql/Generators/TableAliasGenerator.cs +++ b/src/Examples/DapperExample/TranslationToSql/Generators/TableAliasGenerator.cs @@ -3,10 +3,4 @@ namespace DapperExample.TranslationToSql.Generators; /// /// Generates a SQL table alias with a unique name. /// -internal sealed class TableAliasGenerator : UniqueNameGenerator -{ - public TableAliasGenerator() - : base("t") - { - } -} +internal sealed class TableAliasGenerator() : UniqueNameGenerator("t"); diff --git a/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs b/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs index 03692baf2d..a632c43e51 100644 --- a/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs +++ b/src/Examples/DapperExample/TranslationToSql/Transformations/StaleColumnReferenceRewriter.cs @@ -290,14 +290,9 @@ private IReadOnlyList VisitList(IEnumerable nodes, ColumnVisitMode mode return nodes.Select(element => TypedVisit(element, mode)).ToList(); } - private sealed class PopStackOnDispose : IDisposable + private sealed class PopStackOnDispose(Stack stack) : IDisposable { - private readonly Stack _stack; - - public PopStackOnDispose(Stack stack) - { - _stack = stack; - } + private readonly Stack _stack = stack; public void Dispose() { diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInSelectNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInSelectNode.cs index e4b79fe7eb..2be0561011 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInSelectNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInSelectNode.cs @@ -10,18 +10,13 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// SELECT t2.Id AS Id0 FROM (SELECT t1.Id FROM Users AS t1) AS t2 /// ]]>. /// -internal sealed class ColumnInSelectNode : ColumnNode +internal sealed class ColumnInSelectNode(ColumnSelectorNode selector, string? tableAlias) : ColumnNode(GetColumnName(selector), selector.Column.Type, + tableAlias) { - public ColumnSelectorNode Selector { get; } + public ColumnSelectorNode Selector { get; } = selector; public bool IsVirtual => Selector.Alias != null || Selector.Column is ColumnInSelectNode { IsVirtual: true }; - public ColumnInSelectNode(ColumnSelectorNode selector, string? tableAlias) - : base(GetColumnName(selector), selector.Column.Type, tableAlias) - { - Selector = selector; - } - private static string GetColumnName(ColumnSelectorNode selector) { ArgumentGuard.NotNull(selector); diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInTableNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInTableNode.cs index 8e8aab29ce..cd605e72a4 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInTableNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/ColumnInTableNode.cs @@ -8,13 +8,8 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// FROM Users AS t1 /// ]]>. /// -internal sealed class ColumnInTableNode : ColumnNode +internal sealed class ColumnInTableNode(string name, ColumnType type, string? tableAlias) : ColumnNode(name, type, tableAlias) { - public ColumnInTableNode(string name, ColumnType type, string? tableAlias) - : base(name, type, tableAlias) - { - } - public override TResult Accept(SqlTreeNodeVisitor visitor, TArgument argument) { return visitor.VisitColumnInTable(this, argument); diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/CountSelectorNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/CountSelectorNode.cs index 07ad67f144..d0b9e18ca2 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/CountSelectorNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/CountSelectorNode.cs @@ -8,13 +8,8 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// SELECT COUNT(*) FROM Users /// ]]>. /// -internal sealed class CountSelectorNode : SelectorNode +internal sealed class CountSelectorNode(string? alias) : SelectorNode(alias) { - public CountSelectorNode(string? alias) - : base(alias) - { - } - public override TResult Accept(SqlTreeNodeVisitor visitor, TArgument argument) { return visitor.VisitCountSelector(this, argument); diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/FromNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/FromNode.cs index 8ec4ab5c20..3d29636212 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/FromNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/FromNode.cs @@ -5,13 +5,8 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// FROM Customers AS t1 /// ]]>. /// -internal sealed class FromNode : TableAccessorNode +internal sealed class FromNode(TableSourceNode source) : TableAccessorNode(source) { - public FromNode(TableSourceNode source) - : base(source) - { - } - public override TResult Accept(SqlTreeNodeVisitor visitor, TArgument argument) { return visitor.VisitFrom(this, argument); diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/OneSelectorNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/OneSelectorNode.cs index c86aea6d63..a9c05301a7 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/OneSelectorNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/OneSelectorNode.cs @@ -8,13 +8,8 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// SELECT 1 FROM Users /// ]]>. /// -internal sealed class OneSelectorNode : SelectorNode +internal sealed class OneSelectorNode(string? alias) : SelectorNode(alias) { - public OneSelectorNode(string? alias) - : base(alias) - { - } - public override TResult Accept(SqlTreeNodeVisitor visitor, TArgument argument) { return visitor.VisitOneSelector(this, argument); diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/OrderByTermNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/OrderByTermNode.cs index 2c3fc80b3e..89fb4c219d 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/OrderByTermNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/OrderByTermNode.cs @@ -3,12 +3,7 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// /// Represents the base type for terms in an . /// -internal abstract class OrderByTermNode : SqlTreeNode +internal abstract class OrderByTermNode(bool isAscending) : SqlTreeNode { - public bool IsAscending { get; } - - protected OrderByTermNode(bool isAscending) - { - IsAscending = isAscending; - } + public bool IsAscending { get; } = isAscending; } diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectorNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectorNode.cs index 8a47a8af66..44ee14ea17 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectorNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/SelectorNode.cs @@ -3,12 +3,7 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// /// Represents the base type for selectors in a . /// -internal abstract class SelectorNode : SqlTreeNode +internal abstract class SelectorNode(string? alias) : SqlTreeNode { - public string? Alias { get; } - - protected SelectorNode(string? alias) - { - Alias = alias; - } + public string? Alias { get; } = alias; } diff --git a/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableSourceNode.cs b/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableSourceNode.cs index 6628ed11dc..62ff5ad3ef 100644 --- a/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableSourceNode.cs +++ b/src/Examples/DapperExample/TranslationToSql/TreeNodes/TableSourceNode.cs @@ -5,17 +5,12 @@ namespace DapperExample.TranslationToSql.TreeNodes; /// /// Represents the base type for tabular data sources, such as database tables and sub-queries. /// -internal abstract class TableSourceNode : SqlTreeNode +internal abstract class TableSourceNode(string? alias) : SqlTreeNode { public const string IdColumnName = nameof(Identifiable.Id); public abstract IReadOnlyList Columns { get; } - public string? Alias { get; } - - protected TableSourceNode(string? alias) - { - Alias = alias; - } + public string? Alias { get; } = alias; public ColumnNode GetIdColumn(string? innerTableAlias) { diff --git a/src/Examples/DatabasePerTenantExample/Data/AppDbContext.cs b/src/Examples/DatabasePerTenantExample/Data/AppDbContext.cs index 40bf7e3f53..7ff84c8e41 100644 --- a/src/Examples/DatabasePerTenantExample/Data/AppDbContext.cs +++ b/src/Examples/DatabasePerTenantExample/Data/AppDbContext.cs @@ -8,21 +8,15 @@ namespace DatabasePerTenantExample.Data; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class AppDbContext : DbContext +public sealed class AppDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) + : DbContext(options) { - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly IConfiguration _configuration; + private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor; + private readonly IConfiguration _configuration = configuration; private string? _forcedTenantName; public DbSet Employees => Set(); - public AppDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) - : base(options) - { - _httpContextAccessor = httpContextAccessor; - _configuration = configuration; - } - public void SetTenantName(string tenantName) { _forcedTenantName = tenantName; diff --git a/src/Examples/GettingStarted/Data/SampleDbContext.cs b/src/Examples/GettingStarted/Data/SampleDbContext.cs index 44662c388b..5e65f8466e 100644 --- a/src/Examples/GettingStarted/Data/SampleDbContext.cs +++ b/src/Examples/GettingStarted/Data/SampleDbContext.cs @@ -5,12 +5,7 @@ namespace GettingStarted.Data; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public class SampleDbContext : DbContext +public class SampleDbContext(DbContextOptions options) : DbContext(options) { public DbSet Books => Set(); - - public SampleDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/src/Examples/JsonApiDotNetCoreExample/Controllers/OperationsController.cs b/src/Examples/JsonApiDotNetCoreExample/Controllers/OperationsController.cs index 6dd2bcb9ba..e38b30d861 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Controllers/OperationsController.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Controllers/OperationsController.cs @@ -6,11 +6,6 @@ namespace JsonApiDotNetCoreExample.Controllers; -public sealed class OperationsController : JsonApiOperationsController -{ - public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } -} +public sealed class OperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields); diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs index dd30287500..e7864a42f6 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs @@ -8,15 +8,10 @@ namespace JsonApiDotNetCoreExample.Data; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class AppDbContext : DbContext +public sealed class AppDbContext(DbContextOptions options) : DbContext(options) { public DbSet TodoItems => Set(); - public AppDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { // When deleting a person, un-assign him/her from existing todo-items. diff --git a/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs b/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs index 778119c6be..c59ea96918 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Data/RotatingList.cs @@ -16,16 +16,11 @@ public static RotatingList Create(int count, Func createElement) } } -internal sealed class RotatingList +internal sealed class RotatingList(IList elements) { private int _index = -1; - public IList Elements { get; } - - public RotatingList(IList elements) - { - Elements = elements; - } + public IList Elements { get; } = elements; public T GetNext() { diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs index 31aee37585..d94fffa85b 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemDefinition.cs @@ -12,22 +12,19 @@ namespace JsonApiDotNetCoreExample.Definitions; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TodoItemDefinition : JsonApiResourceDefinition +public sealed class TodoItemDefinition( + IResourceGraph resourceGraph, +#if NET6_0 + ISystemClock systemClock +#else + TimeProvider timeProvider +#endif +) : JsonApiResourceDefinition(resourceGraph) { - private readonly Func _getUtcNow; - #if NET6_0 - public TodoItemDefinition(IResourceGraph resourceGraph, ISystemClock systemClock) - : base(resourceGraph) - { - _getUtcNow = () => systemClock.UtcNow; - } + private readonly Func _getUtcNow = () => systemClock.UtcNow; #else - public TodoItemDefinition(IResourceGraph resourceGraph, TimeProvider timeProvider) - : base(resourceGraph) - { - _getUtcNow = timeProvider.GetUtcNow; - } + private readonly Func _getUtcNow = timeProvider.GetUtcNow; #endif public override SortExpression OnApplySort(SortExpression? existingSort) diff --git a/src/Examples/MultiDbContextExample/Data/DbContextA.cs b/src/Examples/MultiDbContextExample/Data/DbContextA.cs index b21e69f2ff..4efd10ea7b 100644 --- a/src/Examples/MultiDbContextExample/Data/DbContextA.cs +++ b/src/Examples/MultiDbContextExample/Data/DbContextA.cs @@ -5,12 +5,7 @@ namespace MultiDbContextExample.Data; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class DbContextA : DbContext +public sealed class DbContextA(DbContextOptions options) : DbContext(options) { public DbSet ResourceAs => Set(); - - public DbContextA(DbContextOptions options) - : base(options) - { - } } diff --git a/src/Examples/MultiDbContextExample/Data/DbContextB.cs b/src/Examples/MultiDbContextExample/Data/DbContextB.cs index 9bc82c5257..faf50c0902 100644 --- a/src/Examples/MultiDbContextExample/Data/DbContextB.cs +++ b/src/Examples/MultiDbContextExample/Data/DbContextB.cs @@ -5,12 +5,7 @@ namespace MultiDbContextExample.Data; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class DbContextB : DbContext +public sealed class DbContextB(DbContextOptions options) : DbContext(options) { public DbSet ResourceBs => Set(); - - public DbContextB(DbContextOptions options) - : base(options) - { - } } diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs index aadeb889cc..d90b572004 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextARepository.cs @@ -8,13 +8,9 @@ namespace MultiDbContextExample.Repositories; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class DbContextARepository : EntityFrameworkCoreRepository - where TResource : class, IIdentifiable -{ - public DbContextARepository(ITargetedFields targetedFields, DbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - } -} +public sealed class DbContextARepository( + ITargetedFields targetedFields, DbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor) + where TResource : class, IIdentifiable; diff --git a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs index ac4ce8789c..ed56237d56 100644 --- a/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs +++ b/src/Examples/MultiDbContextExample/Repositories/DbContextBRepository.cs @@ -8,13 +8,9 @@ namespace MultiDbContextExample.Repositories; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class DbContextBRepository : EntityFrameworkCoreRepository - where TResource : class, IIdentifiable -{ - public DbContextBRepository(ITargetedFields targetedFields, DbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - } -} +public sealed class DbContextBRepository( + ITargetedFields targetedFields, DbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor) + where TResource : class, IIdentifiable; diff --git a/src/Examples/NoEntityFrameworkExample/InMemoryInverseNavigationResolver.cs b/src/Examples/NoEntityFrameworkExample/InMemoryInverseNavigationResolver.cs index 179eafd516..5e0d6e7bd7 100644 --- a/src/Examples/NoEntityFrameworkExample/InMemoryInverseNavigationResolver.cs +++ b/src/Examples/NoEntityFrameworkExample/InMemoryInverseNavigationResolver.cs @@ -4,14 +4,9 @@ namespace NoEntityFrameworkExample; -internal sealed class InMemoryInverseNavigationResolver : IInverseNavigationResolver +internal sealed class InMemoryInverseNavigationResolver(IResourceGraph resourceGraph) : IInverseNavigationResolver { - private readonly IResourceGraph _resourceGraph; - - public InMemoryInverseNavigationResolver(IResourceGraph resourceGraph) - { - _resourceGraph = resourceGraph; - } + private readonly IResourceGraph _resourceGraph = resourceGraph; /// public void Resolve() diff --git a/src/Examples/NoEntityFrameworkExample/QueryLayerToLinqConverter.cs b/src/Examples/NoEntityFrameworkExample/QueryLayerToLinqConverter.cs index f3eca749eb..29d5f999e9 100644 --- a/src/Examples/NoEntityFrameworkExample/QueryLayerToLinqConverter.cs +++ b/src/Examples/NoEntityFrameworkExample/QueryLayerToLinqConverter.cs @@ -7,16 +7,10 @@ namespace NoEntityFrameworkExample; -internal sealed class QueryLayerToLinqConverter +internal sealed class QueryLayerToLinqConverter(IModel model, IQueryableBuilder queryableBuilder) { - private readonly IModel _model; - private readonly IQueryableBuilder _queryableBuilder; - - public QueryLayerToLinqConverter(IModel model, IQueryableBuilder queryableBuilder) - { - _model = model; - _queryableBuilder = queryableBuilder; - } + private readonly IModel _model = model; + private readonly IQueryableBuilder _queryableBuilder = queryableBuilder; public IEnumerable ApplyQueryLayer(QueryLayer queryLayer, IEnumerable resources) where TResource : class, IIdentifiable diff --git a/src/Examples/NoEntityFrameworkExample/Repositories/PersonRepository.cs b/src/Examples/NoEntityFrameworkExample/Repositories/PersonRepository.cs index 4a2fc5e72a..897af592b7 100644 --- a/src/Examples/NoEntityFrameworkExample/Repositories/PersonRepository.cs +++ b/src/Examples/NoEntityFrameworkExample/Repositories/PersonRepository.cs @@ -7,13 +7,9 @@ namespace NoEntityFrameworkExample.Repositories; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class PersonRepository : InMemoryResourceRepository +public sealed class PersonRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) + : InMemoryResourceRepository(resourceGraph, queryableBuilder) { - public PersonRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) - : base(resourceGraph, queryableBuilder) - { - } - protected override IEnumerable GetDataSource() { return Database.People; diff --git a/src/Examples/NoEntityFrameworkExample/Repositories/TagRepository.cs b/src/Examples/NoEntityFrameworkExample/Repositories/TagRepository.cs index 30661d8bc1..30658fb68d 100644 --- a/src/Examples/NoEntityFrameworkExample/Repositories/TagRepository.cs +++ b/src/Examples/NoEntityFrameworkExample/Repositories/TagRepository.cs @@ -7,13 +7,9 @@ namespace NoEntityFrameworkExample.Repositories; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TagRepository : InMemoryResourceRepository +public sealed class TagRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) + : InMemoryResourceRepository(resourceGraph, queryableBuilder) { - public TagRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) - : base(resourceGraph, queryableBuilder) - { - } - protected override IEnumerable GetDataSource() { return Database.Tags; diff --git a/src/Examples/NoEntityFrameworkExample/Repositories/TodoItemRepository.cs b/src/Examples/NoEntityFrameworkExample/Repositories/TodoItemRepository.cs index 8156bf2798..41774b0c8f 100644 --- a/src/Examples/NoEntityFrameworkExample/Repositories/TodoItemRepository.cs +++ b/src/Examples/NoEntityFrameworkExample/Repositories/TodoItemRepository.cs @@ -7,13 +7,9 @@ namespace NoEntityFrameworkExample.Repositories; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TodoItemRepository : InMemoryResourceRepository +public sealed class TodoItemRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) + : InMemoryResourceRepository(resourceGraph, queryableBuilder) { - public TodoItemRepository(IResourceGraph resourceGraph, IQueryableBuilder queryableBuilder) - : base(resourceGraph, queryableBuilder) - { - } - protected override IEnumerable GetDataSource() { return Database.TodoItems; diff --git a/src/Examples/NoEntityFrameworkExample/Services/TodoItemService.cs b/src/Examples/NoEntityFrameworkExample/Services/TodoItemService.cs index 5f8f96e0c6..294d23978c 100644 --- a/src/Examples/NoEntityFrameworkExample/Services/TodoItemService.cs +++ b/src/Examples/NoEntityFrameworkExample/Services/TodoItemService.cs @@ -9,14 +9,12 @@ namespace NoEntityFrameworkExample.Services; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TodoItemService : InMemoryResourceService +public sealed class TodoItemService( + IJsonApiOptions options, IResourceGraph resourceGraph, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, + IEnumerable constraintProviders, IQueryableBuilder queryableBuilder, ILoggerFactory loggerFactory) + : InMemoryResourceService(options, resourceGraph, queryLayerComposer, paginationContext, constraintProviders, queryableBuilder, + loggerFactory) { - public TodoItemService(IJsonApiOptions options, IResourceGraph resourceGraph, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, - IEnumerable constraintProviders, IQueryableBuilder queryableBuilder, ILoggerFactory loggerFactory) - : base(options, resourceGraph, queryLayerComposer, paginationContext, constraintProviders, queryableBuilder, loggerFactory) - { - } - protected override IEnumerable GetDataSource(ResourceType resourceType) { if (resourceType.ClrType == typeof(TodoItem)) diff --git a/src/Examples/ReportsExample/Services/ReportService.cs b/src/Examples/ReportsExample/Services/ReportService.cs index 61a97ecde5..c04e821347 100644 --- a/src/Examples/ReportsExample/Services/ReportService.cs +++ b/src/Examples/ReportsExample/Services/ReportService.cs @@ -5,14 +5,9 @@ namespace ReportsExample.Services; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class ReportService : IGetAllService +public class ReportService(ILoggerFactory loggerFactory) : IGetAllService { - private readonly ILogger _logger; - - public ReportService(ILoggerFactory loggerFactory) - { - _logger = loggerFactory.CreateLogger(); - } + private readonly ILogger _logger = loggerFactory.CreateLogger(); public Task> GetAsync(CancellationToken cancellationToken) { diff --git a/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs b/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs index 0ce666e342..1e68e5afab 100644 --- a/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs +++ b/src/JsonApiDotNetCore.SourceGenerators/SourceCodeWriter.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCore.SourceGenerators; /// /// Writes the source code for an ASP.NET controller for a JSON:API resource. /// -internal sealed class SourceCodeWriter +internal sealed class SourceCodeWriter(GeneratorExecutionContext context, DiagnosticDescriptor missingIndentInTableErrorDescriptor) { private const int SpacesPerIndent = 4; @@ -41,18 +41,12 @@ internal sealed class SourceCodeWriter [JsonApiEndpointsCopy.DeleteRelationship] = ("IRemoveFromRelationshipService", "removeFromRelationship") }; - private readonly GeneratorExecutionContext _context; - private readonly DiagnosticDescriptor _missingIndentInTableErrorDescriptor; + private readonly GeneratorExecutionContext _context = context; + private readonly DiagnosticDescriptor _missingIndentInTableErrorDescriptor = missingIndentInTableErrorDescriptor; private readonly StringBuilder _sourceBuilder = new(); private int _depth; - public SourceCodeWriter(GeneratorExecutionContext context, DiagnosticDescriptor missingIndentInTableErrorDescriptor) - { - _context = context; - _missingIndentInTableErrorDescriptor = missingIndentInTableErrorDescriptor; - } - public string Write(INamedTypeSymbol resourceType, ITypeSymbol idType, JsonApiEndpointsCopy endpointsToGenerate, string? controllerNamespace, string controllerName, INamedTypeSymbol loggerFactoryInterface) { diff --git a/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs b/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs index 4fe3421dd2..09ebefaf93 100644 --- a/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs +++ b/src/JsonApiDotNetCore/AtomicOperations/LocalIdTracker.cs @@ -90,14 +90,9 @@ private static void AssertSameResourceType(ResourceType currentType, ResourceTyp } } - private sealed class LocalIdState + private sealed class LocalIdState(ResourceType resourceType) { - public ResourceType ResourceType { get; } + public ResourceType ResourceType { get; } = resourceType; public string? ServerId { get; set; } - - public LocalIdState(ResourceType resourceType) - { - ResourceType = resourceType; - } } } diff --git a/src/JsonApiDotNetCore/Configuration/InjectablesAssemblyScanner.cs b/src/JsonApiDotNetCore/Configuration/InjectablesAssemblyScanner.cs new file mode 100644 index 0000000000..9985533776 --- /dev/null +++ b/src/JsonApiDotNetCore/Configuration/InjectablesAssemblyScanner.cs @@ -0,0 +1,129 @@ +using System.Reflection; +using JsonApiDotNetCore.Repositories; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCore.Services; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace JsonApiDotNetCore.Configuration; + +/// +/// Scans assemblies for injectables (types that implement , +/// or ) and registers them in the IoC container. +/// +internal sealed class InjectablesAssemblyScanner +{ + internal static readonly HashSet ServiceUnboundInterfaces = + [ + typeof(IResourceService<,>), + typeof(IResourceCommandService<,>), + typeof(IResourceQueryService<,>), + typeof(IGetAllService<,>), + typeof(IGetByIdService<,>), + typeof(IGetSecondaryService<,>), + typeof(IGetRelationshipService<,>), + typeof(ICreateService<,>), + typeof(IAddToRelationshipService<,>), + typeof(IUpdateService<,>), + typeof(ISetRelationshipService<,>), + typeof(IDeleteService<,>), + typeof(IRemoveFromRelationshipService<,>) + ]; + + internal static readonly HashSet RepositoryUnboundInterfaces = + [ + typeof(IResourceRepository<,>), + typeof(IResourceWriteRepository<,>), + typeof(IResourceReadRepository<,>) + ]; + + internal static readonly HashSet ResourceDefinitionUnboundInterfaces = [typeof(IResourceDefinition<,>)]; + + private readonly ResourceDescriptorAssemblyCache _assemblyCache; + private readonly IServiceCollection _services; + private readonly TypeLocator _typeLocator = new(); + + public InjectablesAssemblyScanner(ResourceDescriptorAssemblyCache assemblyCache, IServiceCollection services) + { + ArgumentGuard.NotNull(assemblyCache); + ArgumentGuard.NotNull(services); + + _assemblyCache = assemblyCache; + _services = services; + } + + public void DiscoverInjectables() + { + IReadOnlyCollection descriptors = _assemblyCache.GetResourceDescriptors(); + IReadOnlyCollection assemblies = _assemblyCache.GetAssemblies(); + + foreach (Assembly assembly in assemblies) + { + AddDbContextResolvers(assembly); + AddInjectables(descriptors, assembly); + } + } + + private void AddDbContextResolvers(Assembly assembly) + { + IEnumerable dbContextTypes = _typeLocator.GetDerivedTypes(assembly, typeof(DbContext)); + + foreach (Type dbContextType in dbContextTypes) + { + Type dbContextResolverClosedType = typeof(DbContextResolver<>).MakeGenericType(dbContextType); + _services.TryAddScoped(typeof(IDbContextResolver), dbContextResolverClosedType); + } + } + + private void AddInjectables(IEnumerable resourceDescriptors, Assembly assembly) + { + foreach (ResourceDescriptor resourceDescriptor in resourceDescriptors) + { + AddServices(assembly, resourceDescriptor); + AddRepositories(assembly, resourceDescriptor); + AddResourceDefinitions(assembly, resourceDescriptor); + } + } + + private void AddServices(Assembly assembly, ResourceDescriptor resourceDescriptor) + { + foreach (Type serviceUnboundInterface in ServiceUnboundInterfaces) + { + RegisterImplementations(assembly, serviceUnboundInterface, resourceDescriptor); + } + } + + private void AddRepositories(Assembly assembly, ResourceDescriptor resourceDescriptor) + { + foreach (Type repositoryUnboundInterface in RepositoryUnboundInterfaces) + { + RegisterImplementations(assembly, repositoryUnboundInterface, resourceDescriptor); + } + } + + private void AddResourceDefinitions(Assembly assembly, ResourceDescriptor resourceDescriptor) + { + foreach (Type resourceDefinitionUnboundInterface in ResourceDefinitionUnboundInterfaces) + { + RegisterImplementations(assembly, resourceDefinitionUnboundInterface, resourceDescriptor); + } + } + + private void RegisterImplementations(Assembly assembly, Type interfaceType, ResourceDescriptor resourceDescriptor) + { + Type[] typeArguments = + [ + resourceDescriptor.ResourceClrType, + resourceDescriptor.IdClrType + ]; + + (Type implementationType, Type serviceInterface)? result = _typeLocator.GetContainerRegistrationFromAssembly(assembly, interfaceType, typeArguments); + + if (result != null) + { + (Type implementationType, Type serviceInterface) = result.Value; + _services.TryAddScoped(serviceInterface, implementationType); + } + } +} diff --git a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs index 17ca6677c3..2004178ccd 100644 --- a/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs +++ b/src/JsonApiDotNetCore/Configuration/JsonApiApplicationBuilder.cs @@ -23,17 +23,15 @@ namespace JsonApiDotNetCore.Configuration; /// -/// A utility class that builds a JsonApi application. It registers all required services and allows the user to override parts of the startup +/// A utility class that builds a JSON:API application. It registers all required services and allows the user to override parts of the startup /// configuration. /// -internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder, IDisposable +internal sealed class JsonApiApplicationBuilder : IJsonApiApplicationBuilder { - private readonly JsonApiOptions _options = new(); private readonly IServiceCollection _services; private readonly IMvcCoreBuilder _mvcBuilder; - private readonly ResourceGraphBuilder _resourceGraphBuilder; - private readonly ServiceDiscoveryFacade _serviceDiscoveryFacade; - private readonly ServiceProvider _intermediateProvider; + private readonly JsonApiOptions _options = new(); + private readonly ResourceDescriptorAssemblyCache _assemblyCache = new(); public Action? ConfigureMvcOptions { get; set; } @@ -44,12 +42,6 @@ public JsonApiApplicationBuilder(IServiceCollection services, IMvcCoreBuilder mv _services = services; _mvcBuilder = mvcBuilder; - _intermediateProvider = services.BuildServiceProvider(); - - var loggerFactory = _intermediateProvider.GetRequiredService(); - - _resourceGraphBuilder = new ResourceGraphBuilder(_options, loggerFactory); - _serviceDiscoveryFacade = new ServiceDiscoveryFacade(_services, _resourceGraphBuilder, loggerFactory); } /// @@ -61,35 +53,51 @@ public void ConfigureJsonApiOptions(Action? configureOptions) } /// - /// Executes the action provided by the user to configure . + /// Executes the action provided by the user to configure auto-discovery. /// public void ConfigureAutoDiscovery(Action? configureAutoDiscovery) { - configureAutoDiscovery?.Invoke(_serviceDiscoveryFacade); + if (configureAutoDiscovery != null) + { + var facade = new ServiceDiscoveryFacade(_assemblyCache); + configureAutoDiscovery.Invoke(facade); + } } /// - /// Configures and builds the resource graph with resources from the provided sources and adds it to the DI container. + /// Configures and builds the resource graph with resources from the provided sources and adds them to the IoC container. /// public void ConfigureResourceGraph(ICollection dbContextTypes, Action? configureResourceGraph) { ArgumentGuard.NotNull(dbContextTypes); - _serviceDiscoveryFacade.DiscoverResources(); - - foreach (Type dbContextType in dbContextTypes) + _services.TryAddSingleton(serviceProvider => { - var dbContext = (DbContext)_intermediateProvider.GetRequiredService(dbContextType); - _resourceGraphBuilder.Add(dbContext); - } + var loggerFactory = serviceProvider.GetRequiredService(); + var resourceGraphBuilder = new ResourceGraphBuilder(_options, loggerFactory); - configureResourceGraph?.Invoke(_resourceGraphBuilder); + var scanner = new ResourcesAssemblyScanner(_assemblyCache, resourceGraphBuilder); + scanner.DiscoverResources(); - IResourceGraph resourceGraph = _resourceGraphBuilder.Build(); + if (dbContextTypes.Count > 0) + { + using IServiceScope scope = serviceProvider.CreateScope(); - _options.SerializerOptions.Converters.Add(new ResourceObjectConverter(resourceGraph)); + foreach (Type dbContextType in dbContextTypes) + { + var dbContext = (DbContext)scope.ServiceProvider.GetRequiredService(dbContextType); + resourceGraphBuilder.Add(dbContext); + } + } + + configureResourceGraph?.Invoke(resourceGraphBuilder); + + IResourceGraph resourceGraph = resourceGraphBuilder.Build(); + + _options.SerializerOptions.Converters.Add(new ResourceObjectConverter(resourceGraph)); - _services.TryAddSingleton(resourceGraph); + return resourceGraph; + }); } /// @@ -114,15 +122,16 @@ public void ConfigureMvc() } /// - /// Discovers DI registrable services in the assemblies marked for discovery. + /// Registers injectables in the IoC container found in assemblies marked for auto-discovery. /// public void DiscoverInjectables() { - _serviceDiscoveryFacade.DiscoverInjectables(); + var scanner = new InjectablesAssemblyScanner(_assemblyCache, _services); + scanner.DiscoverInjectables(); } /// - /// Registers the remaining internals. + /// Registers the remaining internals in the IoC container. /// public void ConfigureServiceContainer(ICollection dbContextTypes) { @@ -182,7 +191,7 @@ private void AddMiddlewareLayer() private void AddResourceLayer() { - RegisterImplementationForInterfaces(ServiceDiscoveryFacade.ResourceDefinitionUnboundInterfaces, typeof(JsonApiResourceDefinition<,>)); + RegisterImplementationForInterfaces(InjectablesAssemblyScanner.ResourceDefinitionUnboundInterfaces, typeof(JsonApiResourceDefinition<,>)); _services.TryAddScoped(); _services.TryAddScoped(); @@ -190,7 +199,7 @@ private void AddResourceLayer() private void AddRepositoryLayer() { - RegisterImplementationForInterfaces(ServiceDiscoveryFacade.RepositoryUnboundInterfaces, typeof(EntityFrameworkCoreRepository<,>)); + RegisterImplementationForInterfaces(InjectablesAssemblyScanner.RepositoryUnboundInterfaces, typeof(EntityFrameworkCoreRepository<,>)); _services.TryAddScoped(); @@ -204,7 +213,7 @@ private void AddRepositoryLayer() private void AddServiceLayer() { - RegisterImplementationForInterfaces(ServiceDiscoveryFacade.ServiceUnboundInterfaces, typeof(JsonApiResourceService<,>)); + RegisterImplementationForInterfaces(InjectablesAssemblyScanner.ServiceUnboundInterfaces, typeof(JsonApiResourceService<,>)); } private void RegisterImplementationForInterfaces(HashSet unboundInterfaces, Type unboundImplementationType) @@ -291,9 +300,4 @@ private void AddOperationsLayer() _services.TryAddScoped(); _services.TryAddScoped(); } - - public void Dispose() - { - _intermediateProvider.Dispose(); - } } diff --git a/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs b/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs index a6e12951a9..6a5a09dcaf 100644 --- a/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs +++ b/src/JsonApiDotNetCore/Configuration/ResourceNameFormatter.cs @@ -5,14 +5,9 @@ namespace JsonApiDotNetCore.Configuration; -internal sealed class ResourceNameFormatter +internal sealed class ResourceNameFormatter(JsonNamingPolicy? namingPolicy) { - private readonly JsonNamingPolicy? _namingPolicy; - - public ResourceNameFormatter(JsonNamingPolicy? namingPolicy) - { - _namingPolicy = namingPolicy; - } + private readonly JsonNamingPolicy? _namingPolicy = namingPolicy; /// /// Gets the publicly exposed resource name by applying the configured naming convention on the pluralized CLR type name. diff --git a/src/JsonApiDotNetCore/Configuration/ResourcesAssemblyScanner.cs b/src/JsonApiDotNetCore/Configuration/ResourcesAssemblyScanner.cs new file mode 100644 index 0000000000..cdfdc4446c --- /dev/null +++ b/src/JsonApiDotNetCore/Configuration/ResourcesAssemblyScanner.cs @@ -0,0 +1,29 @@ +using JsonApiDotNetCore.Resources; + +namespace JsonApiDotNetCore.Configuration; + +/// +/// Scans assemblies for types that implement and adds them to the resource graph. +/// +internal sealed class ResourcesAssemblyScanner +{ + private readonly ResourceDescriptorAssemblyCache _assemblyCache; + private readonly ResourceGraphBuilder _resourceGraphBuilder; + + public ResourcesAssemblyScanner(ResourceDescriptorAssemblyCache assemblyCache, ResourceGraphBuilder resourceGraphBuilder) + { + ArgumentGuard.NotNull(assemblyCache); + ArgumentGuard.NotNull(resourceGraphBuilder); + + _assemblyCache = assemblyCache; + _resourceGraphBuilder = resourceGraphBuilder; + } + + public void DiscoverResources() + { + foreach (ResourceDescriptor resourceDescriptor in _assemblyCache.GetResourceDescriptors()) + { + _resourceGraphBuilder.Add(resourceDescriptor.ResourceClrType, resourceDescriptor.IdClrType); + } + } +} diff --git a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs index b25c208086..5ad4474d95 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceCollectionExtensions.cs @@ -43,7 +43,7 @@ private static void SetupApplicationBuilder(IServiceCollection services, Action< Action? configureAutoDiscovery, Action? configureResources, IMvcCoreBuilder? mvcBuilder, ICollection dbContextTypes) { - using var applicationBuilder = new JsonApiApplicationBuilder(services, mvcBuilder ?? services.AddMvcCore()); + var applicationBuilder = new JsonApiApplicationBuilder(services, mvcBuilder ?? services.AddMvcCore()); applicationBuilder.ConfigureJsonApiOptions(configureOptions); applicationBuilder.ConfigureAutoDiscovery(configureAutoDiscovery); @@ -61,7 +61,7 @@ public static IServiceCollection AddResourceService(this IServiceColle { ArgumentGuard.NotNull(services); - RegisterTypeForUnboundInterfaces(services, typeof(TService), ServiceDiscoveryFacade.ServiceUnboundInterfaces); + RegisterTypeForUnboundInterfaces(services, typeof(TService), InjectablesAssemblyScanner.ServiceUnboundInterfaces); return services; } @@ -74,7 +74,7 @@ public static IServiceCollection AddResourceRepository(this IServic { ArgumentGuard.NotNull(services); - RegisterTypeForUnboundInterfaces(services, typeof(TRepository), ServiceDiscoveryFacade.RepositoryUnboundInterfaces); + RegisterTypeForUnboundInterfaces(services, typeof(TRepository), InjectablesAssemblyScanner.RepositoryUnboundInterfaces); return services; } @@ -87,7 +87,7 @@ public static IServiceCollection AddResourceDefinition(this { ArgumentGuard.NotNull(services); - RegisterTypeForUnboundInterfaces(services, typeof(TResourceDefinition), ServiceDiscoveryFacade.ResourceDefinitionUnboundInterfaces); + RegisterTypeForUnboundInterfaces(services, typeof(TResourceDefinition), InjectablesAssemblyScanner.ResourceDefinitionUnboundInterfaces); return services; } diff --git a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs index 01f9ecc7cb..615ef244fc 100644 --- a/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs +++ b/src/JsonApiDotNetCore/Configuration/ServiceDiscoveryFacade.cs @@ -1,66 +1,25 @@ using System.Reflection; using JetBrains.Annotations; -using JsonApiDotNetCore.Repositories; -using JsonApiDotNetCore.Resources; -using JsonApiDotNetCore.Services; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; namespace JsonApiDotNetCore.Configuration; /// -/// Scans for types like resources, services, repositories and resource definitions in an assembly and registers them to the IoC container. +/// Provides auto-discovery by scanning assemblies for resources and related injectables. /// [PublicAPI] public sealed class ServiceDiscoveryFacade { - internal static readonly HashSet ServiceUnboundInterfaces = - [ - typeof(IResourceService<,>), - typeof(IResourceCommandService<,>), - typeof(IResourceQueryService<,>), - typeof(IGetAllService<,>), - typeof(IGetByIdService<,>), - typeof(IGetSecondaryService<,>), - typeof(IGetRelationshipService<,>), - typeof(ICreateService<,>), - typeof(IAddToRelationshipService<,>), - typeof(IUpdateService<,>), - typeof(ISetRelationshipService<,>), - typeof(IDeleteService<,>), - typeof(IRemoveFromRelationshipService<,>) - ]; + private readonly ResourceDescriptorAssemblyCache _assemblyCache; - internal static readonly HashSet RepositoryUnboundInterfaces = - [ - typeof(IResourceRepository<,>), - typeof(IResourceWriteRepository<,>), - typeof(IResourceReadRepository<,>) - ]; - - internal static readonly HashSet ResourceDefinitionUnboundInterfaces = [typeof(IResourceDefinition<,>)]; - - private readonly ILogger _logger; - private readonly IServiceCollection _services; - private readonly ResourceGraphBuilder _resourceGraphBuilder; - private readonly ResourceDescriptorAssemblyCache _assemblyCache = new(); - private readonly TypeLocator _typeLocator = new(); - - public ServiceDiscoveryFacade(IServiceCollection services, ResourceGraphBuilder resourceGraphBuilder, ILoggerFactory loggerFactory) + internal ServiceDiscoveryFacade(ResourceDescriptorAssemblyCache assemblyCache) { - ArgumentGuard.NotNull(services); - ArgumentGuard.NotNull(resourceGraphBuilder); - ArgumentGuard.NotNull(loggerFactory); + ArgumentGuard.NotNull(assemblyCache); - _logger = loggerFactory.CreateLogger(); - _services = services; - _resourceGraphBuilder = resourceGraphBuilder; + _assemblyCache = assemblyCache; } /// - /// Mark the calling assembly for scanning of resources and injectables. + /// Includes the calling assembly for auto-discovery of resources and related injectables. /// public ServiceDiscoveryFacade AddCurrentAssembly() { @@ -68,102 +27,13 @@ public ServiceDiscoveryFacade AddCurrentAssembly() } /// - /// Mark the specified assembly for scanning of resources and injectables. + /// Includes the specified assembly for auto-discovery of resources and related injectables. /// public ServiceDiscoveryFacade AddAssembly(Assembly assembly) { ArgumentGuard.NotNull(assembly); _assemblyCache.RegisterAssembly(assembly); - _logger.LogDebug($"Registering assembly '{assembly.FullName}' for discovery of resources and injectables."); - return this; } - - internal void DiscoverResources() - { - foreach (ResourceDescriptor resourceDescriptor in _assemblyCache.GetResourceDescriptors()) - { - AddResource(resourceDescriptor); - } - } - - internal void DiscoverInjectables() - { - IReadOnlyCollection descriptors = _assemblyCache.GetResourceDescriptors(); - IReadOnlyCollection assemblies = _assemblyCache.GetAssemblies(); - - foreach (Assembly assembly in assemblies) - { - AddDbContextResolvers(assembly); - AddInjectables(descriptors, assembly); - } - } - - private void AddInjectables(IReadOnlyCollection resourceDescriptors, Assembly assembly) - { - foreach (ResourceDescriptor resourceDescriptor in resourceDescriptors) - { - AddServices(assembly, resourceDescriptor); - AddRepositories(assembly, resourceDescriptor); - AddResourceDefinitions(assembly, resourceDescriptor); - } - } - - private void AddDbContextResolvers(Assembly assembly) - { - IEnumerable dbContextTypes = _typeLocator.GetDerivedTypes(assembly, typeof(DbContext)); - - foreach (Type dbContextType in dbContextTypes) - { - Type dbContextResolverClosedType = typeof(DbContextResolver<>).MakeGenericType(dbContextType); - _services.TryAddScoped(typeof(IDbContextResolver), dbContextResolverClosedType); - } - } - - private void AddResource(ResourceDescriptor resourceDescriptor) - { - _resourceGraphBuilder.Add(resourceDescriptor.ResourceClrType, resourceDescriptor.IdClrType); - } - - private void AddServices(Assembly assembly, ResourceDescriptor resourceDescriptor) - { - foreach (Type serviceUnboundInterface in ServiceUnboundInterfaces) - { - RegisterImplementations(assembly, serviceUnboundInterface, resourceDescriptor); - } - } - - private void AddRepositories(Assembly assembly, ResourceDescriptor resourceDescriptor) - { - foreach (Type repositoryUnboundInterface in RepositoryUnboundInterfaces) - { - RegisterImplementations(assembly, repositoryUnboundInterface, resourceDescriptor); - } - } - - private void AddResourceDefinitions(Assembly assembly, ResourceDescriptor resourceDescriptor) - { - foreach (Type resourceDefinitionUnboundInterface in ResourceDefinitionUnboundInterfaces) - { - RegisterImplementations(assembly, resourceDefinitionUnboundInterface, resourceDescriptor); - } - } - - private void RegisterImplementations(Assembly assembly, Type interfaceType, ResourceDescriptor resourceDescriptor) - { - Type[] typeArguments = - [ - resourceDescriptor.ResourceClrType, - resourceDescriptor.IdClrType - ]; - - (Type implementationType, Type serviceInterface)? result = _typeLocator.GetContainerRegistrationFromAssembly(assembly, interfaceType, typeArguments); - - if (result != null) - { - (Type implementationType, Type serviceInterface) = result.Value; - _services.TryAddScoped(serviceInterface, implementationType); - } - } } diff --git a/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs b/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs index 70d65aa7b3..43f75896a0 100644 --- a/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs +++ b/src/JsonApiDotNetCore/Controllers/JsonApiOperationsController.cs @@ -11,14 +11,10 @@ namespace JsonApiDotNetCore.Controllers; /// The base class to derive atomic:operations controllers from. This class delegates all work to but adds /// attributes for routing templates. If you want to provide routing templates yourself, you should derive from BaseJsonApiOperationsController directly. /// -public abstract class JsonApiOperationsController : BaseJsonApiOperationsController +public abstract class JsonApiOperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : BaseJsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields) { - protected JsonApiOperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } - /// [HttpPost] public override Task PostOperationsAsync([FromBody] IList operations, CancellationToken cancellationToken) diff --git a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs index 97377b0d7b..3ec95be11a 100644 --- a/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs +++ b/src/JsonApiDotNetCore/Errors/CannotClearRequiredRelationshipException.cs @@ -8,14 +8,9 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when a required relationship is cleared. /// [PublicAPI] -public sealed class CannotClearRequiredRelationshipException : JsonApiException -{ - public CannotClearRequiredRelationshipException(string relationshipName, string resourceType) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = "Failed to clear a required relationship.", - Detail = $"The relationship '{relationshipName}' on resource type '{resourceType}' cannot be cleared because it is a required relationship." - }) +public sealed class CannotClearRequiredRelationshipException(string relationshipName, string resourceType) : JsonApiException( + new ErrorObject(HttpStatusCode.BadRequest) { - } -} + Title = "Failed to clear a required relationship.", + Detail = $"The relationship '{relationshipName}' on resource type '{resourceType}' cannot be cleared because it is a required relationship." + }); diff --git a/src/JsonApiDotNetCore/Errors/DuplicateLocalIdValueException.cs b/src/JsonApiDotNetCore/Errors/DuplicateLocalIdValueException.cs index 7b714d2b9d..07ac377ae1 100644 --- a/src/JsonApiDotNetCore/Errors/DuplicateLocalIdValueException.cs +++ b/src/JsonApiDotNetCore/Errors/DuplicateLocalIdValueException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when assigning a local ID that was already assigned in an earlier operation. /// [PublicAPI] -public sealed class DuplicateLocalIdValueException : JsonApiException +public sealed class DuplicateLocalIdValueException(string localId) : JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { - public DuplicateLocalIdValueException(string localId) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = "Another local ID with the same name is already defined at this point.", - Detail = $"Another local ID with name '{localId}' is already defined at this point." - }) - { - } -} + Title = "Another local ID with the same name is already defined at this point.", + Detail = $"Another local ID with name '{localId}' is already defined at this point." +}); diff --git a/src/JsonApiDotNetCore/Errors/FailedOperationException.cs b/src/JsonApiDotNetCore/Errors/FailedOperationException.cs index e94b5a7c1b..a6b970bcce 100644 --- a/src/JsonApiDotNetCore/Errors/FailedOperationException.cs +++ b/src/JsonApiDotNetCore/Errors/FailedOperationException.cs @@ -8,18 +8,13 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when an operation in an atomic:operations request failed to be processed for unknown reasons. /// [PublicAPI] -public sealed class FailedOperationException : JsonApiException -{ - public FailedOperationException(int operationIndex, Exception innerException) - : base(new ErrorObject(HttpStatusCode.InternalServerError) - { - Title = "An unhandled error occurred while processing an operation in this request.", - Detail = innerException.Message, - Source = new ErrorSource - { - Pointer = $"/atomic:operations[{operationIndex}]" - } - }, innerException) +public sealed class FailedOperationException(int operationIndex, Exception innerException) : JsonApiException( + new ErrorObject(HttpStatusCode.InternalServerError) { - } -} + Title = "An unhandled error occurred while processing an operation in this request.", + Detail = innerException.Message, + Source = new ErrorSource + { + Pointer = $"/atomic:operations[{operationIndex}]" + } + }, innerException); diff --git a/src/JsonApiDotNetCore/Errors/IncompatibleLocalIdTypeException.cs b/src/JsonApiDotNetCore/Errors/IncompatibleLocalIdTypeException.cs index f3f7b33bb5..e893f04f00 100644 --- a/src/JsonApiDotNetCore/Errors/IncompatibleLocalIdTypeException.cs +++ b/src/JsonApiDotNetCore/Errors/IncompatibleLocalIdTypeException.cs @@ -8,14 +8,9 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when referencing a local ID that was assigned to a different resource type. /// [PublicAPI] -public sealed class IncompatibleLocalIdTypeException : JsonApiException -{ - public IncompatibleLocalIdTypeException(string localId, string declaredType, string currentType) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = "Incompatible type in Local ID usage.", - Detail = $"Local ID '{localId}' belongs to resource type '{declaredType}' instead of '{currentType}'." - }) +public sealed class IncompatibleLocalIdTypeException(string localId, string declaredType, string currentType) : JsonApiException( + new ErrorObject(HttpStatusCode.BadRequest) { - } -} + Title = "Incompatible type in Local ID usage.", + Detail = $"Local ID '{localId}' belongs to resource type '{declaredType}' instead of '{currentType}'." + }); diff --git a/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs b/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs index e25fa5244c..0099e57c79 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidConfigurationException.cs @@ -6,10 +6,4 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when configured usage of this library is invalid. /// [PublicAPI] -public sealed class InvalidConfigurationException : Exception -{ - public InvalidConfigurationException(string message, Exception? innerException = null) - : base(message, innerException) - { - } -} +public sealed class InvalidConfigurationException(string message, Exception? innerException = null) : Exception(message, innerException); diff --git a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs index ce8ab8a1b0..396694b50a 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidModelStateException.cs @@ -15,14 +15,11 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when ASP.NET ModelState validation fails. /// [PublicAPI] -public sealed class InvalidModelStateException : JsonApiException +public sealed class InvalidModelStateException( + IReadOnlyDictionary modelState, Type modelType, bool includeExceptionStackTraceInErrors, IResourceGraph resourceGraph, + Func? getCollectionElementTypeCallback = null) : JsonApiException(FromModelStateDictionary(modelState, modelType, resourceGraph, + includeExceptionStackTraceInErrors, getCollectionElementTypeCallback)) { - public InvalidModelStateException(IReadOnlyDictionary modelState, Type modelType, bool includeExceptionStackTraceInErrors, - IResourceGraph resourceGraph, Func? getCollectionElementTypeCallback = null) - : base(FromModelStateDictionary(modelState, modelType, resourceGraph, includeExceptionStackTraceInErrors, getCollectionElementTypeCallback)) - { - } - private static IEnumerable FromModelStateDictionary(IReadOnlyDictionary modelState, Type modelType, IResourceGraph resourceGraph, bool includeExceptionStackTraceInErrors, Func? getCollectionElementTypeCallback) { @@ -317,18 +314,14 @@ private static ModelStateKeySegment CreateSegment(Type modelType, string key, bo /// /// Represents an array indexer in a ModelState key, such as "1" in "Customer.Orders[1].Amount". /// - private sealed class ArrayIndexerSegment : ModelStateKeySegment + private sealed class ArrayIndexerSegment( + int arrayIndex, Type modelType, bool isInComplexType, string nextKey, string? sourcePointer, ModelStateKeySegment? parent, + Func? getCollectionElementTypeCallback) : ModelStateKeySegment(modelType, isInComplexType, nextKey, sourcePointer, parent, + getCollectionElementTypeCallback) { private static readonly CollectionConverter CollectionConverter = new(); - public int ArrayIndex { get; } - - public ArrayIndexerSegment(int arrayIndex, Type modelType, bool isInComplexType, string nextKey, string? sourcePointer, ModelStateKeySegment? parent, - Func? getCollectionElementTypeCallback) - : base(modelType, isInComplexType, nextKey, sourcePointer, parent, getCollectionElementTypeCallback) - { - ArrayIndex = arrayIndex; - } + public int ArrayIndex { get; } = arrayIndex; public Type GetCollectionElementType() { diff --git a/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs b/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs index f4332c1af1..76ebd91461 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidQueryException.cs @@ -9,14 +9,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when translating a to Entity Framework Core fails. /// [PublicAPI] -public sealed class InvalidQueryException : JsonApiException +public sealed class InvalidQueryException(string reason, Exception? innerException) : JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { - public InvalidQueryException(string reason, Exception? innerException) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = reason, - Detail = innerException?.Message - }, innerException) - { - } -} + Title = reason, + Detail = innerException?.Message +}, innerException); diff --git a/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs b/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs index 485cf3685b..d676e40111 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidQueryStringParameterException.cs @@ -8,21 +8,16 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when processing the request fails due to an error in the request query string. /// [PublicAPI] -public sealed class InvalidQueryStringParameterException : JsonApiException -{ - public string ParameterName { get; } - - public InvalidQueryStringParameterException(string parameterName, string genericMessage, string specificMessage, Exception? innerException = null) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = genericMessage, - Detail = specificMessage, - Source = new ErrorSource - { - Parameter = parameterName - } - }, innerException) +public sealed class InvalidQueryStringParameterException(string parameterName, string genericMessage, string specificMessage, Exception? innerException = null) + : JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { - ParameterName = parameterName; - } + Title = genericMessage, + Detail = specificMessage, + Source = new ErrorSource + { + Parameter = parameterName + } + }, innerException) +{ + public string ParameterName { get; } = parameterName; } diff --git a/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs b/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs index d8d752ece4..25297a4056 100644 --- a/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs +++ b/src/JsonApiDotNetCore/Errors/InvalidRequestBodyException.cs @@ -8,27 +8,22 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when deserializing the request body fails. /// [PublicAPI] -public sealed class InvalidRequestBodyException : JsonApiException +public sealed class InvalidRequestBodyException( + string? requestBody, string? genericMessage, string? specificMessage, string? sourcePointer, HttpStatusCode? alternativeStatusCode = null, + Exception? innerException = null) : JsonApiException(new ErrorObject(alternativeStatusCode ?? HttpStatusCode.UnprocessableEntity) { - public InvalidRequestBodyException(string? requestBody, string? genericMessage, string? specificMessage, string? sourcePointer, - HttpStatusCode? alternativeStatusCode = null, Exception? innerException = null) - : base(new ErrorObject(alternativeStatusCode ?? HttpStatusCode.UnprocessableEntity) + Title = genericMessage != null ? $"Failed to deserialize request body: {genericMessage}" : "Failed to deserialize request body.", + Detail = specificMessage, + Source = sourcePointer == null + ? null + : new ErrorSource { - Title = genericMessage != null ? $"Failed to deserialize request body: {genericMessage}" : "Failed to deserialize request body.", - Detail = specificMessage, - Source = sourcePointer == null - ? null - : new ErrorSource - { - Pointer = sourcePointer - }, - Meta = string.IsNullOrEmpty(requestBody) - ? null - : new Dictionary - { - ["RequestBody"] = requestBody - } - }, innerException) - { - } -} + Pointer = sourcePointer + }, + Meta = string.IsNullOrEmpty(requestBody) + ? null + : new Dictionary + { + ["RequestBody"] = requestBody + } +}, innerException); diff --git a/src/JsonApiDotNetCore/Errors/LocalIdSingleOperationException.cs b/src/JsonApiDotNetCore/Errors/LocalIdSingleOperationException.cs index d99eb6dfbb..e96f78672f 100644 --- a/src/JsonApiDotNetCore/Errors/LocalIdSingleOperationException.cs +++ b/src/JsonApiDotNetCore/Errors/LocalIdSingleOperationException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when assigning and referencing a local ID within the same operation. /// [PublicAPI] -public sealed class LocalIdSingleOperationException : JsonApiException +public sealed class LocalIdSingleOperationException(string localId) : JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { - public LocalIdSingleOperationException(string localId) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = "Local ID cannot be both defined and used within the same operation.", - Detail = $"Local ID '{localId}' cannot be both defined and used within the same operation." - }) - { - } -} + Title = "Local ID cannot be both defined and used within the same operation.", + Detail = $"Local ID '{localId}' cannot be both defined and used within the same operation." +}); diff --git a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs index f67dd0d243..e682a5fac2 100644 --- a/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs +++ b/src/JsonApiDotNetCore/Errors/MissingTransactionSupportException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when accessing a repository that does not support transactions during an atomic:operations request. /// [PublicAPI] -public sealed class MissingTransactionSupportException : JsonApiException +public sealed class MissingTransactionSupportException(string resourceType) : JsonApiException(new ErrorObject(HttpStatusCode.UnprocessableEntity) { - public MissingTransactionSupportException(string resourceType) - : base(new ErrorObject(HttpStatusCode.UnprocessableEntity) - { - Title = "Unsupported resource type in atomic:operations request.", - Detail = $"Operations on resources of type '{resourceType}' cannot be used because transaction support is unavailable." - }) - { - } -} + Title = "Unsupported resource type in atomic:operations request.", + Detail = $"Operations on resources of type '{resourceType}' cannot be used because transaction support is unavailable." +}); diff --git a/src/JsonApiDotNetCore/Errors/NonParticipatingTransactionException.cs b/src/JsonApiDotNetCore/Errors/NonParticipatingTransactionException.cs index 09e116c4c1..b4855e27ff 100644 --- a/src/JsonApiDotNetCore/Errors/NonParticipatingTransactionException.cs +++ b/src/JsonApiDotNetCore/Errors/NonParticipatingTransactionException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when a repository does not participate in the overarching transaction during an atomic:operations request. /// [PublicAPI] -public sealed class NonParticipatingTransactionException : JsonApiException +public sealed class NonParticipatingTransactionException() : JsonApiException(new ErrorObject(HttpStatusCode.UnprocessableEntity) { - public NonParticipatingTransactionException() - : base(new ErrorObject(HttpStatusCode.UnprocessableEntity) - { - Title = "Unsupported combination of resource types in atomic:operations request.", - Detail = "All operations need to participate in a single shared transaction, which is not the case for this request." - }) - { - } -} + Title = "Unsupported combination of resource types in atomic:operations request.", + Detail = "All operations need to participate in a single shared transaction, which is not the case for this request." +}); diff --git a/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs b/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs index 5c4d59e479..11a72f803f 100644 --- a/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/RelationshipNotFoundException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when a relationship does not exist. /// [PublicAPI] -public sealed class RelationshipNotFoundException : JsonApiException +public sealed class RelationshipNotFoundException(string relationshipName, string resourceType) : JsonApiException(new ErrorObject(HttpStatusCode.NotFound) { - public RelationshipNotFoundException(string relationshipName, string resourceType) - : base(new ErrorObject(HttpStatusCode.NotFound) - { - Title = "The requested relationship does not exist.", - Detail = $"Resource of type '{resourceType}' does not contain a relationship named '{relationshipName}'." - }) - { - } -} + Title = "The requested relationship does not exist.", + Detail = $"Resource of type '{resourceType}' does not contain a relationship named '{relationshipName}'." +}); diff --git a/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs b/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs index eb4a444d42..d2941422b9 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceAlreadyExistsException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when creating a resource with an ID that already exists. /// [PublicAPI] -public sealed class ResourceAlreadyExistsException : JsonApiException +public sealed class ResourceAlreadyExistsException(string resourceId, string resourceType) : JsonApiException(new ErrorObject(HttpStatusCode.Conflict) { - public ResourceAlreadyExistsException(string resourceId, string resourceType) - : base(new ErrorObject(HttpStatusCode.Conflict) - { - Title = "Another resource with the specified ID already exists.", - Detail = $"Another resource of type '{resourceType}' with ID '{resourceId}' already exists." - }) - { - } -} + Title = "Another resource with the specified ID already exists.", + Detail = $"Another resource of type '{resourceType}' with ID '{resourceId}' already exists." +}); diff --git a/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs b/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs index 28b60851c3..5b2b2a829f 100644 --- a/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourceNotFoundException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when a resource does not exist. /// [PublicAPI] -public sealed class ResourceNotFoundException : JsonApiException +public sealed class ResourceNotFoundException(string resourceId, string resourceType) : JsonApiException(new ErrorObject(HttpStatusCode.NotFound) { - public ResourceNotFoundException(string resourceId, string resourceType) - : base(new ErrorObject(HttpStatusCode.NotFound) - { - Title = "The requested resource does not exist.", - Detail = $"Resource of type '{resourceType}' with ID '{resourceId}' does not exist." - }) - { - } -} + Title = "The requested resource does not exist.", + Detail = $"Resource of type '{resourceType}' with ID '{resourceId}' does not exist." +}); diff --git a/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs b/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs index f40f76188b..81d0a14dc8 100644 --- a/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs +++ b/src/JsonApiDotNetCore/Errors/ResourcesInRelationshipsNotFoundException.cs @@ -8,13 +8,9 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when referencing one or more non-existing resources in one or more relationships. /// [PublicAPI] -public sealed class ResourcesInRelationshipsNotFoundException : JsonApiException +public sealed class ResourcesInRelationshipsNotFoundException(IEnumerable missingResources) + : JsonApiException(missingResources.Select(CreateError)) { - public ResourcesInRelationshipsNotFoundException(IEnumerable missingResources) - : base(missingResources.Select(CreateError)) - { - } - private static ErrorObject CreateError(MissingResourceInRelationship missingResourceInRelationship) { return new ErrorObject(HttpStatusCode.NotFound) diff --git a/src/JsonApiDotNetCore/Errors/RouteNotAvailableException.cs b/src/JsonApiDotNetCore/Errors/RouteNotAvailableException.cs index 80a368379b..0bd1a3debd 100644 --- a/src/JsonApiDotNetCore/Errors/RouteNotAvailableException.cs +++ b/src/JsonApiDotNetCore/Errors/RouteNotAvailableException.cs @@ -8,17 +8,11 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when a request is received for an HTTP route that is not exposed. /// [PublicAPI] -public sealed class RouteNotAvailableException : JsonApiException +public sealed class RouteNotAvailableException(HttpMethod method, string route) : JsonApiException(new ErrorObject(HttpStatusCode.Forbidden) { - public HttpMethod Method { get; } - - public RouteNotAvailableException(HttpMethod method, string route) - : base(new ErrorObject(HttpStatusCode.Forbidden) - { - Title = "The requested endpoint is not accessible.", - Detail = $"Endpoint '{route}' is not accessible for {method} requests." - }) - { - Method = method; - } + Title = "The requested endpoint is not accessible.", + Detail = $"Endpoint '{route}' is not accessible for {method} requests." +}) +{ + public HttpMethod Method { get; } = method; } diff --git a/src/JsonApiDotNetCore/Errors/UnknownLocalIdValueException.cs b/src/JsonApiDotNetCore/Errors/UnknownLocalIdValueException.cs index b5eeef052e..4cd5e3d0de 100644 --- a/src/JsonApiDotNetCore/Errors/UnknownLocalIdValueException.cs +++ b/src/JsonApiDotNetCore/Errors/UnknownLocalIdValueException.cs @@ -8,14 +8,8 @@ namespace JsonApiDotNetCore.Errors; /// The error that is thrown when referencing a local ID that hasn't been assigned. /// [PublicAPI] -public sealed class UnknownLocalIdValueException : JsonApiException +public sealed class UnknownLocalIdValueException(string localId) : JsonApiException(new ErrorObject(HttpStatusCode.BadRequest) { - public UnknownLocalIdValueException(string localId) - : base(new ErrorObject(HttpStatusCode.BadRequest) - { - Title = "Server-generated value for local ID is not available at this point.", - Detail = $"Server-generated value for local ID '{localId}' is not available at this point." - }) - { - } -} + Title = "Server-generated value for local ID is not available at this point.", + Detail = $"Server-generated value for local ID '{localId}' is not available at this point." +}); diff --git a/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs b/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs index 0b20b897d1..c02b8c02d3 100644 --- a/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs +++ b/src/JsonApiDotNetCore/Middleware/TraceLogWriter.cs @@ -118,17 +118,12 @@ public override void Write(Utf8JsonWriter writer, TWrapper value, JsonSerializer } } -internal sealed class TraceLogWriter : TraceLogWriter +internal sealed class TraceLogWriter(ILoggerFactory loggerFactory) : TraceLogWriter { - private readonly ILogger _logger; + private readonly ILogger _logger = loggerFactory.CreateLogger(typeof(T)); private bool IsEnabled => _logger.IsEnabled(LogLevel.Trace); - public TraceLogWriter(ILoggerFactory loggerFactory) - { - _logger = loggerFactory.CreateLogger(typeof(T)); - } - public void LogMethodStart(object? parameters = null, [CallerMemberName] string memberName = "") { if (IsEnabled) diff --git a/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs b/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs index 184fd7a3c1..7e39ca5735 100644 --- a/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs +++ b/src/JsonApiDotNetCore/Queries/Expressions/PaginationElementQueryStringValueExpression.cs @@ -10,29 +10,22 @@ namespace JsonApiDotNetCore.Queries.Expressions; /// . /// [PublicAPI] -public class PaginationElementQueryStringValueExpression : QueryExpression +public class PaginationElementQueryStringValueExpression(ResourceFieldChainExpression? scope, int value, int position) : QueryExpression { /// /// The relationship this pagination applies to. Chain format: zero or more relationships, followed by a to-many relationship. /// - public ResourceFieldChainExpression? Scope { get; } + public ResourceFieldChainExpression? Scope { get; } = scope; /// /// The numeric pagination value. /// - public int Value { get; } + public int Value { get; } = value; /// /// The zero-based position in the text of the query string parameter value. /// - public int Position { get; } - - public PaginationElementQueryStringValueExpression(ResourceFieldChainExpression? scope, int value, int position) - { - Scope = scope; - Value = value; - Position = position; - } + public int Position { get; } = position; public override TResult Accept(QueryExpressionVisitor visitor, TArgument argument) { diff --git a/src/JsonApiDotNetCore/Queries/IndentingStringWriter.cs b/src/JsonApiDotNetCore/Queries/IndentingStringWriter.cs index 2d5a366c28..e5f39b6c77 100644 --- a/src/JsonApiDotNetCore/Queries/IndentingStringWriter.cs +++ b/src/JsonApiDotNetCore/Queries/IndentingStringWriter.cs @@ -2,17 +2,12 @@ namespace JsonApiDotNetCore.Queries; -internal sealed class IndentingStringWriter : IDisposable +internal sealed class IndentingStringWriter(StringBuilder builder) : IDisposable { - private readonly StringBuilder _builder; + private readonly StringBuilder _builder = builder; private int _indentDepth; - public IndentingStringWriter(StringBuilder builder) - { - _builder = builder; - } - public void WriteLine(string? line) { if (_indentDepth > 0) diff --git a/src/JsonApiDotNetCore/Queries/Parsing/ConstantValueConverter.cs b/src/JsonApiDotNetCore/Queries/Parsing/ConstantValueConverter.cs new file mode 100644 index 0000000000..d624964ddd --- /dev/null +++ b/src/JsonApiDotNetCore/Queries/Parsing/ConstantValueConverter.cs @@ -0,0 +1,15 @@ +namespace JsonApiDotNetCore.Queries.Parsing; + +/// +/// Converts a constant value within a query string parameter to an . +/// +/// +/// The constant value to convert from. +/// +/// +/// The zero-based position of in the query string parameter value. +/// +/// +/// The converted object instance. +/// +public delegate object ConstantValueConverter(string value, int position); diff --git a/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs b/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs index cbd6ee4b21..077d727368 100644 --- a/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs +++ b/src/JsonApiDotNetCore/Queries/Parsing/FilterParser.cs @@ -252,13 +252,13 @@ private QueryExpression ParseComparisonRightTerm(QueryExpression leftTerm) var leftAttribute = (AttrAttribute)leftLastField; - Func constantValueConverter = GetConstantValueConverterForAttribute(leftAttribute); + ConstantValueConverter constantValueConverter = GetConstantValueConverterForAttribute(leftAttribute); return ParseTypedComparisonRightTerm(leftAttribute.Property.PropertyType, constantValueConverter); } if (leftTerm is FunctionExpression leftFunction) { - Func constantValueConverter = GetConstantValueConverterForType(leftFunction.ReturnType); + ConstantValueConverter constantValueConverter = GetConstantValueConverterForType(leftFunction.ReturnType); return ParseTypedComparisonRightTerm(leftFunction.ReturnType, constantValueConverter); } @@ -266,7 +266,7 @@ private QueryExpression ParseComparisonRightTerm(QueryExpression leftTerm) $"Internal error: Expected left term to be a function or field chain, instead of '{leftTerm.GetType().Name}': '{leftTerm}'."); } - private QueryExpression ParseTypedComparisonRightTerm(Type leftType, Func constantValueConverter) + private QueryExpression ParseTypedComparisonRightTerm(Type leftType, ConstantValueConverter constantValueConverter) { bool allowNull = RuntimeTypeConverter.CanContainNull(leftType); @@ -329,7 +329,7 @@ protected virtual MatchTextExpression ParseTextMatch(string operatorName) EatSingleCharacterToken(TokenKind.Comma); - Func constantValueConverter = GetConstantValueConverterForAttribute(targetAttribute); + ConstantValueConverter constantValueConverter = GetConstantValueConverterForAttribute(targetAttribute); LiteralConstantExpression constant = ParseConstant(constantValueConverter); EatSingleCharacterToken(TokenKind.CloseParen); @@ -352,7 +352,7 @@ protected virtual AnyExpression ParseAny() ImmutableHashSet.Builder constantsBuilder = ImmutableHashSet.CreateBuilder(); - Func constantValueConverter = GetConstantValueConverterForAttribute(targetAttribute); + ConstantValueConverter constantValueConverter = GetConstantValueConverterForAttribute(targetAttribute); LiteralConstantExpression constant = ParseConstant(constantValueConverter); constantsBuilder.Add(constant); @@ -489,7 +489,7 @@ private static ResourceType ResolveDerivedType(ResourceType baseType, string der return filter; } - private LiteralConstantExpression ParseConstant(Func constantValueConverter) + private LiteralConstantExpression ParseConstant(ConstantValueConverter constantValueConverter) { int position = GetNextTokenPositionOrEnd(); @@ -514,7 +514,7 @@ private NullConstantExpression ParseNull() throw new QueryParseException("null expected.", position); } - private static Func GetConstantValueConverterForType(Type destinationType) + protected virtual ConstantValueConverter GetConstantValueConverterForType(Type destinationType) { return (stringValue, position) => { @@ -529,7 +529,7 @@ private static Func GetConstantValueConverterForType(Type d }; } - private Func GetConstantValueConverterForAttribute(AttrAttribute attribute) + private ConstantValueConverter GetConstantValueConverterForAttribute(AttrAttribute attribute) { if (attribute is { Property.Name: nameof(Identifiable.Id) }) { @@ -585,14 +585,9 @@ private void AssertResourceTypeStackIsEmpty() } } - private sealed class PopResourceTypeOnDispose : IDisposable + private sealed class PopResourceTypeOnDispose(Stack resourceTypeStack) : IDisposable { - private readonly Stack _resourceTypeStack; - - public PopResourceTypeOnDispose(Stack resourceTypeStack) - { - _resourceTypeStack = resourceTypeStack; - } + private readonly Stack _resourceTypeStack = resourceTypeStack; public void Dispose() { diff --git a/src/JsonApiDotNetCore/Queries/Parsing/Token.cs b/src/JsonApiDotNetCore/Queries/Parsing/Token.cs index 4700127e1d..b4751288bf 100644 --- a/src/JsonApiDotNetCore/Queries/Parsing/Token.cs +++ b/src/JsonApiDotNetCore/Queries/Parsing/Token.cs @@ -3,17 +3,11 @@ namespace JsonApiDotNetCore.Queries.Parsing; [PublicAPI] -public class Token +public class Token(TokenKind kind, int position) { - public TokenKind Kind { get; } + public TokenKind Kind { get; } = kind; public string? Value { get; } - public int Position { get; } - - public Token(TokenKind kind, int position) - { - Kind = kind; - Position = position; - } + public int Position { get; } = position; public Token(TokenKind kind, string value, int position) : this(kind, position) diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/FieldChainFormatException.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/FieldChainFormatException.cs index 8156e1474e..d4e0d35d55 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/FieldChainFormatException.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/FieldChainFormatException.cs @@ -3,16 +3,10 @@ namespace JsonApiDotNetCore.QueryStrings.FieldChains; /// /// The exception that is thrown when the format of a dot-separated resource field chain is invalid. /// -internal sealed class FieldChainFormatException : FormatException +internal sealed class FieldChainFormatException(int position, string message) : FormatException(message) { /// /// Gets the zero-based error position in the field chain, or at its end. /// - public int Position { get; } - - public FieldChainFormatException(int position, string message) - : base(message) - { - Position = position; - } + public int Position { get; } = position; } diff --git a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternFormatException.cs b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternFormatException.cs index 0a1fa13d2c..04a73f7f72 100644 --- a/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternFormatException.cs +++ b/src/JsonApiDotNetCore/QueryStrings/FieldChains/PatternFormatException.cs @@ -6,22 +6,15 @@ namespace JsonApiDotNetCore.QueryStrings.FieldChains; /// The exception that is thrown when the format of a is invalid. /// [PublicAPI] -public sealed class PatternFormatException : FormatException +public sealed class PatternFormatException(string pattern, int position, string message) : FormatException(message) { /// /// Gets the text of the invalid pattern. /// - public string Pattern { get; } + public string Pattern { get; } = pattern; /// /// Gets the zero-based error position in , or at its end. /// - public int Position { get; } - - public PatternFormatException(string pattern, int position, string message) - : base(message) - { - Pattern = pattern; - Position = position; - } + public int Position { get; } = position; } diff --git a/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs index 76bcc4a7b4..ba0f889809 100644 --- a/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/IncludeQueryStringParameterReader.cs @@ -47,14 +47,10 @@ public virtual void Read(string parameterName, StringValues parameterValue) { try { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute _includeExpression = GetInclude(parameterValue.ToString()); } catch (QueryParseException exception) { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute string specificMessage = exception.GetMessageWithPosition(parameterValue.ToString()); throw new InvalidQueryStringParameterException(parameterName, "The specified include is invalid.", specificMessage, exception); } diff --git a/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs index 3364217efb..e46e59ce18 100644 --- a/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/PaginationQueryStringParameterReader.cs @@ -58,8 +58,6 @@ public virtual void Read(string parameterName, StringValues parameterValue) try { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute PaginationQueryStringValueExpression constraint = GetPageConstraint(parameterValue.ToString()); if (constraint.Elements.Any(element => element.Scope == null)) @@ -82,8 +80,6 @@ public virtual void Read(string parameterName, StringValues parameterValue) } catch (QueryParseException exception) { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute string specificMessage = exception.GetMessageWithPosition(isParameterNameValid ? parameterValue.ToString() : parameterName); throw new InvalidQueryStringParameterException(parameterName, "The specified pagination is invalid.", specificMessage, exception); } diff --git a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs index d068ae7ce2..d1ff5fface 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SortQueryStringParameterReader.cs @@ -59,16 +59,12 @@ public virtual void Read(string parameterName, StringValues parameterValue) ResourceFieldChainExpression? scope = GetScope(parameterName); parameterNameIsValid = true; - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute SortExpression sort = GetSort(parameterValue.ToString(), scope); var expressionInScope = new ExpressionInScope(scope, sort); _constraints.Add(expressionInScope); } catch (QueryParseException exception) { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute string specificMessage = exception.GetMessageWithPosition(parameterNameIsValid ? parameterValue.ToString() : parameterName); throw new InvalidQueryStringParameterException(parameterName, "The specified sort is invalid.", specificMessage, exception); } diff --git a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs index 559da09f38..c147285636 100644 --- a/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs +++ b/src/JsonApiDotNetCore/QueryStrings/SparseFieldSetQueryStringParameterReader.cs @@ -63,15 +63,11 @@ public virtual void Read(string parameterName, StringValues parameterValue) ResourceType resourceType = GetScope(parameterName); parameterNameIsValid = true; - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute SparseFieldSetExpression sparseFieldSet = GetSparseFieldSet(parameterValue.ToString(), resourceType); _sparseFieldTableBuilder[resourceType] = sparseFieldSet; } catch (QueryParseException exception) { - // Workaround for https://youtrack.jetbrains.com/issue/RSRP-493256/Incorrect-possible-null-assignment - // ReSharper disable once AssignNullToNotNullAttribute string specificMessage = exception.GetMessageWithPosition(parameterNameIsValid ? parameterValue.ToString() : parameterName); throw new InvalidQueryStringParameterException(parameterName, "The specified fieldset is invalid.", specificMessage, exception); } diff --git a/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs b/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs index e823b50077..4855c7fb6a 100644 --- a/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs +++ b/src/JsonApiDotNetCore/Repositories/DataStoreUpdateException.cs @@ -6,10 +6,4 @@ namespace JsonApiDotNetCore.Repositories; /// The error that is thrown when the underlying data store is unable to persist changes. /// [PublicAPI] -public sealed class DataStoreUpdateException : Exception -{ - public DataStoreUpdateException(Exception? innerException) - : base("Failed to persist changes in the underlying data store.", innerException) - { - } -} +public sealed class DataStoreUpdateException(Exception? innerException) : Exception("Failed to persist changes in the underlying data store.", innerException); diff --git a/src/JsonApiDotNetCore/Serialization/Objects/Document.cs b/src/JsonApiDotNetCore/Serialization/Objects/Document.cs index e0d7d5def3..f21334f5c4 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/Document.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/Document.cs @@ -1,10 +1,12 @@ using System.Text.Json.Serialization; +using JetBrains.Annotations; namespace JsonApiDotNetCore.Serialization.Objects; /// /// See https://jsonapi.org/format#document-top-level and https://jsonapi.org/ext/atomic/#document-structure. /// +[PublicAPI] public sealed class Document { [JsonPropertyName("jsonapi")] diff --git a/src/JsonApiDotNetCore/Serialization/Objects/ErrorObject.cs b/src/JsonApiDotNetCore/Serialization/Objects/ErrorObject.cs index 68a2a19d3a..63d95174cd 100644 --- a/src/JsonApiDotNetCore/Serialization/Objects/ErrorObject.cs +++ b/src/JsonApiDotNetCore/Serialization/Objects/ErrorObject.cs @@ -8,7 +8,7 @@ namespace JsonApiDotNetCore.Serialization.Objects; /// See https://jsonapi.org/format/#error-objects. /// [PublicAPI] -public sealed class ErrorObject +public sealed class ErrorObject(HttpStatusCode statusCode) { [JsonPropertyName("id")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] @@ -19,7 +19,7 @@ public sealed class ErrorObject public ErrorLinks? Links { get; set; } [JsonIgnore] - public HttpStatusCode StatusCode { get; set; } + public HttpStatusCode StatusCode { get; set; } = statusCode; [JsonPropertyName("status")] [JsonIgnore(Condition = JsonIgnoreCondition.Never)] @@ -49,11 +49,6 @@ public string Status [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public IDictionary? Meta { get; set; } - public ErrorObject(HttpStatusCode statusCode) - { - StatusCode = statusCode; - } - public static HttpStatusCode GetResponseStatusCode(IReadOnlyList errorObjects) { if (errorObjects.IsNullOrEmpty()) diff --git a/src/JsonApiDotNetCore/Serialization/Request/Adapters/AtomicReferenceAdapter.cs b/src/JsonApiDotNetCore/Serialization/Request/Adapters/AtomicReferenceAdapter.cs index f7a5ad82fa..8e682439aa 100644 --- a/src/JsonApiDotNetCore/Serialization/Request/Adapters/AtomicReferenceAdapter.cs +++ b/src/JsonApiDotNetCore/Serialization/Request/Adapters/AtomicReferenceAdapter.cs @@ -8,13 +8,9 @@ namespace JsonApiDotNetCore.Serialization.Request.Adapters; /// [PublicAPI] -public sealed class AtomicReferenceAdapter : ResourceIdentityAdapter, IAtomicReferenceAdapter +public sealed class AtomicReferenceAdapter(IResourceGraph resourceGraph, IResourceFactory resourceFactory) + : ResourceIdentityAdapter(resourceGraph, resourceFactory), IAtomicReferenceAdapter { - public AtomicReferenceAdapter(IResourceGraph resourceGraph, IResourceFactory resourceFactory) - : base(resourceGraph, resourceFactory) - { - } - /// public AtomicReferenceResult Convert(AtomicReference atomicReference, ResourceIdentityRequirements requirements, RequestAdapterState state) { diff --git a/src/JsonApiDotNetCore/Serialization/Request/Adapters/RequestAdapterPosition.cs b/src/JsonApiDotNetCore/Serialization/Request/Adapters/RequestAdapterPosition.cs index 644383e711..3b114f61f4 100644 --- a/src/JsonApiDotNetCore/Serialization/Request/Adapters/RequestAdapterPosition.cs +++ b/src/JsonApiDotNetCore/Serialization/Request/Adapters/RequestAdapterPosition.cs @@ -55,14 +55,9 @@ public override string ToString() return ToSourcePointer() ?? string.Empty; } - private sealed class PopStackOnDispose : IDisposable + private sealed class PopStackOnDispose(RequestAdapterPosition owner) : IDisposable { - private readonly RequestAdapterPosition _owner; - - public PopStackOnDispose(RequestAdapterPosition owner) - { - _owner = owner; - } + private readonly RequestAdapterPosition _owner = owner; public void Dispose() { diff --git a/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceDataInOperationsRequestAdapter.cs b/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceDataInOperationsRequestAdapter.cs index afccb303b5..7c299b0b5e 100644 --- a/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceDataInOperationsRequestAdapter.cs +++ b/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceDataInOperationsRequestAdapter.cs @@ -5,13 +5,9 @@ namespace JsonApiDotNetCore.Serialization.Request.Adapters; /// -public sealed class ResourceDataInOperationsRequestAdapter : ResourceDataAdapter, IResourceDataInOperationsRequestAdapter +public sealed class ResourceDataInOperationsRequestAdapter(IResourceDefinitionAccessor resourceDefinitionAccessor, IResourceObjectAdapter resourceObjectAdapter) + : ResourceDataAdapter(resourceDefinitionAccessor, resourceObjectAdapter), IResourceDataInOperationsRequestAdapter { - public ResourceDataInOperationsRequestAdapter(IResourceDefinitionAccessor resourceDefinitionAccessor, IResourceObjectAdapter resourceObjectAdapter) - : base(resourceDefinitionAccessor, resourceObjectAdapter) - { - } - protected override (IIdentifiable resource, ResourceType resourceType) ConvertResourceObject(SingleOrManyData data, ResourceIdentityRequirements requirements, RequestAdapterState state) { diff --git a/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceIdentifierObjectAdapter.cs b/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceIdentifierObjectAdapter.cs index 8032c6c60c..bc9d380388 100644 --- a/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceIdentifierObjectAdapter.cs +++ b/src/JsonApiDotNetCore/Serialization/Request/Adapters/ResourceIdentifierObjectAdapter.cs @@ -5,13 +5,9 @@ namespace JsonApiDotNetCore.Serialization.Request.Adapters; /// -public sealed class ResourceIdentifierObjectAdapter : ResourceIdentityAdapter, IResourceIdentifierObjectAdapter +public sealed class ResourceIdentifierObjectAdapter(IResourceGraph resourceGraph, IResourceFactory resourceFactory) + : ResourceIdentityAdapter(resourceGraph, resourceFactory), IResourceIdentifierObjectAdapter { - public ResourceIdentifierObjectAdapter(IResourceGraph resourceGraph, IResourceFactory resourceFactory) - : base(resourceGraph, resourceFactory) - { - } - /// public IIdentifiable Convert(ResourceIdentifierObject resourceIdentifierObject, ResourceIdentityRequirements requirements, RequestAdapterState state) { diff --git a/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs b/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs index 3ecc0b2c5a..5baef6c086 100644 --- a/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs +++ b/src/JsonApiDotNetCore/Serialization/Response/FingerprintGenerator.cs @@ -6,11 +6,7 @@ namespace JsonApiDotNetCore.Serialization.Response; /// internal sealed class FingerprintGenerator : IFingerprintGenerator { -#if NET6_0 - private static readonly byte[] Separator = Encoding.UTF8.GetBytes("|"); -#else private static readonly byte[] Separator = "|"u8.ToArray(); -#endif private static readonly uint[] LookupTable = Enumerable.Range(0, 256).Select(ToLookupEntry).ToArray(); private static uint ToLookupEntry(int index) diff --git a/test/DapperTests/IntegrationTests/DapperTestContext.cs b/test/DapperTests/IntegrationTests/DapperTestContext.cs index 6bbcca6777..233162e2e8 100644 --- a/test/DapperTests/IntegrationTests/DapperTestContext.cs +++ b/test/DapperTests/IntegrationTests/DapperTestContext.cs @@ -69,6 +69,10 @@ private WebApplicationFactory CreateFactory() { if (_testOutputHelper != null) { +#if !DEBUG + // Reduce logging output when running tests in ci-build. + loggingBuilder.ClearProviders(); +#endif loggingBuilder.Services.AddSingleton(_ => new XUnitLoggerProvider(_testOutputHelper, "DapperExample.")); } }); diff --git a/test/DapperTests/IntegrationTests/FrozenClock.cs b/test/DapperTests/IntegrationTests/FrozenClock.cs index 0de2390b71..c7ca4ea851 100644 --- a/test/DapperTests/IntegrationTests/FrozenClock.cs +++ b/test/DapperTests/IntegrationTests/FrozenClock.cs @@ -1,8 +1,10 @@ using DapperExample; using FluentAssertions.Extensions; +using JetBrains.Annotations; namespace DapperTests.IntegrationTests; +[UsedImplicitly(ImplicitUseTargetFlags.Members)] internal sealed class FrozenClock : IClock { private static readonly DateTimeOffset DefaultTime = 1.January(2020).At(1, 1, 1).AsUtc(); diff --git a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs index a88646c7a7..de860f5814 100644 --- a/test/DapperTests/IntegrationTests/SqlTextAdapter.cs +++ b/test/DapperTests/IntegrationTests/SqlTextAdapter.cs @@ -3,7 +3,7 @@ namespace DapperTests.IntegrationTests; -internal sealed class SqlTextAdapter +internal sealed class SqlTextAdapter(DatabaseProvider databaseProvider) { private static readonly Dictionary SqlServerReplacements = new() { @@ -11,12 +11,7 @@ [new Regex("\"([^\"]+)\"", RegexOptions.Compiled)] = "[$+]", [new Regex($@"(VALUES \([^)]*\)){Environment.NewLine}RETURNING \[Id\]", RegexOptions.Compiled)] = $"OUTPUT INSERTED.[Id]{Environment.NewLine}$1" }; - private readonly DatabaseProvider _databaseProvider; - - public SqlTextAdapter(DatabaseProvider databaseProvider) - { - _databaseProvider = databaseProvider; - } + private readonly DatabaseProvider _databaseProvider = databaseProvider; public string Adapt(string text, bool hasClientGeneratedId) { diff --git a/test/DiscoveryTests/PrivateResourceDefinition.cs b/test/DiscoveryTests/PrivateResourceDefinition.cs index 25ff719718..80883eaa6d 100644 --- a/test/DiscoveryTests/PrivateResourceDefinition.cs +++ b/test/DiscoveryTests/PrivateResourceDefinition.cs @@ -5,10 +5,4 @@ namespace DiscoveryTests; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class PrivateResourceDefinition : JsonApiResourceDefinition -{ - public PrivateResourceDefinition(IResourceGraph resourceGraph) - : base(resourceGraph) - { - } -} +public sealed class PrivateResourceDefinition(IResourceGraph resourceGraph) : JsonApiResourceDefinition(resourceGraph); diff --git a/test/DiscoveryTests/PrivateResourceRepository.cs b/test/DiscoveryTests/PrivateResourceRepository.cs index cb654ea724..eb33d18440 100644 --- a/test/DiscoveryTests/PrivateResourceRepository.cs +++ b/test/DiscoveryTests/PrivateResourceRepository.cs @@ -8,12 +8,8 @@ namespace DiscoveryTests; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class PrivateResourceRepository : EntityFrameworkCoreRepository -{ - public PrivateResourceRepository(ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - } -} +public sealed class PrivateResourceRepository( + ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor); diff --git a/test/DiscoveryTests/PrivateResourceService.cs b/test/DiscoveryTests/PrivateResourceService.cs index 6d289eafb1..751d04baab 100644 --- a/test/DiscoveryTests/PrivateResourceService.cs +++ b/test/DiscoveryTests/PrivateResourceService.cs @@ -10,12 +10,8 @@ namespace DiscoveryTests; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class PrivateResourceService : JsonApiResourceService -{ - public PrivateResourceService(IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, - IJsonApiOptions options, ILoggerFactory loggerFactory, IJsonApiRequest request, IResourceChangeTracker resourceChangeTracker, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor) - { - } -} +public sealed class PrivateResourceService( + IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, IJsonApiOptions options, + ILoggerFactory loggerFactory, IJsonApiRequest request, IResourceChangeTracker resourceChangeTracker, + IResourceDefinitionAccessor resourceDefinitionAccessor) : JsonApiResourceService(repositoryAccessor, queryLayerComposer, + paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionBroadcastDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionBroadcastDefinition.cs index 19a0208b17..5ec385081b 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionBroadcastDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionBroadcastDefinition.cs @@ -13,23 +13,16 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Archiving; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TelevisionBroadcastDefinition : JsonApiResourceDefinition +public sealed class TelevisionBroadcastDefinition( + IResourceGraph resourceGraph, TelevisionDbContext dbContext, IJsonApiRequest request, IEnumerable constraintProviders) + : JsonApiResourceDefinition(resourceGraph) { - private readonly TelevisionDbContext _dbContext; - private readonly IJsonApiRequest _request; - private readonly IEnumerable _constraintProviders; + private readonly TelevisionDbContext _dbContext = dbContext; + private readonly IJsonApiRequest _request = request; + private readonly IEnumerable _constraintProviders = constraintProviders; private DateTimeOffset? _storedArchivedAt; - public TelevisionBroadcastDefinition(IResourceGraph resourceGraph, TelevisionDbContext dbContext, IJsonApiRequest request, - IEnumerable constraintProviders) - : base(resourceGraph) - { - _dbContext = dbContext; - _request = request; - _constraintProviders = constraintProviders; - } - public override FilterExpression? OnApplyFilter(FilterExpression? existingFilter) { if (_request.IsReadOnly) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionDbContext.cs index f378dd5846..b05a82f382 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Archiving/TelevisionDbContext.cs @@ -5,15 +5,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Archiving; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class TelevisionDbContext : TestableDbContext +public sealed class TelevisionDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Networks => Set(); public DbSet Stations => Set(); public DbSet Broadcasts => Set(); public DbSet Comments => Set(); - - public TelevisionDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs index 5c9647f6f7..8285661ede 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Controllers/CreateMusicTrackOperationsController.cs @@ -14,14 +14,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Controllers; [DisableRoutingConvention] [Route("/operations/musicTracks/create")] -public sealed class CreateMusicTrackOperationsController : JsonApiOperationsController +public sealed class CreateMusicTrackOperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields) { - public CreateMusicTrackOperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IOperationsProcessor processor, IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } - public override Task PostOperationsAsync(IList operations, CancellationToken cancellationToken) { AssertOnlyCreatingMusicTracks(operations); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ImplicitlyChangingTextLanguageDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ImplicitlyChangingTextLanguageDefinition.cs index 4548e31c16..fedd490ddd 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ImplicitlyChangingTextLanguageDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ImplicitlyChangingTextLanguageDefinition.cs @@ -9,17 +9,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations; /// Used to simulate side effects that occur in the database while saving, typically caused by database triggers. /// [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class ImplicitlyChangingTextLanguageDefinition : HitCountingResourceDefinition +public class ImplicitlyChangingTextLanguageDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter, OperationsDbContext dbContext) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { internal const string Suffix = " (changed)"; - private readonly OperationsDbContext _dbContext; - - public ImplicitlyChangingTextLanguageDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter, OperationsDbContext dbContext) - : base(resourceGraph, hitCounter) - { - _dbContext = dbContext; - } + private readonly OperationsDbContext _dbContext = dbContext; public override async Task OnWriteSucceededAsync(TextLanguage resource, WriteOperationKind writeOperation, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs index be59668c1c..3c8dda12ab 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/MusicTrackMetaDefinition.cs @@ -4,15 +4,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Meta; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class MusicTrackMetaDefinition : HitCountingResourceDefinition +public sealed class MusicTrackMetaDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.GetMeta; - public MusicTrackMetaDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - } - public override IDictionary GetMeta(MusicTrack resource) { base.GetMeta(resource); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs index f46b2940a6..679a3b76a9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Meta/TextLanguageMetaDefinition.cs @@ -4,17 +4,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Meta; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TextLanguageMetaDefinition : ImplicitlyChangingTextLanguageDefinition +public sealed class TextLanguageMetaDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter, OperationsDbContext dbContext) + : ImplicitlyChangingTextLanguageDefinition(resourceGraph, hitCounter, dbContext) { internal const string NoticeText = "See https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes for ISO 639-1 language codes."; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.GetMeta; - public TextLanguageMetaDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter, OperationsDbContext dbContext) - : base(resourceGraph, hitCounter, dbContext) - { - } - public override IDictionary GetMeta(TextLanguage resource) { base.GetMeta(resource); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicLoggingTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicLoggingTests.cs index bae5abf988..58824a8bf9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicLoggingTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Mixed/AtomicLoggingTests.cs @@ -135,17 +135,12 @@ public Task BeginTransactionAsync(CancellationToken canc return Task.FromResult(transaction); } - private sealed class ThrowingOperationsTransaction : IOperationsTransaction + private sealed class ThrowingOperationsTransaction(ThrowingOperationsTransactionFactory owner) : IOperationsTransaction { - private readonly ThrowingOperationsTransactionFactory _owner; + private readonly ThrowingOperationsTransactionFactory _owner = owner; public string TransactionId => "some"; - public ThrowingOperationsTransaction(ThrowingOperationsTransactionFactory owner) - { - _owner = owner; - } - public ValueTask DisposeAsync() { return ValueTask.CompletedTask; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsController.cs index 08ef7b169b..5380300ede 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsController.cs @@ -7,11 +7,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations; -public sealed class OperationsController : JsonApiOperationsController -{ - public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } -} +public sealed class OperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs index 6fd7817ba7..e4e22195a8 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/OperationsDbContext.cs @@ -7,7 +7,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class OperationsDbContext : TestableDbContext +public sealed class OperationsDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Playlists => Set(); public DbSet MusicTracks => Set(); @@ -16,11 +16,6 @@ public sealed class OperationsDbContext : TestableDbContext public DbSet Performers => Set(); public DbSet RecordCompanies => Set(); - public OperationsDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/RecordCompanyDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/RecordCompanyDefinition.cs index 4db0e6fe3c..4c89170efc 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/RecordCompanyDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/Serialization/RecordCompanyDefinition.cs @@ -4,15 +4,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.ResourceDefinitions.Serialization; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class RecordCompanyDefinition : HitCountingResourceDefinition +public sealed class RecordCompanyDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Serialization; - public RecordCompanyDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - } - public override void OnDeserialize(RecordCompany resource) { base.OnDeserialize(resource); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/SparseFieldSets/LyricTextDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/SparseFieldSets/LyricTextDefinition.cs index 3abc4a134c..8f38b1aa32 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/SparseFieldSets/LyricTextDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/ResourceDefinitions/SparseFieldSets/LyricTextDefinition.cs @@ -5,18 +5,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.ResourceDefinitions.SparseFieldSets; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class LyricTextDefinition : HitCountingResourceDefinition +public sealed class LyricTextDefinition(IResourceGraph resourceGraph, LyricPermissionProvider lyricPermissionProvider, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly LyricPermissionProvider _lyricPermissionProvider; + private readonly LyricPermissionProvider _lyricPermissionProvider = lyricPermissionProvider; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.OnApplySparseFieldSet; - public LyricTextDefinition(IResourceGraph resourceGraph, LyricPermissionProvider lyricPermissionProvider, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - _lyricPermissionProvider = lyricPermissionProvider; - } - public override SparseFieldSetExpression? OnApplySparseFieldSet(SparseFieldSetExpression? existingSparseFieldSet) { base.OnApplySparseFieldSet(existingSparseFieldSet); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs index 8638855a46..efc9ebaeaa 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/ExtraDbContext.cs @@ -5,10 +5,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Transactions; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ExtraDbContext : TestableDbContext -{ - public ExtraDbContext(DbContextOptions options) - : base(options) - { - } -} +public sealed class ExtraDbContext(DbContextOptions options) : TestableDbContext(options); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs index 6512b3fb27..7766b67570 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/AtomicOperations/Transactions/MusicTrackRepository.cs @@ -8,14 +8,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.AtomicOperations.Transactions; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class MusicTrackRepository : EntityFrameworkCoreRepository +public sealed class MusicTrackRepository( + ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor) { public override string? TransactionId => null; - - public MusicTrackRepository(ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/OperationsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/OperationsController.cs index bfdf4aaa94..357ff7ef5a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/OperationsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/OperationsController.cs @@ -10,14 +10,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Authorization.Scopes; -public sealed class OperationsController : JsonApiOperationsController +public sealed class OperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields) { - public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } - public override async Task PostOperationsAsync(IList operations, CancellationToken cancellationToken) { AuthScopeSet requestedScopes = AuthScopeSet.GetRequestedScopes(HttpContext.Request.Headers); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesAuthorizationFilter.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesAuthorizationFilter.cs index a788b3e115..a4cba72878 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesAuthorizationFilter.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesAuthorizationFilter.cs @@ -60,14 +60,9 @@ private AuthScopeSet GetRequiredScopes(IJsonApiRequest request, ITargetedFields return requiredScopes; } - private sealed class QueryStringWalker : QueryExpressionRewriter + private sealed class QueryStringWalker(AuthScopeSet authScopeSet) : QueryExpressionRewriter { - private readonly AuthScopeSet _authScopeSet; - - public QueryStringWalker(AuthScopeSet authScopeSet) - { - _authScopeSet = authScopeSet; - } + private readonly AuthScopeSet _authScopeSet = authScopeSet; public void IncludeScopesFrom(IEnumerable constraintProviders) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesDbContext.cs index 26ce29ff8f..81af9423d2 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Authorization/Scopes/ScopesDbContext.cs @@ -5,14 +5,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Authorization.Scopes; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ScopesDbContext : TestableDbContext +public sealed class ScopesDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Movies => Set(); public DbSet Actors => Set(); public DbSet Genres => Set(); - - public ScopesDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobDbContext.cs index 88a891c319..64c8cd7569 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Blobs/BlobDbContext.cs @@ -5,12 +5,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Blobs; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class BlobDbContext : TestableDbContext +public sealed class BlobDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet ImageContainers => Set(); - - public BlobDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarCompositeKeyAwareRepository.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarCompositeKeyAwareRepository.cs index 989967bc10..b818c0f094 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarCompositeKeyAwareRepository.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CarCompositeKeyAwareRepository.cs @@ -9,18 +9,14 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.CompositeKeys; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class CarCompositeKeyAwareRepository : EntityFrameworkCoreRepository +public class CarCompositeKeyAwareRepository( + ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor) where TResource : class, IIdentifiable { - private readonly CarExpressionRewriter _writer; - - public CarCompositeKeyAwareRepository(ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - _writer = new CarExpressionRewriter(resourceGraph); - } + private readonly CarExpressionRewriter _writer = new(resourceGraph); protected override IQueryable ApplyQueryLayer(QueryLayer queryLayer) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs index d4850ad428..3d10a70df6 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CompositeKeys/CompositeDbContext.cs @@ -7,17 +7,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.CompositeKeys; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class CompositeDbContext : TestableDbContext +public sealed class CompositeDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Cars => Set(); public DbSet Engines => Set(); public DbSet Dealerships => Set(); - public CompositeDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/OperationsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/OperationsController.cs index d24a0f29d1..dfe7282eac 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/OperationsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/OperationsController.cs @@ -7,11 +7,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ContentNegotiation; -public sealed class OperationsController : JsonApiOperationsController -{ - public OperationsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, - IJsonApiRequest request, ITargetedFields targetedFields) - : base(options, resourceGraph, loggerFactory, processor, request, targetedFields) - { - } -} +public sealed class OperationsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IOperationsProcessor processor, IJsonApiRequest request, + ITargetedFields targetedFields) : JsonApiOperationsController(options, resourceGraph, loggerFactory, processor, request, targetedFields); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs index 2526faae2e..bf96700a06 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ContentNegotiation/PolicyDbContext.cs @@ -5,12 +5,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ContentNegotiation; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class PolicyDbContext : TestableDbContext +public sealed class PolicyDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Policies => Set(); - - public PolicyDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs index d0a6050a0b..bbf27df0d3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ControllerActionResults/ActionResultDbContext.cs @@ -5,12 +5,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ControllerActionResults; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ActionResultDbContext : TestableDbContext +public sealed class ActionResultDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Toothbrushes => Set(); - - public ActionResultDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs index 9e2debb9a0..43c3bfa59f 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/CustomRoutes/CustomRouteDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.CustomRoutes; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class CustomRouteDbContext : TestableDbContext +public sealed class CustomRouteDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Towns => Set(); public DbSet Civilians => Set(); - - public CustomRouteDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/BuildingRepository.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/BuildingRepository.cs index 888f060ca1..8f6d59c7b1 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/BuildingRepository.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/BuildingRepository.cs @@ -8,15 +8,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.EagerLoading; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class BuildingRepository : EntityFrameworkCoreRepository +public sealed class BuildingRepository( + ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor) + : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, + resourceDefinitionAccessor) { - public BuildingRepository(ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - } - public override async Task GetForCreateAsync(Type resourceClrType, int id, CancellationToken cancellationToken) { Building building = await base.GetForCreateAsync(resourceClrType, id, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs index a31deab9a8..9b0932064c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/EagerLoading/EagerLoadingDbContext.cs @@ -7,18 +7,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.EagerLoading; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class EagerLoadingDbContext : TestableDbContext +public sealed class EagerLoadingDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet States => Set(); public DbSet Streets => Set(); public DbSet Buildings => Set(); public DbSet Doors => Set(); - public EagerLoadingDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/AlternateExceptionHandler.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/AlternateExceptionHandler.cs index 4af459fb71..6e406d9e0c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/AlternateExceptionHandler.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/AlternateExceptionHandler.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ExceptionHandling; -public sealed class AlternateExceptionHandler : ExceptionHandler +public sealed class AlternateExceptionHandler(ILoggerFactory loggerFactory, IJsonApiOptions options) : ExceptionHandler(loggerFactory, options) { - public AlternateExceptionHandler(ILoggerFactory loggerFactory, IJsonApiOptions options) - : base(loggerFactory, options) - { - } - protected override LogLevel GetLogLevel(Exception exception) { if (exception is ConsumerArticleIsNoLongerAvailableException) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs index 6c913ac04b..a1f7f15fcf 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleIsNoLongerAvailableException.cs @@ -4,17 +4,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ExceptionHandling; -internal sealed class ConsumerArticleIsNoLongerAvailableException : JsonApiException -{ - public string SupportEmailAddress { get; } - - public ConsumerArticleIsNoLongerAvailableException(string articleCode, string supportEmailAddress) - : base(new ErrorObject(HttpStatusCode.Gone) - { - Title = "The requested article is no longer available.", - Detail = $"Article with code '{articleCode}' is no longer available." - }) +internal sealed class ConsumerArticleIsNoLongerAvailableException(string articleCode, string supportEmailAddress) : JsonApiException( + new ErrorObject(HttpStatusCode.Gone) { - SupportEmailAddress = supportEmailAddress; - } + Title = "The requested article is no longer available.", + Detail = $"Article with code '{articleCode}' is no longer available." + }) +{ + public string SupportEmailAddress { get; } = supportEmailAddress; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs index 335bf7e9fb..fe110f7714 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ConsumerArticleService.cs @@ -10,18 +10,15 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ExceptionHandling; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class ConsumerArticleService : JsonApiResourceService +public sealed class ConsumerArticleService( + IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, IJsonApiOptions options, + ILoggerFactory loggerFactory, IJsonApiRequest request, IResourceChangeTracker resourceChangeTracker, + IResourceDefinitionAccessor resourceDefinitionAccessor) : JsonApiResourceService(repositoryAccessor, queryLayerComposer, + paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor) { private const string SupportEmailAddress = "company@email.com"; internal const string UnavailableArticlePrefix = "X"; - public ConsumerArticleService(IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, - IJsonApiOptions options, ILoggerFactory loggerFactory, IJsonApiRequest request, IResourceChangeTracker resourceChangeTracker, - IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor) - { - } - public override async Task GetAsync(int id, CancellationToken cancellationToken) { ConsumerArticle consumerArticle = await base.GetAsync(id, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs index bf176e681e..fb90f661fa 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ExceptionHandling/ErrorDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ExceptionHandling; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ErrorDbContext : TestableDbContext +public sealed class ErrorDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet ConsumerArticles => Set(); public DbSet ThrowingArticles => Set(); - - public ErrorDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingDbContext.cs index a99db32f47..a27f87c770 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/HostingInIIS/HostingDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.HostingInIIS; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class HostingDbContext : TestableDbContext +public sealed class HostingDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet ArtGalleries => Set(); public DbSet Paintings => Set(); - - public HostingDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/BankAccountsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/BankAccountsController.cs index eedc36ff87..b34fe3a321 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/BankAccountsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/BankAccountsController.cs @@ -4,11 +4,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.IdObfuscation; -public sealed class BankAccountsController : ObfuscatedIdentifiableController -{ - public BankAccountsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} +public sealed class BankAccountsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : ObfuscatedIdentifiableController(options, resourceGraph, loggerFactory, resourceService); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/DebitCardsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/DebitCardsController.cs index e8c426572a..7fb26d5708 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/DebitCardsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/DebitCardsController.cs @@ -4,11 +4,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.IdObfuscation; -public sealed class DebitCardsController : ObfuscatedIdentifiableController -{ - public DebitCardsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} +public sealed class DebitCardsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : ObfuscatedIdentifiableController(options, resourceGraph, loggerFactory, resourceService); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscatedIdentifiableController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscatedIdentifiableController.cs index cded455259..4f8c5af49b 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscatedIdentifiableController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscatedIdentifiableController.cs @@ -7,17 +7,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.IdObfuscation; -public abstract class ObfuscatedIdentifiableController : BaseJsonApiController +public abstract class ObfuscatedIdentifiableController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : BaseJsonApiController(options, resourceGraph, loggerFactory, resourceService) where TResource : class, IIdentifiable { private readonly HexadecimalCodec _codec = new(); - protected ObfuscatedIdentifiableController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } - [HttpGet] public override Task GetAsync(CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs index efc83bbdf8..820a6cf554 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/IdObfuscation/ObfuscationDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.IdObfuscation; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ObfuscationDbContext : TestableDbContext +public sealed class ObfuscationDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet BankAccounts => Set(); public DbSet DebitCards => Set(); - - public ObfuscationDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs index 1bfdb1a28e..3d41c39035 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/ModelState/ModelStateDbContext.cs @@ -7,17 +7,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.InputValidation.ModelState; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ModelStateDbContext : TestableDbContext +public sealed class ModelStateDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Volumes => Set(); public DbSet Directories => Set(); public DbSet Files => Set(); - public ModelStateDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDbContext.cs index 438093f855..e49e5618a2 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDbContext.cs @@ -7,12 +7,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.InputValidation.RequestBody; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class WorkflowDbContext : TestableDbContext +public sealed class WorkflowDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Workflows => Set(); - - public WorkflowDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDefinition.cs index f63b793e5b..cdcd268558 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/InputValidation/RequestBody/WorkflowDefinition.cs @@ -9,7 +9,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.InputValidation.RequestBody; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class WorkflowDefinition : JsonApiResourceDefinition +public sealed class WorkflowDefinition(IResourceGraph resourceGraph) : JsonApiResourceDefinition(resourceGraph) { private static readonly Dictionary> StageTransitionTable = new() { @@ -33,11 +33,6 @@ public sealed class WorkflowDefinition : JsonApiResourceDefinition options) : TestableDbContext(options) { public DbSet PhotoAlbums => Set(); public DbSet Photos => Set(); public DbSet PhotoLocations => Set(); - public LinksDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingDbContext.cs index 26d86c8c3f..262f8e1aee 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Logging/LoggingDbContext.cs @@ -5,16 +5,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Logging; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class LoggingDbContext : TestableDbContext +public sealed class LoggingDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet AuditEntries => Set(); public DbSet FruitBowls => Set(); public DbSet Fruits => Set(); public DbSet Bananas => Set(); public DbSet Peaches => Set(); - - public LoggingDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/MetaDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/MetaDbContext.cs index 84937ff3d5..a1ab87c420 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/MetaDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/MetaDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Meta; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class MetaDbContext : TestableDbContext +public sealed class MetaDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet ProductFamilies => Set(); public DbSet SupportTickets => Set(); - - public MetaDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/SupportTicketDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/SupportTicketDefinition.cs index 6ca207d0aa..20e5078bfe 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/SupportTicketDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Meta/SupportTicketDefinition.cs @@ -4,15 +4,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Meta; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class SupportTicketDefinition : HitCountingResourceDefinition +public sealed class SupportTicketDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.GetMeta; - public SupportTicketDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - } - public override IDictionary? GetMeta(SupportTicket resource) { base.GetMeta(resource); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetDbContext.cs index 83cddc52f0..c25715d282 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetDbContext.cs @@ -5,13 +5,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.FireAndForgetDelivery; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class FireForgetDbContext : TestableDbContext +public sealed class FireForgetDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Users => Set(); public DbSet Groups => Set(); - - public FireForgetDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetGroupDefinition.cs index a148a47b20..f23dd9670e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetGroupDefinition.cs @@ -6,18 +6,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.FireAndForgetDelivery; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class FireForgetGroupDefinition : MessagingGroupDefinition +public sealed class FireForgetGroupDefinition( + IResourceGraph resourceGraph, FireForgetDbContext dbContext, MessageBroker messageBroker, ResourceDefinitionHitCounter hitCounter) + : MessagingGroupDefinition(resourceGraph, dbContext.Users, dbContext.Groups, hitCounter) { - private readonly MessageBroker _messageBroker; + private readonly MessageBroker _messageBroker = messageBroker; private DomainGroup? _groupToDelete; - public FireForgetGroupDefinition(IResourceGraph resourceGraph, FireForgetDbContext dbContext, MessageBroker messageBroker, - ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, dbContext.Users, dbContext.Groups, hitCounter) - { - _messageBroker = messageBroker; - } - public override async Task OnWritingAsync(DomainGroup group, WriteOperationKind writeOperation, CancellationToken cancellationToken) { await base.OnWritingAsync(group, writeOperation, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetUserDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetUserDefinition.cs index c72cd667f0..86afa84846 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetUserDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/FireAndForgetDelivery/FireForgetUserDefinition.cs @@ -6,18 +6,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.FireAndForgetDelivery; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class FireForgetUserDefinition : MessagingUserDefinition +public sealed class FireForgetUserDefinition( + IResourceGraph resourceGraph, FireForgetDbContext dbContext, MessageBroker messageBroker, ResourceDefinitionHitCounter hitCounter) + : MessagingUserDefinition(resourceGraph, dbContext.Users, hitCounter) { - private readonly MessageBroker _messageBroker; + private readonly MessageBroker _messageBroker = messageBroker; private DomainUser? _userToDelete; - public FireForgetUserDefinition(IResourceGraph resourceGraph, FireForgetDbContext dbContext, MessageBroker messageBroker, - ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, dbContext.Users, hitCounter) - { - _messageBroker = messageBroker; - } - public override async Task OnWritingAsync(DomainUser user, WriteOperationKind writeOperation, CancellationToken cancellationToken) { await base.OnWritingAsync(user, writeOperation, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupCreatedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupCreatedContent.cs index c7c400ae4f..75abfd7170 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupCreatedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupCreatedContent.cs @@ -3,16 +3,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class GroupCreatedContent : IMessageContent +public sealed class GroupCreatedContent(Guid groupId, string groupName) : IMessageContent { public int FormatVersion => 1; - public Guid GroupId { get; } - public string GroupName { get; } - - public GroupCreatedContent(Guid groupId, string groupName) - { - GroupId = groupId; - GroupName = groupName; - } + public Guid GroupId { get; } = groupId; + public string GroupName { get; } = groupName; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupDeletedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupDeletedContent.cs index 338b88a676..1d11b80d84 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupDeletedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupDeletedContent.cs @@ -3,14 +3,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class GroupDeletedContent : IMessageContent +public sealed class GroupDeletedContent(Guid groupId) : IMessageContent { public int FormatVersion => 1; - public Guid GroupId { get; } - - public GroupDeletedContent(Guid groupId) - { - GroupId = groupId; - } + public Guid GroupId { get; } = groupId; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupRenamedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupRenamedContent.cs index 2412e9c8c1..d2745f5694 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupRenamedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/GroupRenamedContent.cs @@ -3,18 +3,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class GroupRenamedContent : IMessageContent +public sealed class GroupRenamedContent(Guid groupId, string beforeGroupName, string afterGroupName) : IMessageContent { public int FormatVersion => 1; - public Guid GroupId { get; } - public string BeforeGroupName { get; } - public string AfterGroupName { get; } - - public GroupRenamedContent(Guid groupId, string beforeGroupName, string afterGroupName) - { - GroupId = groupId; - BeforeGroupName = beforeGroupName; - AfterGroupName = afterGroupName; - } + public Guid GroupId { get; } = groupId; + public string BeforeGroupName { get; } = beforeGroupName; + public string AfterGroupName { get; } = afterGroupName; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserAddedToGroupContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserAddedToGroupContent.cs index fd8400b9a4..4d61510b02 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserAddedToGroupContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserAddedToGroupContent.cs @@ -3,16 +3,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserAddedToGroupContent : IMessageContent +public sealed class UserAddedToGroupContent(Guid userId, Guid groupId) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public Guid GroupId { get; } - - public UserAddedToGroupContent(Guid userId, Guid groupId) - { - UserId = userId; - GroupId = groupId; - } + public Guid UserId { get; } = userId; + public Guid GroupId { get; } = groupId; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserCreatedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserCreatedContent.cs index 8c9f2c08f7..774f9d3a70 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserCreatedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserCreatedContent.cs @@ -3,18 +3,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserCreatedContent : IMessageContent +public sealed class UserCreatedContent(Guid userId, string userLoginName, string? userDisplayName) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public string UserLoginName { get; } - public string? UserDisplayName { get; } - - public UserCreatedContent(Guid userId, string userLoginName, string? userDisplayName) - { - UserId = userId; - UserLoginName = userLoginName; - UserDisplayName = userDisplayName; - } + public Guid UserId { get; } = userId; + public string UserLoginName { get; } = userLoginName; + public string? UserDisplayName { get; } = userDisplayName; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDeletedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDeletedContent.cs index f0a5a30102..877609eb5b 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDeletedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDeletedContent.cs @@ -3,14 +3,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserDeletedContent : IMessageContent +public sealed class UserDeletedContent(Guid userId) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - - public UserDeletedContent(Guid userId) - { - UserId = userId; - } + public Guid UserId { get; } = userId; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDisplayNameChangedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDisplayNameChangedContent.cs index aff93ee7db..05d84a8fa0 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDisplayNameChangedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserDisplayNameChangedContent.cs @@ -3,18 +3,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserDisplayNameChangedContent : IMessageContent +public sealed class UserDisplayNameChangedContent(Guid userId, string? beforeUserDisplayName, string? afterUserDisplayName) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public string? BeforeUserDisplayName { get; } - public string? AfterUserDisplayName { get; } - - public UserDisplayNameChangedContent(Guid userId, string? beforeUserDisplayName, string? afterUserDisplayName) - { - UserId = userId; - BeforeUserDisplayName = beforeUserDisplayName; - AfterUserDisplayName = afterUserDisplayName; - } + public Guid UserId { get; } = userId; + public string? BeforeUserDisplayName { get; } = beforeUserDisplayName; + public string? AfterUserDisplayName { get; } = afterUserDisplayName; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserLoginNameChangedContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserLoginNameChangedContent.cs index d835220aa0..bb46640e67 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserLoginNameChangedContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserLoginNameChangedContent.cs @@ -3,18 +3,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserLoginNameChangedContent : IMessageContent +public sealed class UserLoginNameChangedContent(Guid userId, string beforeUserLoginName, string afterUserLoginName) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public string BeforeUserLoginName { get; } - public string AfterUserLoginName { get; } - - public UserLoginNameChangedContent(Guid userId, string beforeUserLoginName, string afterUserLoginName) - { - UserId = userId; - BeforeUserLoginName = beforeUserLoginName; - AfterUserLoginName = afterUserLoginName; - } + public Guid UserId { get; } = userId; + public string BeforeUserLoginName { get; } = beforeUserLoginName; + public string AfterUserLoginName { get; } = afterUserLoginName; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserMovedToGroupContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserMovedToGroupContent.cs index 766422e595..aad81f0123 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserMovedToGroupContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserMovedToGroupContent.cs @@ -3,18 +3,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserMovedToGroupContent : IMessageContent +public sealed class UserMovedToGroupContent(Guid userId, Guid beforeGroupId, Guid afterGroupId) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public Guid BeforeGroupId { get; } - public Guid AfterGroupId { get; } - - public UserMovedToGroupContent(Guid userId, Guid beforeGroupId, Guid afterGroupId) - { - UserId = userId; - BeforeGroupId = beforeGroupId; - AfterGroupId = afterGroupId; - } + public Guid UserId { get; } = userId; + public Guid BeforeGroupId { get; } = beforeGroupId; + public Guid AfterGroupId { get; } = afterGroupId; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserRemovedFromGroupContent.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserRemovedFromGroupContent.cs index 8623d101b9..1969b7c4d7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserRemovedFromGroupContent.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/Messages/UserRemovedFromGroupContent.cs @@ -3,16 +3,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.Messages; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UserRemovedFromGroupContent : IMessageContent +public sealed class UserRemovedFromGroupContent(Guid userId, Guid groupId) : IMessageContent { public int FormatVersion => 1; - public Guid UserId { get; } - public Guid GroupId { get; } - - public UserRemovedFromGroupContent(Guid userId, Guid groupId) - { - UserId = userId; - GroupId = groupId; - } + public Guid UserId { get; } = userId; + public Guid GroupId { get; } = groupId; } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs index b30c8ef88f..e6c1d53314 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingGroupDefinition.cs @@ -7,24 +7,18 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices; -public abstract class MessagingGroupDefinition : HitCountingResourceDefinition +public abstract class MessagingGroupDefinition( + IResourceGraph resourceGraph, DbSet userSet, DbSet groupSet, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly DbSet _userSet; - private readonly DbSet _groupSet; + private readonly DbSet _userSet = userSet; + private readonly DbSet _groupSet = groupSet; private readonly List _pendingMessages = []; private string? _beforeGroupName; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Writing; - protected MessagingGroupDefinition(IResourceGraph resourceGraph, DbSet userSet, DbSet groupSet, - ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - _userSet = userSet; - _groupSet = groupSet; - } - public override async Task OnPrepareWriteAsync(DomainGroup group, WriteOperationKind writeOperation, CancellationToken cancellationToken) { await base.OnPrepareWriteAsync(group, writeOperation, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs index 74b5190cd1..72c38677dd 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/MessagingUserDefinition.cs @@ -7,9 +7,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices; -public abstract class MessagingUserDefinition : HitCountingResourceDefinition +public abstract class MessagingUserDefinition(IResourceGraph resourceGraph, DbSet userSet, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly DbSet _userSet; + private readonly DbSet _userSet = userSet; private readonly List _pendingMessages = []; private string? _beforeLoginName; @@ -17,12 +18,6 @@ public abstract class MessagingUserDefinition : HitCountingResourceDefinition ResourceDefinitionExtensibilityPoints.Writing; - protected MessagingUserDefinition(IResourceGraph resourceGraph, DbSet userSet, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - _userSet = userSet; - } - public override async Task OnPrepareWriteAsync(DomainUser user, WriteOperationKind writeOperation, CancellationToken cancellationToken) { await base.OnPrepareWriteAsync(user, writeOperation, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxDbContext.cs index c02b8fcc34..a09b8ba389 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxDbContext.cs @@ -6,14 +6,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.TransactionalOutboxPattern; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class OutboxDbContext : TestableDbContext +public sealed class OutboxDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Users => Set(); public DbSet Groups => Set(); public DbSet OutboxMessages => Set(); - - public OutboxDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxGroupDefinition.cs index 8aaef59e35..9e950fa653 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxGroupDefinition.cs @@ -7,15 +7,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.TransactionalOutboxPattern; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class OutboxGroupDefinition : MessagingGroupDefinition +public sealed class OutboxGroupDefinition(IResourceGraph resourceGraph, OutboxDbContext dbContext, ResourceDefinitionHitCounter hitCounter) + : MessagingGroupDefinition(resourceGraph, dbContext.Users, dbContext.Groups, hitCounter) { - private readonly DbSet _outboxMessageSet; - - public OutboxGroupDefinition(IResourceGraph resourceGraph, OutboxDbContext dbContext, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, dbContext.Users, dbContext.Groups, hitCounter) - { - _outboxMessageSet = dbContext.OutboxMessages; - } + private readonly DbSet _outboxMessageSet = dbContext.OutboxMessages; public override async Task OnWritingAsync(DomainGroup group, WriteOperationKind writeOperation, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxUserDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxUserDefinition.cs index 8076c944ec..cbf08b9aef 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxUserDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Microservices/TransactionalOutboxPattern/OutboxUserDefinition.cs @@ -7,15 +7,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Microservices.TransactionalOutboxPattern; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class OutboxUserDefinition : MessagingUserDefinition +public sealed class OutboxUserDefinition(IResourceGraph resourceGraph, OutboxDbContext dbContext, ResourceDefinitionHitCounter hitCounter) + : MessagingUserDefinition(resourceGraph, dbContext.Users, hitCounter) { - private readonly DbSet _outboxMessageSet; - - public OutboxUserDefinition(IResourceGraph resourceGraph, OutboxDbContext dbContext, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, dbContext.Users, hitCounter) - { - _outboxMessageSet = dbContext.OutboxMessages; - } + private readonly DbSet _outboxMessageSet = dbContext.OutboxMessages; public override async Task OnWritingAsync(DomainUser user, WriteOperationKind writeOperation, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs index 69a6459303..2ace5fb3fd 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenancyDbContext.cs @@ -7,19 +7,13 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.MultiTenancy; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class MultiTenancyDbContext : TestableDbContext +public sealed class MultiTenancyDbContext(DbContextOptions options, ITenantProvider tenantProvider) : TestableDbContext(options) { - private readonly ITenantProvider _tenantProvider; + private readonly ITenantProvider _tenantProvider = tenantProvider; public DbSet WebShops => Set(); public DbSet WebProducts => Set(); - public MultiTenancyDbContext(DbContextOptions options, ITenantProvider tenantProvider) - : base(options) - { - _tenantProvider = tenantProvider; - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenantResourceService.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenantResourceService.cs index b46a8133d0..9918cbaff3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenantResourceService.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/MultiTenantResourceService.cs @@ -10,21 +10,18 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.MultiTenancy; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class MultiTenantResourceService : JsonApiResourceService +public class MultiTenantResourceService( + ITenantProvider tenantProvider, IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, + IPaginationContext paginationContext, IJsonApiOptions options, ILoggerFactory loggerFactory, IJsonApiRequest request, + IResourceChangeTracker resourceChangeTracker, IResourceDefinitionAccessor resourceDefinitionAccessor) + : JsonApiResourceService(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, + resourceDefinitionAccessor) where TResource : class, IIdentifiable { - private readonly ITenantProvider _tenantProvider; + private readonly ITenantProvider _tenantProvider = tenantProvider; private static bool ResourceHasTenant => typeof(IHasTenant).IsAssignableFrom(typeof(TResource)); - public MultiTenantResourceService(ITenantProvider tenantProvider, IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, - IPaginationContext paginationContext, IJsonApiOptions options, ILoggerFactory loggerFactory, IJsonApiRequest request, - IResourceChangeTracker resourceChangeTracker, IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor) - { - _tenantProvider = tenantProvider; - } - protected override async Task InitializeResourceAsync(TResource resourceForDatabase, CancellationToken cancellationToken) { await base.InitializeResourceAsync(resourceForDatabase, cancellationToken); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/RouteTenantProvider.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/RouteTenantProvider.cs index f51c214f0e..253b48b58a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/RouteTenantProvider.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/MultiTenancy/RouteTenantProvider.cs @@ -2,7 +2,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.MultiTenancy; -internal sealed class RouteTenantProvider : ITenantProvider +internal sealed class RouteTenantProvider(IHttpContextAccessor httpContextAccessor) : ITenantProvider { // In reality, this would be looked up in a database. We'll keep it hardcoded for simplicity. public static readonly IDictionary TenantRegistry = new Dictionary @@ -11,7 +11,7 @@ internal sealed class RouteTenantProvider : ITenantProvider ["ita"] = Guid.NewGuid() }; - private readonly IHttpContextAccessor _httpContextAccessor; + private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor; public Guid TenantId { @@ -26,9 +26,4 @@ public Guid TenantId return countryCode != null && TenantRegistry.TryGetValue(countryCode, out Guid tenantId) ? tenantId : Guid.Empty; } } - - public RouteTenantProvider(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/DivingBoardsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/DivingBoardsController.cs index 55a3cd97da..3c02f9d8e2 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/DivingBoardsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/DivingBoardsController.cs @@ -5,11 +5,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NamingConventions; -public sealed class DivingBoardsController : JsonApiController -{ - public DivingBoardsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} +public sealed class DivingBoardsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : JsonApiController(options, resourceGraph, loggerFactory, resourceService); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/NamingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/NamingDbContext.cs index 059abf5d51..a13c4a44ae 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/NamingDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/NamingDbContext.cs @@ -5,14 +5,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NamingConventions; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class NamingDbContext : TestableDbContext +public sealed class NamingDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet SwimmingPools => Set(); public DbSet WaterSlides => Set(); public DbSet DivingBoards => Set(); - - public NamingDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/SwimmingPoolsController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/SwimmingPoolsController.cs index b87206097b..95c368fb0e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/SwimmingPoolsController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NamingConventions/SwimmingPoolsController.cs @@ -5,11 +5,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NamingConventions; -public sealed class SwimmingPoolsController : JsonApiController -{ - public SwimmingPoolsController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} +public sealed class SwimmingPoolsController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : JsonApiController(options, resourceGraph, loggerFactory, resourceService); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateKnownResourcesController.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateKnownResourcesController.cs index b127a8cc81..34a9d1d674 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateKnownResourcesController.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/DuplicateKnownResourcesController.cs @@ -5,11 +5,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers; -public sealed class DuplicateKnownResourcesController : JsonApiController -{ - public DuplicateKnownResourcesController(IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, - IResourceService resourceService) - : base(options, resourceGraph, loggerFactory, resourceService) - { - } -} +public sealed class DuplicateKnownResourcesController( + IJsonApiOptions options, IResourceGraph resourceGraph, ILoggerFactory loggerFactory, IResourceService resourceService) + : JsonApiController(options, resourceGraph, loggerFactory, resourceService); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/EmptyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/EmptyDbContext.cs index 0ac00ea2ae..33fa56a0bb 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/EmptyDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/EmptyDbContext.cs @@ -5,10 +5,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class EmptyDbContext : TestableDbContext -{ - public EmptyDbContext(DbContextOptions options) - : base(options) - { - } -} +public sealed class EmptyDbContext(DbContextOptions options) : TestableDbContext(options); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/KnownDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/KnownDbContext.cs index b18d71938c..23aae10cd3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/KnownDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/NonJsonApiControllers/KnownDbContext.cs @@ -5,12 +5,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.NonJsonApiControllers; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class KnownDbContext : TestableDbContext +public sealed class KnownDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet KnownResources => Set(); - - public KnownDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParseTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParseTests.cs index aca362aed3..ff0f8f6e09 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParseTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParseTests.cs @@ -66,7 +66,7 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "has(posts,isUpperCase(author.userName))", null)] [InlineData("filter", "or(isUpperCase(title),isUpperCase(platformName))", null)] [InlineData("filter[posts]", "isUpperCase(author.userName)", "posts")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParser.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParser.cs index 5debe54835..27b32d7189 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParser.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/IsUpperCase/IsUpperCaseFilterParser.cs @@ -6,13 +6,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.IsUpperCase; -internal sealed class IsUpperCaseFilterParser : FilterParser +internal sealed class IsUpperCaseFilterParser(IResourceFactory resourceFactory) : FilterParser(resourceFactory) { - public IsUpperCaseFilterParser(IResourceFactory resourceFactory) - : base(resourceFactory) - { - } - protected override FilterExpression ParseFilter() { if (TokenStack.TryPeek(out Token? nextToken) && nextToken is { Kind: TokenKind.Text, Value: IsUpperCaseExpression.Keyword }) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParseTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParseTests.cs index 78352a6ab7..e9f07521ac 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParseTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParseTests.cs @@ -66,7 +66,7 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "has(posts,lessThan(length(author.userName),'1'))", null)] [InlineData("filter", "or(equals(length(title),'1'),equals(length(platformName),'1'))", null)] [InlineData("filter[posts]", "equals(length(author.userName),'1')", "posts")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParser.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParser.cs index 028d40c0ed..f429224290 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParser.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthFilterParser.cs @@ -6,13 +6,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.StringLength; -internal sealed class LengthFilterParser : FilterParser +internal sealed class LengthFilterParser(IResourceFactory resourceFactory) : FilterParser(resourceFactory) { - public LengthFilterParser(IResourceFactory resourceFactory) - : base(resourceFactory) - { - } - protected override bool IsFunction(string name) { if (name == LengthExpression.Keyword) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthSortParseTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthSortParseTests.cs index c28bec8c8a..e7e16196e4 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthSortParseTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/StringLength/LengthSortParseTests.cs @@ -62,7 +62,7 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("sort", "length(title),-length(platformName)", null)] [InlineData("sort", "length(owner.userName)", null)] [InlineData("sort[posts]", "length(author.userName)", "posts")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParseTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParseTests.cs index c2cc62e279..cc4c3fc7e9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParseTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParseTests.cs @@ -71,7 +71,7 @@ public void Reader_Read_Fails(string parameterName, string parameterValue, strin [InlineData("filter", "has(posts,greaterThan(sum(comments,numStars),'5'))", null)] [InlineData("filter[posts]", "equals(sum(comments,numStars),'11')", "posts")] [InlineData("filter[posts]", "equals(sum(labels,count(posts)),'8')", "posts")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs index 76087dc31f..1db57b4fc0 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/Sum/SumFilterParser.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.Sum; -internal sealed class SumFilterParser : FilterParser +internal sealed class SumFilterParser(IResourceFactory resourceFactory) : FilterParser(resourceFactory) { private static readonly FieldChainPattern SingleToManyRelationshipChain = FieldChainPattern.Parse("M"); @@ -25,11 +25,6 @@ internal sealed class SumFilterParser : FilterParser typeof(decimal) ]; - public SumFilterParser(IResourceFactory resourceFactory) - : base(resourceFactory) - { - } - protected override bool IsFunction(string name) { if (name == SumExpression.Keyword) diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs index c3e5941a19..1a704d3883 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterRewritingResourceDefinition.cs @@ -7,16 +7,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.TimeOffset; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class FilterRewritingResourceDefinition : JsonApiResourceDefinition +public class FilterRewritingResourceDefinition(IResourceGraph resourceGraph, ISystemClock systemClock) + : JsonApiResourceDefinition(resourceGraph) where TResource : class, IIdentifiable { - private readonly FilterTimeOffsetRewriter _rewriter; - - public FilterRewritingResourceDefinition(IResourceGraph resourceGraph, ISystemClock systemClock) - : base(resourceGraph) - { - _rewriter = new FilterTimeOffsetRewriter(systemClock); - } + private readonly FilterTimeOffsetRewriter _rewriter = new(systemClock); public override FilterExpression? OnApplyFilter(FilterExpression? existingFilter) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs index 2d2ee4da89..9f9c97c73a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/CustomFunctions/TimeOffset/FilterTimeOffsetRewriter.cs @@ -3,7 +3,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.CustomFunctions.TimeOffset; -internal sealed class FilterTimeOffsetRewriter : QueryExpressionRewriter +internal sealed class FilterTimeOffsetRewriter(ISystemClock systemClock) : QueryExpressionRewriter { private static readonly Dictionary InverseComparisonOperatorTable = new() { @@ -14,12 +14,7 @@ internal sealed class FilterTimeOffsetRewriter : QueryExpressionRewriter options) : TestableDbContext(options) { public DbSet FilterableResources => Set(); - public FilterDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs index 3aa40b2725..28a8935d26 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/QueryStringDbContext.cs @@ -7,7 +7,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class QueryStringDbContext : TestableDbContext +public sealed class QueryStringDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Blogs => Set(); public DbSet Posts => Set(); @@ -23,11 +23,6 @@ public sealed class QueryStringDbContext : TestableDbContext public DbSet Appointments => Set(); public DbSet Reminders => Set(); - public QueryStringDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs index d900e5809d..97eed95472 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/QueryStrings/SparseFieldSets/ResultCapturingRepository.cs @@ -11,18 +11,14 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.QueryStrings.SparseFieldSets; /// Enables sparse fieldset tests to verify which fields were (not) retrieved from the database. /// [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class ResultCapturingRepository : EntityFrameworkCoreRepository +public sealed class ResultCapturingRepository( + ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, IResourceFactory resourceFactory, + IEnumerable constraintProviders, ILoggerFactory loggerFactory, IResourceDefinitionAccessor resourceDefinitionAccessor, + ResourceCaptureStore captureStore) : EntityFrameworkCoreRepository(targetedFields, dbContextResolver, resourceGraph, resourceFactory, + constraintProviders, loggerFactory, resourceDefinitionAccessor) where TResource : class, IIdentifiable { - private readonly ResourceCaptureStore _captureStore; - - public ResultCapturingRepository(ITargetedFields targetedFields, IDbContextResolver dbContextResolver, IResourceGraph resourceGraph, - IResourceFactory resourceFactory, IEnumerable constraintProviders, ILoggerFactory loggerFactory, - IResourceDefinitionAccessor resourceDefinitionAccessor, ResourceCaptureStore captureStore) - : base(targetedFields, dbContextResolver, resourceGraph, resourceFactory, constraintProviders, loggerFactory, resourceDefinitionAccessor) - { - _captureStore = captureStore; - } + private readonly ResourceCaptureStore _captureStore = captureStore; public override async Task> GetAsync(QueryLayer queryLayer, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemDefinition.cs index fdf1e2e512..996e917693 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemDefinition.cs @@ -10,17 +10,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ReadWrite; /// Used to simulate side effects that occur in the database while saving, typically caused by database triggers. /// [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class ImplicitlyChangingWorkItemDefinition : JsonApiResourceDefinition +public sealed class ImplicitlyChangingWorkItemDefinition(IResourceGraph resourceGraph, ReadWriteDbContext dbContext) + : JsonApiResourceDefinition(resourceGraph) { internal const string Suffix = " (changed)"; - private readonly ReadWriteDbContext _dbContext; - - public ImplicitlyChangingWorkItemDefinition(IResourceGraph resourceGraph, ReadWriteDbContext dbContext) - : base(resourceGraph) - { - _dbContext = dbContext; - } + private readonly ReadWriteDbContext _dbContext = dbContext; public override async Task OnWriteSucceededAsync(WorkItem resource, WriteOperationKind writeOperation, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemGroupDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemGroupDefinition.cs index 1fbec1c9df..c0f06094aa 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemGroupDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ImplicitlyChangingWorkItemGroupDefinition.cs @@ -10,17 +10,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ReadWrite; /// Used to simulate side effects that occur in the database while saving, typically caused by database triggers. /// [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class ImplicitlyChangingWorkItemGroupDefinition : JsonApiResourceDefinition +public sealed class ImplicitlyChangingWorkItemGroupDefinition(IResourceGraph resourceGraph, ReadWriteDbContext dbContext) + : JsonApiResourceDefinition(resourceGraph) { internal const string Suffix = " (changed)"; - private readonly ReadWriteDbContext _dbContext; - - public ImplicitlyChangingWorkItemGroupDefinition(IResourceGraph resourceGraph, ReadWriteDbContext dbContext) - : base(resourceGraph) - { - _dbContext = dbContext; - } + private readonly ReadWriteDbContext _dbContext = dbContext; public override async Task OnWriteSucceededAsync(WorkItemGroup resource, WriteOperationKind writeOperation, CancellationToken cancellationToken) { diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs index 4f3d1080cf..e8350555d5 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/ReadWriteDbContext.cs @@ -8,7 +8,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ReadWrite; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ReadWriteDbContext : TestableDbContext +public sealed class ReadWriteDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet WorkItems => Set(); public DbSet WorkTags => Set(); @@ -16,11 +16,6 @@ public sealed class ReadWriteDbContext : TestableDbContext public DbSet RgbColors => Set(); public DbSet UserAccounts => Set(); - public ReadWriteDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs index 567559b5d4..4f3e8d3ab3 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ReadWrite/Updating/Relationships/RemoveFromToManyRelationshipTests.cs @@ -1096,7 +1096,7 @@ await _testContext.RunOnDatabaseAsync(async dbContext => } [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] - private sealed class RemoveExtraFromWorkItemDefinition : JsonApiResourceDefinition + private sealed class RemoveExtraFromWorkItemDefinition(IResourceGraph resourceGraph) : JsonApiResourceDefinition(resourceGraph) { // Enables to verify that not the full relationship was loaded upfront. public ISet PreloadedSubscribers { get; } = new HashSet(IdentifiableComparer.Instance); @@ -1106,11 +1106,6 @@ private sealed class RemoveExtraFromWorkItemDefinition : JsonApiResourceDefiniti public ISet ExtraSubscribersIdsToRemove { get; } = new HashSet(); public ISet ExtraTagIdsToRemove { get; } = new HashSet(); - public RemoveExtraFromWorkItemDefinition(IResourceGraph resourceGraph) - : base(resourceGraph) - { - } - public void Reset() { PreloadedSubscribers.Clear(); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs index 5b0b839c63..d0bea86f38 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/RequiredRelationships/DefaultBehaviorDbContext.cs @@ -7,17 +7,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.RequiredRelationships; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class DefaultBehaviorDbContext : TestableDbContext +public sealed class DefaultBehaviorDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Customers => Set(); public DbSet Orders => Set(); public DbSet Shipments => Set(); - public DefaultBehaviorDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs index 6da63a30cb..6a04e8a1ab 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/GiftCertificate.cs @@ -8,9 +8,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection; [UsedImplicitly(ImplicitUseTargetFlags.Members)] [Resource(ControllerNamespace = "JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection")] -public sealed class GiftCertificate : Identifiable +public sealed class GiftCertificate(InjectionDbContext injectionDbContext) : Identifiable { - private readonly ISystemClock _systemClock; + private readonly ISystemClock _systemClock = injectionDbContext.SystemClock; [Attr] public DateTimeOffset IssueDate { get; set; } @@ -21,9 +21,4 @@ public sealed class GiftCertificate : Identifiable [HasOne] public PostOffice? Issuer { get; set; } - - public GiftCertificate(InjectionDbContext injectionDbContext) - { - _systemClock = injectionDbContext.SystemClock; - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs index f7bd504cd8..86658bb9d7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceConstructorInjection/PostOffice.cs @@ -8,9 +8,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection; [UsedImplicitly(ImplicitUseTargetFlags.Members)] [Resource(ControllerNamespace = "JsonApiDotNetCoreTests.IntegrationTests.ResourceConstructorInjection")] -public sealed class PostOffice : Identifiable +public sealed class PostOffice(InjectionDbContext injectionDbContext) : Identifiable { - private readonly ISystemClock _systemClock; + private readonly ISystemClock _systemClock = injectionDbContext.SystemClock; [Attr] public string Address { get; set; } = null!; @@ -22,11 +22,6 @@ public sealed class PostOffice : Identifiable [HasMany] public IList GiftCertificates { get; set; } = new List(); - public PostOffice(InjectionDbContext injectionDbContext) - { - _systemClock = injectionDbContext.SystemClock; - } - private bool IsWithinOperatingHours() { DateTimeOffset currentTime = _systemClock.UtcNow; diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs index 2b904434ad..ada3bce0f7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/MoonDefinition.cs @@ -9,21 +9,14 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Reading; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class MoonDefinition : HitCountingResourceDefinition +// The constructor parameters will be resolved from the container, which means you can take on any dependency that is also defined in the container. +public sealed class MoonDefinition(IResourceGraph resourceGraph, IClientSettingsProvider clientSettingsProvider, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly IClientSettingsProvider _clientSettingsProvider; + private readonly IClientSettingsProvider _clientSettingsProvider = clientSettingsProvider; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Reading; - public MoonDefinition(IResourceGraph resourceGraph, IClientSettingsProvider clientSettingsProvider, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - // This constructor will be resolved from the container, which means - // you can take on any dependency that is also defined in the container. - - _clientSettingsProvider = clientSettingsProvider; - } - public override IImmutableSet OnApplyIncludes(IImmutableSet existingIncludes) { base.OnApplyIncludes(existingIncludes); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/PlanetDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/PlanetDefinition.cs index 70f77ecb24..d4a0c23af8 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/PlanetDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/PlanetDefinition.cs @@ -10,21 +10,14 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Reading; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class PlanetDefinition : HitCountingResourceDefinition +// The constructor parameters will be resolved from the container, which means you can take on any dependency that is also defined in the container. +public sealed class PlanetDefinition(IResourceGraph resourceGraph, IClientSettingsProvider clientSettingsProvider, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly IClientSettingsProvider _clientSettingsProvider; + private readonly IClientSettingsProvider _clientSettingsProvider = clientSettingsProvider; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Reading; - public PlanetDefinition(IResourceGraph resourceGraph, IClientSettingsProvider clientSettingsProvider, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - // This constructor will be resolved from the container, which means - // you can take on any dependency that is also defined in the container. - - _clientSettingsProvider = clientSettingsProvider; - } - public override IImmutableSet OnApplyIncludes(IImmutableSet existingIncludes) { base.OnApplyIncludes(existingIncludes); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs index 6146e04367..944cb4ca0e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/StarDefinition.cs @@ -6,17 +6,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Reading; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class StarDefinition : HitCountingResourceDefinition +// The constructor parameters will be resolved from the container, which means you can take on any dependency that is also defined in the container. +public sealed class StarDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Reading; - public StarDefinition(IResourceGraph resourceGraph, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - // This constructor will be resolved from the container, which means - // you can take on any dependency that is also defined in the container. - } - public override SortExpression OnApplySort(SortExpression? existingSort) { base.OnApplySort(existingSort); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/UniverseDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/UniverseDbContext.cs index 3dc619dcba..6bfd710d0d 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/UniverseDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Reading/UniverseDbContext.cs @@ -5,14 +5,9 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Reading; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class UniverseDbContext : TestableDbContext +public sealed class UniverseDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Stars => Set(); public DbSet Planets => Set(); public DbSet Moons => Set(); - - public UniverseDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs index 4bfb7aa709..1772f6118c 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/SerializationDbContext.cs @@ -7,16 +7,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Serialization; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class SerializationDbContext : TestableDbContext +public sealed class SerializationDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Students => Set(); public DbSet Scholarships => Set(); - public SerializationDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/StudentDefinition.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/StudentDefinition.cs index 8c857b5bc9..26e6eee785 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/StudentDefinition.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceDefinitions/Serialization/StudentDefinition.cs @@ -4,21 +4,14 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceDefinitions.Serialization; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class StudentDefinition : HitCountingResourceDefinition +// The constructor parameters will be resolved from the container, which means you can take on any dependency that is also defined in the container. +public sealed class StudentDefinition(IResourceGraph resourceGraph, IEncryptionService encryptionService, ResourceDefinitionHitCounter hitCounter) + : HitCountingResourceDefinition(resourceGraph, hitCounter) { - private readonly IEncryptionService _encryptionService; + private readonly IEncryptionService _encryptionService = encryptionService; protected override ResourceDefinitionExtensibilityPoints ExtensibilityPointsToTrack => ResourceDefinitionExtensibilityPoints.Serialization; - public StudentDefinition(IResourceGraph resourceGraph, IEncryptionService encryptionService, ResourceDefinitionHitCounter hitCounter) - : base(resourceGraph, hitCounter) - { - // This constructor will be resolved from the container, which means - // you can take on any dependency that is also defined in the container. - - _encryptionService = encryptionService; - } - public override void OnDeserialize(Student resource) { base.OnDeserialize(resource); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ChangeTracking/ChangeTrackingDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ChangeTracking/ChangeTrackingDbContext.cs index a335f493c4..e9002e7be9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ChangeTracking/ChangeTrackingDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ChangeTracking/ChangeTrackingDbContext.cs @@ -5,12 +5,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.ChangeTracking; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ChangeTrackingDbContext : ResourceInheritanceDbContext +public sealed class ChangeTrackingDbContext(DbContextOptions options) : ResourceInheritanceDbContext(options) { public DbSet AlwaysMovingTandems => Set(); - - public ChangeTrackingDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceDbContext.cs index f5e0fc1bbe..acac25ee8a 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/ResourceInheritanceDbContext.cs @@ -6,7 +6,7 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public abstract class ResourceInheritanceDbContext : TestableDbContext +public abstract class ResourceInheritanceDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Vehicles => Set(); public DbSet Bikes => Set(); @@ -32,9 +32,4 @@ public abstract class ResourceInheritanceDbContext : TestableDbContext public DbSet BicycleLights => Set(); public DbSet NavigationSystems => Set(); public DbSet GenericFeatures => Set(); - - protected ResourceInheritanceDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeDbContext.cs index 2b5977c8b4..1e7e644367 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeDbContext.cs @@ -7,13 +7,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerConcreteType; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class TablePerConcreteTypeDbContext : ResourceInheritanceDbContext +public sealed class TablePerConcreteTypeDbContext(DbContextOptions options) : ResourceInheritanceDbContext(options) { - public TablePerConcreteTypeDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeReadTests.cs index bcffe2ed5e..217918c468 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeReadTests.cs @@ -4,10 +4,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerConcreteType; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerConcreteTypeReadTests : ResourceInheritanceReadTests -{ - public TablePerConcreteTypeReadTests(IntegrationTestContext, TablePerConcreteTypeDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerConcreteTypeReadTests( + IntegrationTestContext, TablePerConcreteTypeDbContext> testContext) + : ResourceInheritanceReadTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeWriteTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeWriteTests.cs index 9f2e3c3cae..8827feaa61 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeWriteTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerConcreteType/TablePerConcreteTypeWriteTests.cs @@ -4,10 +4,6 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerConcreteType; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerConcreteTypeWriteTests : ResourceInheritanceWriteTests -{ - public TablePerConcreteTypeWriteTests(IntegrationTestContext, TablePerConcreteTypeDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerConcreteTypeWriteTests( + IntegrationTestContext, TablePerConcreteTypeDbContext> testContext) + : ResourceInheritanceWriteTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyDbContext.cs index 582b995d89..f9d63e7dde 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyDbContext.cs @@ -4,10 +4,4 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerHierarchy; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class TablePerHierarchyDbContext : ResourceInheritanceDbContext -{ - public TablePerHierarchyDbContext(DbContextOptions options) - : base(options) - { - } -} +public sealed class TablePerHierarchyDbContext(DbContextOptions options) : ResourceInheritanceDbContext(options); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyReadTests.cs index e9d3df4ac0..7a5b4113e7 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyReadTests.cs @@ -4,10 +4,5 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerHierarchy; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerHierarchyReadTests : ResourceInheritanceReadTests -{ - public TablePerHierarchyReadTests(IntegrationTestContext, TablePerHierarchyDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerHierarchyReadTests(IntegrationTestContext, TablePerHierarchyDbContext> testContext) + : ResourceInheritanceReadTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyWriteTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyWriteTests.cs index edd81659e8..fb26f609aa 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyWriteTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerHierarchy/TablePerHierarchyWriteTests.cs @@ -4,10 +4,5 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerHierarchy; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerHierarchyWriteTests : ResourceInheritanceWriteTests -{ - public TablePerHierarchyWriteTests(IntegrationTestContext, TablePerHierarchyDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerHierarchyWriteTests(IntegrationTestContext, TablePerHierarchyDbContext> testContext) + : ResourceInheritanceWriteTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs index 86a723bfd3..382a54cc3e 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeDbContext.cs @@ -7,13 +7,8 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerType; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class TablePerTypeDbContext : ResourceInheritanceDbContext +public sealed class TablePerTypeDbContext(DbContextOptions options) : ResourceInheritanceDbContext(options) { - public TablePerTypeDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeReadTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeReadTests.cs index 7782f4f315..c3c64bb1a6 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeReadTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeReadTests.cs @@ -4,10 +4,5 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerType; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerTypeReadTests : ResourceInheritanceReadTests -{ - public TablePerTypeReadTests(IntegrationTestContext, TablePerTypeDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerTypeReadTests(IntegrationTestContext, TablePerTypeDbContext> testContext) + : ResourceInheritanceReadTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeWriteTests.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeWriteTests.cs index ed98334583..d6516586fb 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeWriteTests.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ResourceInheritance/TablePerType/TablePerTypeWriteTests.cs @@ -4,10 +4,5 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ResourceInheritance.TablePerType; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public sealed class TablePerTypeWriteTests : ResourceInheritanceWriteTests -{ - public TablePerTypeWriteTests(IntegrationTestContext, TablePerTypeDbContext> testContext) - : base(testContext) - { - } -} +public sealed class TablePerTypeWriteTests(IntegrationTestContext, TablePerTypeDbContext> testContext) + : ResourceInheritanceWriteTests(testContext); diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs index 433d50ecd3..8a5f5484de 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/RestrictedControllers/RestrictionDbContext.cs @@ -5,15 +5,10 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.RestrictedControllers; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class RestrictionDbContext : TestableDbContext +public sealed class RestrictionDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Tables => Set
(); public DbSet Chairs => Set(); public DbSet Sofas => Set(); public DbSet Beds => Set(); - - public RestrictionDbContext(DbContextOptions options) - : base(options) - { - } } diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationDbContext.cs index 32e093214c..c90e22f736 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/Serialization/SerializationDbContext.cs @@ -7,16 +7,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.Serialization; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class SerializationDbContext : TestableDbContext +public sealed class SerializationDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Meetings => Set(); public DbSet Attendees => Set(); - public SerializationDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs index 6a865eaf85..c7449397a9 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionAwareResourceService.cs @@ -11,24 +11,18 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.SoftDeletion; [UsedImplicitly(ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature)] -public class SoftDeletionAwareResourceService : JsonApiResourceService +public class SoftDeletionAwareResourceService( + ISystemClock systemClock, ITargetedFields targetedFields, IResourceRepositoryAccessor repositoryAccessor, IQueryLayerComposer queryLayerComposer, + IPaginationContext paginationContext, IJsonApiOptions options, ILoggerFactory loggerFactory, IJsonApiRequest request, + IResourceChangeTracker resourceChangeTracker, IResourceDefinitionAccessor resourceDefinitionAccessor) + : JsonApiResourceService(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, + resourceDefinitionAccessor) where TResource : class, IIdentifiable { - private readonly ISystemClock _systemClock; - private readonly ITargetedFields _targetedFields; - private readonly IResourceRepositoryAccessor _repositoryAccessor; - private readonly IJsonApiRequest _request; - - public SoftDeletionAwareResourceService(ISystemClock systemClock, ITargetedFields targetedFields, IResourceRepositoryAccessor repositoryAccessor, - IQueryLayerComposer queryLayerComposer, IPaginationContext paginationContext, IJsonApiOptions options, ILoggerFactory loggerFactory, - IJsonApiRequest request, IResourceChangeTracker resourceChangeTracker, IResourceDefinitionAccessor resourceDefinitionAccessor) - : base(repositoryAccessor, queryLayerComposer, paginationContext, options, loggerFactory, request, resourceChangeTracker, resourceDefinitionAccessor) - { - _systemClock = systemClock; - _targetedFields = targetedFields; - _repositoryAccessor = repositoryAccessor; - _request = request; - } + private readonly ISystemClock _systemClock = systemClock; + private readonly ITargetedFields _targetedFields = targetedFields; + private readonly IResourceRepositoryAccessor _repositoryAccessor = repositoryAccessor; + private readonly IJsonApiRequest _request = request; // To optimize performance, the default resource service does not always fetch all resources on write operations. // We do that here, to assure a 404 error is thrown for soft-deleted resources. diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs index 3e98950be0..98da66fc3d 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/SoftDeletion/SoftDeletionDbContext.cs @@ -7,16 +7,11 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.SoftDeletion; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class SoftDeletionDbContext : TestableDbContext +public sealed class SoftDeletionDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Companies => Set(); public DbSet Departments => Set(); - public SoftDeletionDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs index 3e93768683..8502500c20 100644 --- a/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs +++ b/test/JsonApiDotNetCoreTests/IntegrationTests/ZeroKeys/ZeroKeyDbContext.cs @@ -7,17 +7,12 @@ namespace JsonApiDotNetCoreTests.IntegrationTests.ZeroKeys; [UsedImplicitly(ImplicitUseTargetFlags.Members)] -public sealed class ZeroKeyDbContext : TestableDbContext +public sealed class ZeroKeyDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet Games => Set(); public DbSet Players => Set(); public DbSet Maps => Set(); - public ZeroKeyDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs index 9e96bc718a..1249cd5dfa 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/DependencyContainerRegistrationTests.cs @@ -15,9 +15,6 @@ using TestBuildingBlocks; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace JsonApiDotNetCoreTests.UnitTests.Configuration; public sealed class DependencyContainerRegistrationTests @@ -179,14 +176,10 @@ public CircularServiceB(CircularServiceA serviceA) } [UsedImplicitly(ImplicitUseTargetFlags.Members)] - private sealed class DependencyContainerRegistrationDbContext : TestableDbContext + private sealed class DependencyContainerRegistrationDbContext(DbContextOptions options) + : TestableDbContext(options) { public DbSet Resources => Set(); - - public DependencyContainerRegistrationDbContext(DbContextOptions options) - : base(options) - { - } } [UsedImplicitly(ImplicitUseTargetFlags.Members)] diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs index 0f7e8b0b09..66bb8b6f04 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Configuration/ServiceCollectionExtensionsTests.cs @@ -567,16 +567,11 @@ public void OnSerialize(ResourceOfGuid resource) } [UsedImplicitly(ImplicitUseTargetFlags.Members)] - private sealed class TestDbContext : TestableDbContext + private sealed class TestDbContext(DbContextOptions options) : TestableDbContext(options) { public DbSet ResourcesOfInt32 => Set(); public DbSet ResourcesOfGuid => Set(); public DbSet SetOfPersons => Set(); - - public TestDbContext(DbContextOptions options) - : base(options) - { - } } [UsedImplicitly(ImplicitUseKindFlags.Access)] diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs index f308b40d2d..067f8167d8 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternInheritanceMatchTests.cs @@ -10,9 +10,6 @@ using Xunit; using Xunit.Abstractions; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - // ReSharper disable InconsistentNaming #pragma warning disable AV1706 // Identifier contains an abbreviation or is too short diff --git a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs index dec0e7c33d..613dd4fd41 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/FieldChains/FieldChainPatternMatchTests.cs @@ -10,9 +10,6 @@ using Xunit; using Xunit.Abstractions; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - // ReSharper disable InconsistentNaming #pragma warning disable AV1706 // Identifier contains an abbreviation or is too short diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs index 4293a894df..196ac6493e 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Middleware/JsonApiMiddlewareTests.cs @@ -13,9 +13,6 @@ using TestBuildingBlocks; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - #pragma warning disable AV1561 // Signature contains too many parameters namespace JsonApiDotNetCoreTests.UnitTests.Middleware; @@ -194,16 +191,10 @@ private sealed class TodoItem : Identifiable public ISet Tags { get; set; } = new HashSet(); } - private sealed class FakeJsonApiRoutingConvention : IJsonApiRoutingConvention + private sealed class FakeJsonApiRoutingConvention(IResourceGraph resourceGraph, string? resourceTypePublicName) : IJsonApiRoutingConvention { - private readonly IResourceGraph _resourceGraph; - private readonly string? _resourceTypePublicName; - - public FakeJsonApiRoutingConvention(IResourceGraph resourceGraph, string? resourceTypePublicName) - { - _resourceGraph = resourceGraph; - _resourceTypePublicName = resourceTypePublicName; - } + private readonly IResourceGraph _resourceGraph = resourceGraph; + private readonly string? _resourceTypePublicName = resourceTypePublicName; public void Apply(ApplicationModel application) { diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs index a1daade80a..34bbc16d17 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ModelStateValidation/ModelStateValidationTests.cs @@ -10,9 +10,6 @@ using TestBuildingBlocks; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace JsonApiDotNetCoreTests.UnitTests.ModelStateValidation; public sealed class ModelStateValidationTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/FilterParseTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/FilterParseTests.cs index 1b3026e67b..9799d7d6ae 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/FilterParseTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/FilterParseTests.cs @@ -202,7 +202,7 @@ public void Reader_Read_ParameterValue_Fails(string parameterName, string parame [InlineData("filter", "isType(owner.person,men,equals(hasBeard,'true'))", null)] [InlineData("filter[posts.contributors]", "isType(,women)", "posts.contributors")] [InlineData("filter[posts.contributors]", "isType(,women,equals(maidenName,'Austen'))", "posts.contributors")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); @@ -246,13 +246,8 @@ public void Throws_When_No_ResourceType_In_Scope() action.Should().ThrowExactly().WithMessage("No resource type is currently in scope. Call Parse() first."); } - private sealed class NotDisposingFilterParser : FilterParser + private sealed class NotDisposingFilterParser(IResourceFactory resourceFactory) : FilterParser(resourceFactory) { - public NotDisposingFilterParser(IResourceFactory resourceFactory) - : base(resourceFactory) - { - } - protected override FilterExpression ParseFilter() { // Forgot to dispose the return value. @@ -262,13 +257,8 @@ protected override FilterExpression ParseFilter() } } - private sealed class ResourceTypeAccessingFilterParser : FilterParser + private sealed class ResourceTypeAccessingFilterParser(IResourceFactory resourceFactory) : FilterParser(resourceFactory) { - public ResourceTypeAccessingFilterParser(IResourceFactory resourceFactory) - : base(resourceFactory) - { - } - protected override void Tokenize(string source) { // There is no resource type in scope yet. diff --git a/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/SortParseTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/SortParseTests.cs index a2a013d535..77c52b3828 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/SortParseTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/QueryStringParameters/SortParseTests.cs @@ -152,7 +152,7 @@ public void Reader_Read_ParameterValue_Fails(string parameterName, string parame [InlineData("sort[posts.contributors]", "count(wife.husband.drinkingBuddies)", "posts.contributors")] [InlineData("sort[posts.contributors]", "wife.age", "posts.contributors")] [InlineData("sort[posts.contributors]", "count(father.friends)", "posts.contributors")] - public void Reader_Read_Succeeds(string parameterName, string parameterValue, string scopeExpected) + public void Reader_Read_Succeeds(string parameterName, string parameterValue, string? scopeExpected) { // Act _reader.Read(parameterName, parameterValue); diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs index bedb5398f8..30e8a899dc 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceDefinitions/CreateSortExpressionFromLambdaTests.cs @@ -11,9 +11,6 @@ using TestBuildingBlocks; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace JsonApiDotNetCoreTests.UnitTests.ResourceDefinitions; public sealed class CreateSortExpressionFromLambdaTests @@ -348,14 +345,9 @@ private static IResourceGraph GetResourceGraph() // @formatter:wrap_before_first_method_call restore } - private sealed class WrapperResourceDefinition : JsonApiResourceDefinition + private sealed class WrapperResourceDefinition(IResourceGraph resourceGraph) : JsonApiResourceDefinition(resourceGraph) where TResource : class, IIdentifiable { - public WrapperResourceDefinition(IResourceGraph resourceGraph) - : base(resourceGraph) - { - } - public SortExpression GetSortExpressionFromLambda(PropertySortOrder sortOrder) { return CreateSortExpressionFromLambda(sortOrder); diff --git a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs index 0f270ddfeb..ebce906b9d 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/ResourceGraph/ResourceGraphBuilderTests.cs @@ -10,9 +10,6 @@ using TestBuildingBlocks; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace JsonApiDotNetCoreTests.UnitTests.ResourceGraph; public sealed class ResourceGraphBuilderTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs index 5d6551e2ad..85329874ea 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/Serialization/Response/IncompleteResourceGraphTests.cs @@ -10,9 +10,6 @@ using Microsoft.Extensions.Logging.Abstractions; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace JsonApiDotNetCoreTests.UnitTests.Serialization.Response; public sealed class IncompleteResourceGraphTests diff --git a/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs b/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs index 4fbe4f3d22..1263912faf 100644 --- a/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs +++ b/test/JsonApiDotNetCoreTests/UnitTests/TypeConversion/RuntimeTypeConverterTests.cs @@ -141,7 +141,7 @@ public void Returns_same_instance_for_interface() [InlineData(typeof(IFace), null)] [InlineData(typeof(BaseType), null)] [InlineData(typeof(DerivedType), null)] - public void Returns_default_value_for_empty_string(Type type, object expectedValue) + public void Returns_default_value_for_empty_string(Type type, object? expectedValue) { // Act object? result = RuntimeTypeConverter.ConvertType(string.Empty, type); diff --git a/test/MultiDbContextTests/ResourceTests.cs b/test/MultiDbContextTests/ResourceTests.cs index ed25d0f274..3b2c259c57 100644 --- a/test/MultiDbContextTests/ResourceTests.cs +++ b/test/MultiDbContextTests/ResourceTests.cs @@ -10,9 +10,9 @@ namespace MultiDbContextTests; -public sealed class ResourceTests : IntegrationTest, IClassFixture> +public sealed class ResourceTests(NoLoggingWebApplicationFactory factory) : IntegrationTest, IClassFixture> { - private readonly NoLoggingWebApplicationFactory _factory; + private readonly NoLoggingWebApplicationFactory _factory = factory; protected override JsonSerializerOptions SerializerOptions { @@ -23,11 +23,6 @@ protected override JsonSerializerOptions SerializerOptions } } - public ResourceTests(NoLoggingWebApplicationFactory factory) - { - _factory = factory; - } - [Fact] public async Task Can_get_ResourceAs() { diff --git a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs index 27a52c0732..0a61821987 100644 --- a/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs +++ b/test/NoEntityFrameworkTests/NullSafeExpressionRewriterTests.cs @@ -6,13 +6,12 @@ using NoEntityFrameworkExample; using Xunit; -// Workaround for Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494909/Breaking-UsedImplicitly-and-PublicAPI-on-types-no-longer-respected. -// ReSharper disable PropertyCanBeMadeInitOnly.Local - namespace NoEntityFrameworkTests; public sealed class NullSafeExpressionRewriterTests { + private const nint OnePointer = 1; + [Fact] public void Can_rewrite_where_clause_with_constant_comparison() { @@ -501,11 +500,7 @@ public void Can_rewrite_order_by_clause_with_IntPtr() Parent = new TestResource { Id = generator.GetNext(), -#if NET6_0 - Pointer = (IntPtr)1 -#else - Pointer = 1 -#endif + Pointer = OnePointer } } }; diff --git a/test/NoEntityFrameworkTests/PersonTests.cs b/test/NoEntityFrameworkTests/PersonTests.cs index 965cac9a3e..01cdefa3e5 100644 --- a/test/NoEntityFrameworkTests/PersonTests.cs +++ b/test/NoEntityFrameworkTests/PersonTests.cs @@ -10,9 +10,9 @@ namespace NoEntityFrameworkTests; -public sealed class PersonTests : IntegrationTest, IClassFixture> +public sealed class PersonTests(NoLoggingWebApplicationFactory factory) : IntegrationTest, IClassFixture> { - private readonly NoLoggingWebApplicationFactory _factory; + private readonly NoLoggingWebApplicationFactory _factory = factory; protected override JsonSerializerOptions SerializerOptions { @@ -23,11 +23,6 @@ protected override JsonSerializerOptions SerializerOptions } } - public PersonTests(NoLoggingWebApplicationFactory factory) - { - _factory = factory; - } - [Fact] public async Task Can_get_primary_resources() { diff --git a/test/NoEntityFrameworkTests/TagTests.cs b/test/NoEntityFrameworkTests/TagTests.cs index 83842b7725..49b5887adb 100644 --- a/test/NoEntityFrameworkTests/TagTests.cs +++ b/test/NoEntityFrameworkTests/TagTests.cs @@ -10,9 +10,9 @@ namespace NoEntityFrameworkTests; -public sealed class TagTests : IntegrationTest, IClassFixture> +public sealed class TagTests(NoLoggingWebApplicationFactory factory) : IntegrationTest, IClassFixture> { - private readonly NoLoggingWebApplicationFactory _factory; + private readonly NoLoggingWebApplicationFactory _factory = factory; protected override JsonSerializerOptions SerializerOptions { @@ -23,11 +23,6 @@ protected override JsonSerializerOptions SerializerOptions } } - public TagTests(NoLoggingWebApplicationFactory factory) - { - _factory = factory; - } - [Fact] public async Task Can_get_primary_resources() { diff --git a/test/NoEntityFrameworkTests/TodoItemTests.cs b/test/NoEntityFrameworkTests/TodoItemTests.cs index 3fdd5683c5..90691fd770 100644 --- a/test/NoEntityFrameworkTests/TodoItemTests.cs +++ b/test/NoEntityFrameworkTests/TodoItemTests.cs @@ -10,9 +10,9 @@ namespace NoEntityFrameworkTests; -public sealed class TodoItemTests : IntegrationTest, IClassFixture> +public sealed class TodoItemTests(NoLoggingWebApplicationFactory factory) : IntegrationTest, IClassFixture> { - private readonly NoLoggingWebApplicationFactory _factory; + private readonly NoLoggingWebApplicationFactory _factory = factory; protected override JsonSerializerOptions SerializerOptions { @@ -23,11 +23,6 @@ protected override JsonSerializerOptions SerializerOptions } } - public TodoItemTests(NoLoggingWebApplicationFactory factory) - { - _factory = factory; - } - [Fact] public async Task Can_get_primary_resources() { diff --git a/test/SourceGeneratorTests/GeneratorDriverRunResultExtensions.cs b/test/SourceGeneratorTests/GeneratorDriverRunResultExtensions.cs index bb8e1bfd04..f54f9767d7 100644 --- a/test/SourceGeneratorTests/GeneratorDriverRunResultExtensions.cs +++ b/test/SourceGeneratorTests/GeneratorDriverRunResultExtensions.cs @@ -12,15 +12,11 @@ public static GeneratorDriverRunResultAssertions Should(this GeneratorDriverRunR return new GeneratorDriverRunResultAssertions(instance); } - internal sealed class GeneratorDriverRunResultAssertions : ReferenceTypeAssertions + internal sealed class GeneratorDriverRunResultAssertions(GeneratorDriverRunResult subject) + : ReferenceTypeAssertions(subject) { protected override string Identifier => nameof(GeneratorDriverRunResult); - public GeneratorDriverRunResultAssertions(GeneratorDriverRunResult subject) - : base(subject) - { - } - public void NotHaveDiagnostics() { Subject.Diagnostics.Should().BeEmpty(); diff --git a/test/TestBuildingBlocks/FakeLogMessage.cs b/test/TestBuildingBlocks/FakeLogMessage.cs index 8df3eebde6..cd6cc2bdaf 100644 --- a/test/TestBuildingBlocks/FakeLogMessage.cs +++ b/test/TestBuildingBlocks/FakeLogMessage.cs @@ -4,16 +4,10 @@ namespace TestBuildingBlocks; [PublicAPI] -public sealed class FakeLogMessage +public sealed class FakeLogMessage(LogLevel logLevel, string text) { - public LogLevel LogLevel { get; } - public string Text { get; } - - public FakeLogMessage(LogLevel logLevel, string text) - { - LogLevel = logLevel; - Text = text; - } + public LogLevel LogLevel { get; } = logLevel; + public string Text { get; } = text; public override string ToString() { diff --git a/test/TestBuildingBlocks/FakeLoggerFactory.cs b/test/TestBuildingBlocks/FakeLoggerFactory.cs index 9d8e74c5b3..cb726bb4d7 100644 --- a/test/TestBuildingBlocks/FakeLoggerFactory.cs +++ b/test/TestBuildingBlocks/FakeLoggerFactory.cs @@ -4,14 +4,9 @@ namespace TestBuildingBlocks; [PublicAPI] -public sealed class FakeLoggerFactory : ILoggerFactory, ILoggerProvider +public sealed class FakeLoggerFactory(LogLevel minimumLevel) : ILoggerFactory, ILoggerProvider { - public FakeLogger Logger { get; } - - public FakeLoggerFactory(LogLevel minimumLevel) - { - Logger = new FakeLogger(minimumLevel); - } + public FakeLogger Logger { get; } = new(minimumLevel); public ILogger CreateLogger(string categoryName) { @@ -26,18 +21,13 @@ public void Dispose() { } - public sealed class FakeLogger : ILogger + public sealed class FakeLogger(LogLevel minimumLevel) : ILogger { - private readonly LogLevel _minimumLevel; + private readonly LogLevel _minimumLevel = minimumLevel; private readonly object _lockObject = new(); private readonly List _messages = []; - public FakeLogger(LogLevel minimumLevel) - { - _minimumLevel = minimumLevel; - } - public bool IsEnabled(LogLevel logLevel) { return _minimumLevel != LogLevel.None && logLevel >= _minimumLevel; diff --git a/test/TestBuildingBlocks/IntegrationTestContext.cs b/test/TestBuildingBlocks/IntegrationTestContext.cs index dc186b474b..83f00667b2 100644 --- a/test/TestBuildingBlocks/IntegrationTestContext.cs +++ b/test/TestBuildingBlocks/IntegrationTestContext.cs @@ -83,8 +83,8 @@ private WebApplicationFactory CreateFactory() }); }); - // We have placed an appsettings.json in the TestBuildingBlock project folder and set the content root to there. Note that controllers - // are not discovered in the content root but are registered manually using IntegrationTestContext.UseController. + // We have placed an appsettings.json in the TestBuildingBlocks project directory and set the content root to there. Note that + // controllers are not discovered in the content root, but are registered manually using IntegrationTestContext.UseController. WebApplicationFactory factoryWithConfiguredContentRoot = factory.WithWebHostBuilder(builder => builder.UseSolutionRelativeContentRoot($"test/{nameof(TestBuildingBlocks)}")); @@ -161,8 +161,8 @@ protected override IHostBuilder CreateHostBuilder() .CreateDefaultBuilder(null) .ConfigureAppConfiguration(builder => { - // For tests asserting on log output, we discard the logging settings from appsettings.json. - // But using appsettings.json for all other tests makes it easy to quickly toggle when debugging. + // For tests asserting on log output, we discard the log levels from appsettings.json and environment variables. + // But using appsettings.json for all other tests makes it easy to quickly toggle when debugging tests. if (_loggingConfiguration != null) { builder.Sources.Clear(); diff --git a/test/TestBuildingBlocks/TestBuildingBlocks.csproj b/test/TestBuildingBlocks/TestBuildingBlocks.csproj index ae6cf32ff6..40e10eb297 100644 --- a/test/TestBuildingBlocks/TestBuildingBlocks.csproj +++ b/test/TestBuildingBlocks/TestBuildingBlocks.csproj @@ -19,6 +19,6 @@ - + diff --git a/test/TestBuildingBlocks/TestableDbContext.cs b/test/TestBuildingBlocks/TestableDbContext.cs index 65cb8872be..a91a8530ad 100644 --- a/test/TestBuildingBlocks/TestableDbContext.cs +++ b/test/TestBuildingBlocks/TestableDbContext.cs @@ -5,13 +5,8 @@ namespace TestBuildingBlocks; -public abstract class TestableDbContext : DbContext +public abstract class TestableDbContext(DbContextOptions options) : DbContext(options) { - protected TestableDbContext(DbContextOptions options) - : base(options) - { - } - protected override void OnConfiguring(DbContextOptionsBuilder builder) { WriteSqlStatementsToOutputWindow(builder); diff --git a/test/TestBuildingBlocks/XUnitLoggerProvider.cs b/test/TestBuildingBlocks/XUnitLoggerProvider.cs index e19f8cbbc6..6b5e7f93ec 100644 --- a/test/TestBuildingBlocks/XUnitLoggerProvider.cs +++ b/test/TestBuildingBlocks/XUnitLoggerProvider.cs @@ -38,18 +38,11 @@ public void Dispose() { } - private sealed class XUnitLogger : ILogger + private sealed class XUnitLogger(ITestOutputHelper testOutputHelper, LogOutputFields outputFields, string categoryName) : ILogger { - private readonly ITestOutputHelper _testOutputHelper; - private readonly LogOutputFields _outputFields; - private readonly string _categoryName; - - public XUnitLogger(ITestOutputHelper testOutputHelper, LogOutputFields outputFields, string categoryName) - { - _testOutputHelper = testOutputHelper; - _outputFields = outputFields; - _categoryName = categoryName; - } + private readonly ITestOutputHelper _testOutputHelper = testOutputHelper; + private readonly LogOutputFields _outputFields = outputFields; + private readonly string _categoryName = categoryName; public bool IsEnabled(LogLevel logLevel) { diff --git a/test/UnitTests/Internal/ErrorObjectTests.cs b/test/UnitTests/Internal/ErrorObjectTests.cs index bb8c4e3bcc..9d022b0caa 100644 --- a/test/UnitTests/Internal/ErrorObjectTests.cs +++ b/test/UnitTests/Internal/ErrorObjectTests.cs @@ -7,28 +7,15 @@ namespace UnitTests.Internal; public sealed class ErrorObjectTests { - // Formatting below is broken due to Resharper bug at https://youtrack.jetbrains.com/issue/RSRP-494897/Formatter-directive-broken-in-2023.3-EAP7. - // This no longer works: @formatter:wrap_array_initializer_style wrap_if_long + // @formatter:wrap_array_initializer_style wrap_if_long + // @formatter:max_array_initializer_elements_on_line 10 [Theory] - [InlineData(new[] - { - HttpStatusCode.UnprocessableEntity - }, HttpStatusCode.UnprocessableEntity)] - [InlineData(new[] - { - HttpStatusCode.UnprocessableEntity, - HttpStatusCode.UnprocessableEntity - }, HttpStatusCode.UnprocessableEntity)] - [InlineData(new[] - { - HttpStatusCode.UnprocessableEntity, - HttpStatusCode.Unauthorized - }, HttpStatusCode.BadRequest)] - [InlineData(new[] - { - HttpStatusCode.UnprocessableEntity, - HttpStatusCode.BadGateway - }, HttpStatusCode.InternalServerError)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.UnprocessableEntity }, HttpStatusCode.UnprocessableEntity)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.Unauthorized }, HttpStatusCode.BadRequest)] + [InlineData(new[] { HttpStatusCode.UnprocessableEntity, HttpStatusCode.BadGateway }, HttpStatusCode.InternalServerError)] + // @formatter:max_array_initializer_elements_on_line restore + // @formatter:wrap_array_initializer_style restore public void ErrorDocument_GetErrorStatusCode_IsCorrect(HttpStatusCode[] errorCodes, HttpStatusCode expected) { // Arrange pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy