Skip to content

Coding guidelines tweaks #965

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4c6b02c
Auto-formatted codebase using Resharper
Mar 3, 2021
d909d9f
Replaced "var _" with discards
Mar 3, 2021
0b998d0
Test: fail the build with an inspectcode warning
Mar 3, 2021
0afa692
Test: fail the build with formatting violations
Mar 3, 2021
aeead1f
Revert "Test: fail the build with formatting violations"
Mar 4, 2021
d369ab4
Revert "Test: fail the build with an inspectcode warning"
Mar 4, 2021
49a8334
Empty commit
Mar 4, 2021
9b1ab18
Use extension method for null/empty checks and assertions
Mar 5, 2021
85c0205
Removed unused code
Mar 5, 2021
dc9dceb
Formatting: trim trailing whitespace
Mar 5, 2021
362f637
Boost various hints and suggestions to warning level during cibuild, …
Mar 5, 2021
8903c26
Fixed remaining warnings
Mar 5, 2021
599e103
AV1250: Iterator method returns result of defered execution
Mar 5, 2021
5068bd7
AV1706: Don't use single-letter variables
Mar 6, 2021
8d887e2
AV1562: Do not use ref/out parameters
Mar 6, 2021
55534af
Split up Act and Assert steps in tests
Mar 6, 2021
a144bdd
AV1561: Do not return tuples with more than 2 parameters
Mar 8, 2021
1d73d87
Minor cleanup
Mar 8, 2021
fe1f350
AV1008: Class should not be static
Mar 8, 2021
a303a33
AV1010: Member hides inherited member
Mar 8, 2021
af9206d
AV1115: Member contains the word 'and', which suggests doing multiple…
Mar 8, 2021
d273ce1
AV1210: Do not catch-all
Mar 8, 2021
3513dd1
AV1708: Do not use 'Helper' or 'Shared' in type names
Mar 8, 2021
3a5d0ee
Added CSharpGuidelinesAnalyzer with settings
Mar 8, 2021
36b9961
AV1130: Use collection interface as return type
Mar 10, 2021
a8e6356
Simplified test code for hooks
Mar 10, 2021
06210db
Automated code cleanup
Mar 10, 2021
be1cb11
Refactored TypeHelper
Mar 10, 2021
dc93930
Set AV1555 to Warning level
Mar 10, 2021
d01c1f2
Renamed ITraversalHelper to INodeNavigator
Mar 11, 2021
e644a0f
Renamed IHookExecutorHelper to IHookContainerProvider
Mar 11, 2021
88bd432
Fixed cibuild
Mar 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function CheckLastExitCode {

function RunInspectCode {
$outputPath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), 'jetbrains-inspectcode-results.xml')
dotnet jb inspectcode JsonApiDotNetCore.sln --output="$outputPath" --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=SolutionPersonal -dsl=ProjectPersonal
dotnet jb inspectcode JsonApiDotNetCore.sln --output="$outputPath" --profile=JsonApiDotNetCore-WarningSeverities.DotSettings --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=SolutionPersonal -dsl=ProjectPersonal
CheckLastExitCode

[xml]$xml = Get-Content "$outputPath"
Expand Down
5 changes: 5 additions & 0 deletions CSharpGuidelinesAnalyzer.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<cSharpGuidelinesAnalyzerSettings>
<setting rule="AV1561" name="MaxParameterCount" value="6" />
<setting rule="AV1561" name="MaxConstructorParameterCount" value="12" />
</cSharpGuidelinesAnalyzerSettings>
31 changes: 31 additions & 0 deletions CodingGuidelines.ruleset
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="Coding Guidelines" Description=" " ToolsVersion="16.0">
<Rules AnalyzerId="CSharpGuidelinesAnalyzer" RuleNamespace="CSharpGuidelinesAnalyzer">
<Rule Id="AV1500" Action="None" />
<Rule Id="AV1505" Action="Warning" />
<Rule Id="AV1506" Action="Warning" />
<Rule Id="AV1507" Action="Warning" />
<Rule Id="AV1008" Action="Warning" />
<Rule Id="AV1130" Action="Warning" />
<Rule Id="AV1135" Action="Info" />
<Rule Id="AV1536" Action="None" />
<Rule Id="AV1537" Action="None" />
<Rule Id="AV1551" Action="Info" />
<Rule Id="AV1555" Action="Warning" />
<Rule Id="AV1564" Action="Info" />
<Rule Id="AV1568" Action="Warning" />
<Rule Id="AV1706" Action="Warning" />
<Rule Id="AV1710" Action="Info" />
<Rule Id="AV1711" Action="Info" />
<Rule Id="AV1738" Action="Warning" />
<Rule Id="AV1739" Action="Warning" />
<Rule Id="AV1745" Action="Warning" />
<Rule Id="AV1755" Action="Warning" />
<Rule Id="AV2210" Action="None" />
<Rule Id="AV2220" Action="Warning" />
<Rule Id="AV2230" Action="Info" />
<Rule Id="AV2305" Action="None" />
<Rule Id="AV2310" Action="Info" />
<Rule Id="AV2318" Action="Info" />
</Rules>
</RuleSet>
7 changes: 7 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
<AspNetCoreVersion>3.1.*</AspNetCoreVersion>
<EFCoreVersion>3.1.*</EFCoreVersion>
<NpgsqlPostgreSQLVersion>3.1.*</NpgsqlPostgreSQLVersion>
<CodeAnalysisRuleSet>$(SolutionDir)CodingGuidelines.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>

<ItemGroup>
<AdditionalFiles Include="$(SolutionDir)CSharpGuidelinesAnalyzer.config">
<Link>CSharpGuidelinesAnalyzer.config</Link>
</AdditionalFiles>
</ItemGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'">
<NoWarn>$(NoWarn);1591</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down
254 changes: 254 additions & 0 deletions JsonApiDotNetCore-WarningSeverities.DotSettings

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions JsonApiDotNetCore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$, $NAME$);</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyStringComparison/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestDiscardDeclarationVarStyle/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TailRecursiveCall/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=TryCastAlwaysSucceeds/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnnecessaryWhitespace/@EntryIndexedValue">HINT</s:String>
Expand Down Expand Up @@ -554,7 +555,6 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$, $NAME$);</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForBuiltInTypes/@EntryValue">UseExplicitType</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForOtherTypes/@EntryValue">UseVarWhenEvident</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/ForSimpleTypes/@EntryValue">UseVarWhenEvident</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/PreferExplicitDiscardDeclaration/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CSharpVarKeywordUsage/UseRoslynLogicForEvidentTypes/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/EnableClangFormatSupport/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/EditorConfig/EnableEditorConfigSupport/@EntryValue">False</s:Boolean>
Expand Down Expand Up @@ -590,7 +590,7 @@ JsonApiDotNetCore.ArgumentGuard.NotNull($EXPR$, $NAME$);</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=546845333F49494AB6CF8F0477A0F71D/ReplacePattern/@EntryValue">JsonApiDotNetCore.ArgumentGuard.NotNull($argument$, nameof($argument$));&#xD;
$left$ = $right$;</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=546845333F49494AB6CF8F0477A0F71D/SearchPattern/@EntryValue">$left$ = $right$ ?? throw new ArgumentNullException(nameof($argument$));</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=546845333F49494AB6CF8F0477A0F71D/Severity/@EntryValue">SUGGESTION</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=546845333F49494AB6CF8F0477A0F71D/Severity/@EntryValue">WARNING</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/Comment/@EntryValue">Replace classic argument null check with Guard clause</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/CustomPatternPlaceholder/=argument/@KeyIndexDefined">True</s:Boolean>
Expand All @@ -604,7 +604,7 @@ $left$ = $right$;</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/ReplaceComment/@EntryValue">Replace argument null check with Guard clause</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/ReplacePattern/@EntryValue">JsonApiDotNetCore.ArgumentGuard.NotNull($argument$, nameof($argument$));</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/SearchPattern/@EntryValue">if ($argument$ == null) throw new ArgumentNullException(nameof($argument$));</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/Severity/@EntryValue">SUGGESTION</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=67F8FFFFE7DCA24889232D6952BDFD59/Severity/@EntryValue">WARNING</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/Comment/@EntryValue">Replace collection null/empty check with extension method</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/CustomPatternPlaceholder/=collection/@KeyIndexDefined">True</s:Boolean>
Expand All @@ -617,7 +617,7 @@ $left$ = $right$;</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/ReplaceComment/@EntryValue">Replace collection null/empty check with extension method</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/ReplacePattern/@EntryValue">$collection$.IsNullOrEmpty()</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/SearchPattern/@EntryValue">$collection$ == null || !$collection$.Any()</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/Severity/@EntryValue">SUGGESTION</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/StructuralSearch/Pattern/=B3D9EE6B4EC62A4F961EB15F9ADEC2C6/Severity/@EntryValue">WARNING</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Assignee/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Injectables/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=linebreaks/@EntryIndexedValue">True</s:Boolean>
Expand Down
2 changes: 2 additions & 0 deletions benchmarks/BenchmarkResourcePublicNames.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#pragma warning disable AV1008 // Class should not be static

namespace Benchmarks
{
internal static class BenchmarkResourcePublicNames
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/DependencyFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

namespace Benchmarks
{
internal static class DependencyFactory
internal sealed class DependencyFactory
{
public static IResourceGraph CreateResourceGraph(IJsonApiOptions options)
public IResourceGraph CreateResourceGraph(IJsonApiOptions options)
{
var builder = new ResourceGraphBuilder(options, NullLoggerFactory.Instance);
builder.Add<BenchmarkResource>(BenchmarkResourcePublicNames.Type);
Expand Down
5 changes: 3 additions & 2 deletions benchmarks/Query/QueryParserBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Benchmarks.Query
[MemoryDiagnoser]
public class QueryParserBenchmarks
{
private readonly DependencyFactory _dependencyFactory = new DependencyFactory();
private readonly FakeRequestQueryStringAccessor _queryStringAccessor = new FakeRequestQueryStringAccessor();
private readonly QueryStringReader _queryStringReaderForSort;
private readonly QueryStringReader _queryStringReaderForAll;
Expand All @@ -31,7 +32,7 @@ public QueryParserBenchmarks()
EnableLegacyFilterNotation = true
};

IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options);
IResourceGraph resourceGraph = _dependencyFactory.CreateResourceGraph(options);

var request = new JsonApiRequest
{
Expand Down Expand Up @@ -107,7 +108,7 @@ public void ComplexQuery()

private void Run(int iterations, Action action)
{
for (int i = 0; i < iterations; i++)
for (int index = 0; index < iterations; index++)
{
action();
}
Expand Down
3 changes: 2 additions & 1 deletion benchmarks/Serialization/JsonApiDeserializerBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ public class JsonApiDeserializerBenchmarks
}
});

private readonly DependencyFactory _dependencyFactory = new DependencyFactory();
private readonly IJsonApiDeserializer _jsonApiDeserializer;

public JsonApiDeserializerBenchmarks()
{
var options = new JsonApiOptions();
IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options);
IResourceGraph resourceGraph = _dependencyFactory.CreateResourceGraph(options);
var targetedFields = new TargetedFields();
var request = new JsonApiRequest();
var resourceFactory = new ResourceFactory(new ServiceContainer());
Expand Down
3 changes: 2 additions & 1 deletion benchmarks/Serialization/JsonApiSerializerBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ public class JsonApiSerializerBenchmarks
Name = Guid.NewGuid().ToString()
};

private readonly DependencyFactory _dependencyFactory = new DependencyFactory();
private readonly IJsonApiSerializer _jsonApiSerializer;

public JsonApiSerializerBenchmarks()
{
var options = new JsonApiOptions();
IResourceGraph resourceGraph = DependencyFactory.CreateResourceGraph(options);
IResourceGraph resourceGraph = _dependencyFactory.CreateResourceGraph(options);
IFieldsToSerialize fieldsToSerialize = CreateFieldsToSerialize(resourceGraph);

IMetaBuilder metaBuilder = new Mock<IMetaBuilder>().Object;
Expand Down
2 changes: 1 addition & 1 deletion inspectcode.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,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 --output="$outputPath" --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=SolutionPersonal -dsl=ProjectPersonal
dotnet jb inspectcode JsonApiDotNetCore.sln --output="$outputPath" --profile=JsonApiDotNetCore-WarningSeverities.DotSettings --properties:Configuration=Release --severity=WARNING --verbosity=WARN -dsl=GlobalAll -dsl=SolutionPersonal -dsl=ProjectPersonal

if ($LASTEXITCODE -ne 0) {
throw "Code inspection failed with exit code $LASTEXITCODE"
Expand Down
24 changes: 12 additions & 12 deletions src/Examples/JsonApiDotNetCoreExample/Data/AppDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ public AppDbContext(DbContextOptions<AppDbContext> options)
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<TodoItem>()
.HasOne(t => t.Assignee)
.WithMany(p => p.AssignedTodoItems);
.HasOne(todoItem => todoItem.Assignee)
.WithMany(person => person.AssignedTodoItems);

builder.Entity<TodoItem>()
.HasOne(t => t.Owner)
.WithMany(p => p.TodoItems);
.HasOne(todoItem => todoItem.Owner)
.WithMany(person => person.TodoItems);

builder.Entity<ArticleTag>()
.HasKey(bc => new
Expand All @@ -45,23 +45,23 @@ protected override void OnModelCreating(ModelBuilder builder)
});

builder.Entity<Person>()
.HasOne(t => t.StakeHolderTodoItem)
.WithMany(t => t.StakeHolders)
.HasOne(person => person.StakeHolderTodoItem)
.WithMany(todoItem => todoItem.StakeHolders)
.OnDelete(DeleteBehavior.Cascade);

builder.Entity<TodoItem>()
.HasMany(t => t.ChildTodoItems)
.WithOne(t => t.ParentTodo);
.HasMany(todoItem => todoItem.ChildTodoItems)
.WithOne(todoItem => todoItem.ParentTodo);

builder.Entity<Passport>()
.HasOne(p => p.Person)
.WithOne(p => p.Passport)
.HasOne(passport => passport.Person)
.WithOne(person => person.Passport)
.HasForeignKey<Person>("PassportKey")
.OnDelete(DeleteBehavior.SetNull);

builder.Entity<TodoItem>()
.HasOne(p => p.OneToOnePerson)
.WithOne(p => p.OneToOneTodoItem)
.HasOne(todoItem => todoItem.OneToOnePerson)
.WithOne(person => person.OneToOneTodoItem)
.HasForeignKey<TodoItem>("OneToOnePersonKey");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public ArticleHooksDefinition(IResourceGraph resourceGraph)

public override IEnumerable<Article> OnReturn(HashSet<Article> resources, ResourcePipeline pipeline)
{
if (pipeline == ResourcePipeline.GetSingle && resources.Any(r => r.Caption == "Classified"))
if (pipeline == ResourcePipeline.GetSingle && resources.Any(article => article.Caption == "Classified"))
{
throw new JsonApiException(new Error(HttpStatusCode.Forbidden)
{
Title = "You are not allowed to see this article."
});
}

return resources.Where(article => article.Caption != "This should not be included");
return resources.Where(article => article.Caption != "This should not be included").ToArray();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ public override void BeforeRead(ResourcePipeline pipeline, bool isIncluded = fal

public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary<Passport> resourcesByRelationship, ResourcePipeline pipeline)
{
resourcesByRelationship.GetByRelationship<Person>().ToList().ForEach(kvp => DisallowLocked(kvp.Value));
resourcesByRelationship.GetByRelationship<Person>().ToList().ForEach(pair => DisallowLocked(pair.Value));
}

public override IEnumerable<Passport> OnReturn(HashSet<Passport> resources, ResourcePipeline pipeline)
{
return resources.Where(passport => !passport.IsLocked);
return resources.Where(passport => !passport.IsLocked).ToArray();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public override IEnumerable<string> BeforeUpdateRelationship(HashSet<string> ids

public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary<Person> resourcesByRelationship, ResourcePipeline pipeline)
{
resourcesByRelationship.GetByRelationship<Passport>().ToList().ForEach(kvp => DisallowLocked(kvp.Value));
resourcesByRelationship.GetByRelationship<Passport>().ToList().ForEach(pair => DisallowLocked(pair.Value));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public TagHooksDefinition(IResourceGraph resourceGraph)

public override IEnumerable<Tag> OnReturn(HashSet<Tag> resources, ResourcePipeline pipeline)
{
return resources.Where(tag => tag.Name != "This should not be included");
return resources.Where(tag => tag.Name != "This should not be included").ToArray();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ public override void BeforeRead(ResourcePipeline pipeline, bool isIncluded = fal

public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary<TodoItem> resourcesByRelationship, ResourcePipeline pipeline)
{
List<TodoItem> todoItems = resourcesByRelationship.GetByRelationship<Person>().SelectMany(kvp => kvp.Value).ToList();
List<TodoItem> todoItems = resourcesByRelationship.GetByRelationship<Person>().SelectMany(pair => pair.Value).ToList();
DisallowLocked(todoItems);
}

public override IEnumerable<TodoItem> OnReturn(HashSet<TodoItem> resources, ResourcePipeline pipeline)
{
return resources.Where(todoItem => todoItem.Description != "This should not be included");
return resources.Where(todoItem => todoItem.Description != "This should not be included").ToArray();
}
}
}
19 changes: 17 additions & 2 deletions src/JsonApiDotNetCore/ArgumentGuard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Linq;
using JetBrains.Annotations;

#pragma warning disable AV1008 // Class should not be static

namespace JsonApiDotNetCore
{
internal static class ArgumentGuard
Expand All @@ -20,13 +22,26 @@ public static void NotNull<T>([CanBeNull] [NoEnumeration] T value, [NotNull] [In

[AssertionMethod]
[ContractAnnotation("value: null => halt")]
public static void NotNullNorEmpty<T>([CanBeNull] IEnumerable<T> value, [NotNull] [InvokerParameterName] string name)
public static void NotNullNorEmpty<T>([CanBeNull] IEnumerable<T> value, [NotNull] [InvokerParameterName] string name,
[CanBeNull] string collectionName = null)
{
NotNull(value, name);

if (!value.Any())
{
throw new ArgumentException("Collection cannot be empty.", name);
throw new ArgumentException($"Must have one or more {collectionName ?? name}.", name);
}
}

[AssertionMethod]
[ContractAnnotation("value: null => halt")]
public static void NotNullNorEmpty([CanBeNull] string value, [NotNull] [InvokerParameterName] string name)
{
NotNull(value, name);

if (value == string.Empty)
{
throw new ArgumentException("String cannot be null or empty.", name);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/JsonApiDotNetCore/ArrayFactory.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#pragma warning disable AV1008 // Class should not be static
#pragma warning disable AV1130 // Return type in method signature should be a collection interface instead of a concrete type

namespace JsonApiDotNetCore
{
internal static class ArrayFactory
Expand Down
Loading