Skip to content

Commit

Permalink
epic: Changes for User Group (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
Hona authored Oct 3, 2024
1 parent 6e8b6c7 commit af9667f
Show file tree
Hide file tree
Showing 25 changed files with 373 additions and 137 deletions.
8 changes: 8 additions & 0 deletions template/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<ItemGroup>
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
3 changes: 2 additions & 1 deletion template/VerticalSliceArchitecture.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<metadata>

<id>Hona.VerticalSliceArchitecture.Template</id>
<version>2.0.0-rc5</version>
<version>2.0.0-rc6</version>
<title>Vertical Slice Architecture Template</title>
<authors>Luke Parker (Hona)</authors>
<description>Spend less time over-engineering, and more time coding. The template has a focus on convenience, and developer confidence.</description>
Expand All @@ -12,6 +12,7 @@
</summary>
<releaseNotes>
Early preview of my v2 VSA template.
Latest changes include what is presented at User Groups.
</releaseNotes>
<readme>README.md</readme>
<projectUrl>https://github.com/Hona/VerticalSliceArchitecture</projectUrl>
Expand Down
2 changes: 2 additions & 0 deletions template/VerticalSliceArchitectureTemplate.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
LICENSE = LICENSE
README.md = README.md
Directory.Build.props = Directory.Build.props
docker-compose.yml = docker-compose.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{92C5999C-A447-479E-8630-064E6FDC78DA}"
Expand Down
9 changes: 9 additions & 0 deletions template/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
db:
image: postgres:latest
environment:
POSTGRES_USER: vsa
POSTGRES_PASSWORD: vsapwd
POSTGRES_DB: verticalslicearchitecturetemplate
ports:
- "5432:5432"
39 changes: 22 additions & 17 deletions template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void MakeMove(BoardPosition position, Tile tile)
{
GameState.XTurn when tile == Tile.X => GameState.OTurn,
GameState.OTurn when tile == Tile.O => GameState.XTurn,
_ => throw new InvalidMoveException("Game is already over")
_ => throw new InvalidMoveException("Game is already over"),
};

Board.SetTileAt(position, tile);
Expand All @@ -65,9 +65,10 @@ public void MakeMove(BoardPosition position, Tile tile)
{
State = winner switch
{
Tile.X => GameState.XTurn,
Tile.X => GameState.XWon,
Tile.O => GameState.OWon,
_ => throw new UnreachableException("Game was won with empty tiles!")
null => GameState.Stalemate,
_ => throw new UnreachableException("Game was won with empty tiles!"),
};
}
}
Expand All @@ -78,8 +79,6 @@ private bool IsGameOver(out Tile? winner)

var tiles = Board.Value;

var firstTile = tiles[0][0];

winner = CheckRowsAndColumns() ?? CheckDiagonals();

return winner is not null || IsStalemate();
Expand All @@ -88,24 +87,24 @@ private bool IsGameOver(out Tile? winner)
{
for (var i = 0; i < _defaultBoardSize.Value; i++)
{
var firstInColumn = tiles[i][0];
// Check columns
if (
firstInColumn != Tile.Empty
&& firstInColumn == tiles[i][1]
&& firstInColumn == tiles[i][2]
tiles[0][i] != Tile.Empty
&& tiles[0][i] == tiles[1][i]
&& tiles[0][i] == tiles[2][i]

Check warning on line 94 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
)
{
return firstInColumn;
return tiles[0][i];
}

var firstInRow = tiles[0][i];
// Check rows
if (
firstInRow != Tile.Empty
&& firstInRow == tiles[1][i]
&& firstInRow == tiles[2][i]
tiles[i][0] != Tile.Empty
&& tiles[i][0] == tiles[i][1]
&& tiles[i][0] == tiles[i][2]

Check warning on line 104 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
)
{
return firstInRow;
return tiles[i][0];
}
}

Expand All @@ -114,11 +113,17 @@ private bool IsGameOver(out Tile? winner)

Tile? CheckDiagonals()
{
if (firstTile != Tile.Empty && firstTile == tiles[1][1] && firstTile == tiles[2][2])
// Check main diagonal
if (
tiles[0][0] != Tile.Empty
&& tiles[0][0] == tiles[1][1]
&& tiles[0][0] == tiles[2][2]

Check warning on line 120 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)

Check warning on line 120 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
)
{
return firstTile;
return tiles[0][0];
}

// Check other diagonal
if (
tiles[0][2] != Tile.Empty

Check warning on line 128 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
&& tiles[0][2] == tiles[1][1]

Check warning on line 129 in template/src/VerticalSliceArchitectureTemplate/Domain/Game.cs

View workflow job for this annotation

GitHub Actions / Build

Assign this magic number '2' to a well-named (variable|constant), and use the (variable|constant) instead. (https://rules.sonarsource.com/csharp/RSPEC-109)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public enum GameState
OTurn,
XWon,
OWon,
Stalemate,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ public enum Tile
{
Empty,
X,
O
O,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public record GameResponse
{
public required string Name { get; set; }
public char[][]? Board { get; set; }

public GameState State { get; set; }
}

[Mapper]
Expand All @@ -24,6 +26,6 @@ private static char GetTileChar(Tile tile) =>
Tile.Empty => ' ',
Tile.X => 'X',
Tile.O => 'O',
_ => '?'
_ => '?',
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace VerticalSliceArchitectureTemplate.Features.Games;

internal sealed record NewGameRequest(string Name);
public sealed record NewGameRequest(string Name);

internal sealed class NewGameRequestValidator : AbstractValidator<NewGameRequest>
{
Expand Down Expand Up @@ -28,6 +28,6 @@ CancellationToken cancellationToken
db.Add(game);
await db.SaveChangesAsync(cancellationToken);

await SendResultAsync(TypedResults.Created("/games/{gameId}", game.Id));
await SendResultAsync(TypedResults.Created($"/games/{game.Id}"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace VerticalSliceArchitectureTemplate.Features.Games;

internal sealed record PlayTurnRequest(GameId GameId, BoardPosition BoardPosition, Tile Player);
public sealed record PlayTurnRequest(GameId GameId, BoardPosition BoardPosition, Tile Player);

internal sealed class PlayTurnCommand(AppDbContext db)
: Endpoint<PlayTurnRequest, Results<Ok<GameResponse>, NotFound>>
Expand All @@ -22,7 +22,7 @@ public override async Task HandleAsync(
CancellationToken cancellationToken
)
{
var game = await db.FindAsync<Game>(request.GameId);
var game = await db.FindAsync<Game>(request.GameId, cancellationToken);

if (game is null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace VerticalSliceArchitectureTemplate.Features.Games;

internal sealed record ViewGameRequest(GameId GameId);
public sealed record ViewGameRequest(GameId GameId);

internal sealed class ViewGameQuery(AppDbContext db)
: Endpoint<ViewGameRequest, Results<Ok<GameResponse>, NotFound>>
Expand Down
21 changes: 18 additions & 3 deletions template/src/VerticalSliceArchitectureTemplate/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Text.Json.Serialization;
using FastEndpoints.Swagger;
using Microsoft.EntityFrameworkCore;

Check warning on line 3 in template/src/VerticalSliceArchitectureTemplate/Program.cs

View workflow job for this annotation

GitHub Actions / Build

Remove this unnecessary 'using'. (https://rules.sonarsource.com/csharp/RSPEC-1128)

[assembly: VogenDefaults(customizations: Customizations.AddFactoryMethodForGuids)]

Expand All @@ -10,22 +12,35 @@
VerticalSliceArchitectureTemplate.DiscoveredTypes.All
);
});
builder.Services.Configure<Microsoft.AspNetCore.Http.Json.JsonOptions>(options =>
{
options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.Configure<Microsoft.AspNetCore.Mvc.JsonOptions>(options =>
{
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
builder.Services.SwaggerDocument();

builder.Services.AddAppDbContext(builder.Configuration);

var app = builder.Build();

app.UseFastEndpoints();
app.UseFastEndpoints(config =>
{
config.Serializer.Options.Converters.Add(new JsonStringEnumConverter());
});
app.UseSwaggerGen();

#if DEBUG
using (var dbScope = app.Services.CreateScope())
{
var db = dbScope.ServiceProvider.GetRequiredService<AppDbContext>();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
await db.Database.EnsureCreatedAsync();
await db.Database.MigrateAsync();
}
#endif

app.Run();

public partial class Program;
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,33 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Ardalis.GuardClauses" Version="4.6.0" />
<PackageReference Include="CSharpier.MsBuild" Version="0.28.2">
<PackageReference Include="Ardalis.GuardClauses" Version="5.0.0" />
<PackageReference Include="FastEndpoints" Version="5.30.0" />
<PackageReference Include="FastEndpoints.Generator" Version="5.30.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FastEndpoints" Version="5.27.0" />
<PackageReference Include="FastEndpoints.Generator" Version="5.28.0">
<PackageReference Include="FastEndpoints.Swagger" Version="5.30.0" />
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FastEndpoints.Swagger" Version="5.27.0" />
<PackageReference Include="FluentValidation" Version="11.9.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7">
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization" Version="8.9.1" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.9.1" />
<PackageReference Include="Microsoft.Extensions.StaticAnalysis" Version="8.9.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.ResourceUtilization" Version="8.7.0" />
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="8.7.0" />
<PackageReference Include="Microsoft.Extensions.StaticAnalysis" Version="8.7.0">
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.8" />
<PackageReference Include="Riok.Mapperly" Version="3.6.0" />
<PackageReference Include="Vogen" Version="5.0.3" />
<PackageReference Update="CSharpier.MsBuild" Version="0.29.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
<PackageReference Include="Riok.Mapperly" Version="3.6.0" />
<PackageReference Include="Vogen" Version="4.0.17" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
global using Xunit;
global using Xunit;
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand All @@ -20,6 +20,10 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Update="CSharpier.MsBuild" Version="0.29.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
Loading

0 comments on commit af9667f

Please sign in to comment.