Skip to content

Commit 4c750f9

Browse files
authored
Merge branch 'main' into support-nested-modules
2 parents 4bac839 + 8456dd0 commit 4c750f9

File tree

16 files changed

+477
-123
lines changed

16 files changed

+477
-123
lines changed

.github/workflows/dotnetcore.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ jobs:
1818

1919
name: Github Actions Build
2020
runs-on: ubuntu-latest
21-
21+
permissions: write-all
22+
2223
steps:
2324
- uses: actions/checkout@v1
2425
- name: Setup .NET Core

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ For a better understanding, take a good look at the [samples](https://github.com
66

77
Other extensions include:
88

9-
* `Validate<T>` - [FluentValidation](https://github.com/JeremySkinner/FluentValidation) extensions to validate incoming HTTP requests which is not available with ASP.NET Core Minimal APIs.
9+
* `Validate<T> / ValidateAsync<T>` - [FluentValidation](https://github.com/JeremySkinner/FluentValidation) extensions to validate incoming HTTP requests which is not available with ASP.NET Core Minimal APIs.
1010
* `BindFile/BindFiles/BindFileAndSave/BindFilesAndSave` - Allows you to easily get access to a file/files that has been uploaded. Alternatively you can call `BindFilesAndSave` and this will save it to a path you specify.
1111
* Routes to use in common ASP.NET Core middleware e.g., `app.UseExceptionHandler("/errorhandler");`.
1212
* `IResponseNegotiator`s allow you to define how the response should look on a certain Accept header(content negotiation). Handling JSON is built in the default response but implementing an interface allows the user to choose how they want to represent resources.
@@ -21,7 +21,7 @@ Other extensions include:
2121

2222
### Join our Slack Channel
2323

24-
<a href="https://join.slack.com/t/cartercommunity/shared_invite/enQtMzY2Nzc0NjU2MTgyLWY3M2Y2Yjk3NzViN2Y3YTQ4ZDA5NWFlMTYxMTIwNDFkMTc5YWEwMDFiOWUyM2Q4ZmY5YmRkODYyYTllZDViMmE"><img src="./slack.svg" width="140px"/></a>
24+
[![Join our slack channel](https://raw.githubusercontent.com/CarterCommunity/Carter/main/slack.png)](https://join.slack.com/t/cartercommunity/shared_invite/enQtMzY2Nzc0NjU2MTgyLWY3M2Y2Yjk3NzViN2Y3YTQ4ZDA5NWFlMTYxMTIwNDFkMTc5YWEwMDFiOWUyM2Q4ZmY5YmRkODYyYTllZDViMmE)
2525

2626
#### Routing
2727

samples/CarterSample/Features/CastMembers/CastMemberModule.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ public class CastMemberModule : ICarterModule
44
{
55
public void AddRoutes(IEndpointRouteBuilder app)
66
{
7-
app.MapPost("/castmembers", (HttpRequest req, CastMember castMember) =>
7+
app.MapPost("/castmembers", async (HttpRequest req, CastMember castMember) =>
88
{
9-
var result = req.Validate<CastMember>(castMember);
9+
var result = await req.ValidateAsync<CastMember>(castMember);
1010

1111
if (!result.IsValid)
1212
{
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
namespace ValidatorOnlyProject
22
{
3+
using System.Threading.Tasks;
34
using FluentValidation;
45

56
public class CastMemberValidator : AbstractValidator<CastMember>
67
{
78
public CastMemberValidator()
89
{
9-
this.RuleFor(x => x.Name).NotEmpty();
10+
this.RuleFor(x => x.Name).NotEmpty().MustAsync(async (name, cancellation) =>
11+
{
12+
await Task.Delay(50);
13+
return true;
14+
});
1015
}
1116
}
1217
}

slack.png

2.54 KB
Loading

slack.svg

Lines changed: 0 additions & 107 deletions
This file was deleted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
namespace Carter.Analyzers;
2+
3+
using System.Collections.Immutable;
4+
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.CSharp.Syntax;
6+
using Microsoft.CodeAnalysis.Diagnostics;
7+
8+
[DiagnosticAnalyzer(LanguageNames.CSharp)]
9+
internal sealed class CarterModuleShouldNotHaveDependenciesAnalyzer : DiagnosticAnalyzer
10+
{
11+
public override void Initialize(AnalysisContext context)
12+
{
13+
context.EnableConcurrentExecution();
14+
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
15+
context.RegisterCompilationStartAction(OnCompilationStart);
16+
}
17+
18+
private static void OnCompilationStart(CompilationStartAnalysisContext context)
19+
{
20+
var carterModuleType = context.Compilation.GetTypeByMetadataName("Carter.ICarterModule");
21+
if (carterModuleType is null)
22+
{
23+
return;
24+
}
25+
26+
context.RegisterSymbolAction(ctx => OnTypeAnalysis(ctx, carterModuleType), SymbolKind.NamedType);
27+
}
28+
29+
private static void OnTypeAnalysis(SymbolAnalysisContext context, INamedTypeSymbol carterModuleType)
30+
{
31+
var typeSymbol = (INamedTypeSymbol)context.Symbol;
32+
if (!typeSymbol.Interfaces.Contains(carterModuleType, SymbolEqualityComparer.Default))
33+
{
34+
return;
35+
}
36+
37+
foreach (var constructor in typeSymbol.Constructors)
38+
{
39+
if (constructor.DeclaredAccessibility == Accessibility.Private || constructor.Parameters.Length == 0)
40+
{
41+
continue;
42+
}
43+
44+
foreach (var syntaxReference in constructor.DeclaringSyntaxReferences)
45+
{
46+
var node = syntaxReference.GetSyntax();
47+
SyntaxToken identifier;
48+
if (node is ConstructorDeclarationSyntax constructorDeclaration)
49+
{
50+
identifier = constructorDeclaration.Identifier;
51+
} else if (node is RecordDeclarationSyntax recordDeclaration)
52+
{
53+
identifier = recordDeclaration.Identifier;
54+
}
55+
else
56+
{
57+
continue;
58+
}
59+
60+
var diagnostic = Diagnostic.Create(
61+
DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies,
62+
identifier.GetLocation(),
63+
identifier.Text
64+
);
65+
context.ReportDiagnostic(diagnostic);
66+
}
67+
}
68+
}
69+
70+
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = [DiagnosticDescriptors.CarterModuleShouldNotHaveDependencies];
71+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Microsoft.CodeAnalysis;
2+
3+
namespace Carter.Analyzers;
4+
5+
internal static class DiagnosticDescriptors
6+
{
7+
public static readonly DiagnosticDescriptor CarterModuleShouldNotHaveDependencies = new(
8+
"CARTER1",
9+
"Carter module should not have dependencies",
10+
"'{0}' should not have dependencies",
11+
"Usage",
12+
DiagnosticSeverity.Warning,
13+
true,
14+
"When a class implements ICarterModule, it should not have any dependencies. This is because Carter uses minimal APIs and dependencies should be declared in the request delegate."
15+
);
16+
}

src/Carter/Carter.csproj

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,28 @@
1212
<PublishRepositoryUrl>true</PublishRepositoryUrl>
1313
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
1414
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
15+
<PackageReadmeFile>README.md</PackageReadmeFile>
16+
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
17+
<NoWarn>RS2008</NoWarn>
1518
</PropertyGroup>
1619
<ItemGroup>
1720
<None Include="..\..\media\carterlogo.png" Pack="true" PackagePath="\" />
21+
<None Include="..\..\README.md" Pack="true" PackagePath="\"/>
22+
<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
1823
</ItemGroup>
1924
<ItemGroup>
2025
<FrameworkReference Include="Microsoft.AspNetCore.App" />
2126
</ItemGroup>
2227
<ItemGroup>
2328
<PackageReference Include="FluentValidation" Version="11.8.0" />
29+
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" PrivateAssets="compile" />
2430
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.0" />
2531
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
2632
<PackageReference Include="MinVer" Version="2.5.0">
2733
<PrivateAssets>all</PrivateAssets>
2834
</PackageReference>
29-
35+
</ItemGroup>
36+
<ItemGroup>
37+
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
3038
</ItemGroup>
3139
</Project>

src/Carter/DependencyContextAssemblyCatalog.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ private static Assembly SafeLoadAssembly(AssemblyName assemblyName)
8989
{
9090
try
9191
{
92+
#pragma warning disable RS1035
9293
return Assembly.Load(assemblyName);
94+
#pragma warning restore RS1035
9395
}
9496
catch (Exception)
9597
{

0 commit comments

Comments
 (0)