Skip to content

Commit

Permalink
Add web api for management.
Browse files Browse the repository at this point in the history
  • Loading branch information
kasper090288 committed Mar 19, 2024
1 parent ce35a07 commit f4a9d18
Show file tree
Hide file tree
Showing 26 changed files with 460 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Football.Management.Application/Abstractions/ICommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using FluentResults;
using MediatR;

namespace Football.Management.Application.Abstractions;

public interface ICommand : IRequest<Result> {}
public interface ICommand<TResponse> : IRequest<Result<TResponse>> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using FluentResults;
using MediatR;

namespace Football.Management.Application.Abstractions;

public interface ICommandHandler<TCommand> : IRequestHandler<TCommand, Result> where TCommand : ICommand {}
public interface ICommandHandler<TCommand, TResponse> : IRequestHandler<TCommand, Result<TResponse>> where TCommand : ICommand<TResponse> {}
6 changes: 6 additions & 0 deletions Football.Management.Application/Abstractions/IQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using FluentResults;
using MediatR;

namespace Football.Management.Application.Abstractions;

public interface IQuery<TResponse> : IRequest<Result<TResponse>> {}
6 changes: 6 additions & 0 deletions Football.Management.Application/Abstractions/IQueryHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using FluentResults;
using MediatR;

namespace Football.Management.Application.Abstractions;

public interface IQueryHandler<TQuery, TResponse> : IRequestHandler<TQuery, Result<TResponse>> where TQuery : IQuery<TResponse> {}
8 changes: 8 additions & 0 deletions Football.Management.Application/AssemblyReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Reflection;

namespace Football.Management.Application;

public class AssemblyReference
{
public static readonly Assembly Assembly = typeof(AssemblyReference).Assembly;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\Football.Management.Domain\Football.Management.Domain.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentResults" Version="3.15.2" />
<PackageReference Include="MediatR" Version="12.2.0" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using Football.Management.Application.Abstractions;
using Football.Management.Domain.Identities;

namespace Football.Management.Application.Players.Commands.CreatePlayer;

public sealed record CreatePlayerCommand(string FirstName, string LastName, int AttackSkill, int MidfieldSkill, int DefenseSkill) : ICommand<PlayerId>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using FluentResults;
using Football.Management.Application.Abstractions;
using Football.Management.Domain.Entities;
using Football.Management.Domain.Identities;
using Football.Management.Domain.Repositories;
using Football.Management.Domain.ValueObjects;

namespace Football.Management.Application.Players.Commands.CreatePlayer;

internal sealed class CreatePlayerCommandHander : ICommandHandler<CreatePlayerCommand, PlayerId>
{
private readonly IPlayerRepository _playerRepository;

public CreatePlayerCommandHander(IPlayerRepository playerRepository)
{
_playerRepository = playerRepository;
}

public async Task<Result<PlayerId>> Handle(CreatePlayerCommand request, CancellationToken cancellationToken)
{
var firstName = PlayerFirstName.Create(request.FirstName);

if (firstName.IsFailed)
{
return firstName.ToResult<PlayerId>();
}

var lastName = PlayerLastName.Create(request.LastName);

if (lastName.IsFailed)
{
return lastName.ToResult<PlayerId>();
}

var attackSkill = PlayerAttackSkill.Create(request.AttackSkill);

if (attackSkill.IsFailed)
{
return attackSkill.ToResult<PlayerId>();
}

var midfieldSkill = PlayerMidfieldSkill.Create(request.MidfieldSkill);

if (midfieldSkill.IsFailed)
{
return midfieldSkill.ToResult<PlayerId>();
}

var defenseSkill = PlayerDefenseSkill.Create(request.DefenseSkill);

if (defenseSkill.IsFailed)
{
return defenseSkill.ToResult<PlayerId>();
}

var player = Player.Create(
firstName.ValueOrDefault,
lastName.ValueOrDefault,
attackSkill.ValueOrDefault,
midfieldSkill.ValueOrDefault,
defenseSkill.ValueOrDefault);

if (player.IsFailed)
{
return player.ToResult<PlayerId>();
}

await _playerRepository.AddAsync(player.Value, cancellationToken);

return player.Value.Id;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
using Football.Management.Application.Abstractions;
using Football.Management.Domain.Entities;
using Football.Management.Domain.Identities;

namespace Football.Management.Application.Players.Queries.GetPlayerById;

public sealed record GetPlayerByIdQuery(PlayerId PlayerId) : IQuery<Player>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using FluentResults;
using Football.Management.Application.Abstractions;
using Football.Management.Domain.Entities;
using Football.Management.Domain.Repositories;

namespace Football.Management.Application.Players.Queries.GetPlayerById;

public class GetPlayerByIdQueryHandler : IQueryHandler<GetPlayerByIdQuery, Player>
{
private readonly IPlayerRepository _playerRepository;

public GetPlayerByIdQueryHandler(IPlayerRepository playerRepository)
{
_playerRepository = playerRepository;
}

public async Task<Result<Player>> Handle(GetPlayerByIdQuery request, CancellationToken cancellationToken)
{
var player = await _playerRepository.GetAsync(request.PlayerId, cancellationToken);

if (player is null)
{
return Result.Fail("Player was not found.");
}

return player;
}
}
10 changes: 10 additions & 0 deletions Football.Management.Domain/Repositories/IPlayerRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Football.Management.Domain.Entities;
using Football.Management.Domain.Identities;

namespace Football.Management.Domain.Repositories;

public interface IPlayerRepository
{
Task AddAsync(Player player, CancellationToken cancellationToken);
Task<Player?> GetAsync(PlayerId playerId, CancellationToken cancellationToken);
}
8 changes: 8 additions & 0 deletions Football.Management.Persistence/AssemblyReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Reflection;

namespace Football.Management.Persistence;

public class AssemblyReference
{
public static readonly Assembly Assembly = typeof(AssemblyReference).Assembly;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\Football.Management.Domain\Football.Management.Domain.csproj" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Football.Management.Domain.Entities;
using Football.Management.Domain.Identities;
using Football.Management.Domain.Repositories;
using Football.Management.Domain.ValueObjects;

namespace Football.Management.Persistence.Repositories;

public sealed class PlayerRepositoryInMemory : IPlayerRepository
{
private List<Player> _players = new();

public PlayerRepositoryInMemory()
{
var player = Player.Create(
PlayerFirstName.Create("Kamil").ValueOrDefault,
PlayerLastName.Create("Grabara").ValueOrDefault,
PlayerAttackSkill.Create(0).ValueOrDefault,
PlayerMidfieldSkill.Create(5).ValueOrDefault,
PlayerDefenseSkill.Create(10).ValueOrDefault);

_players.Add(player.Value);
}

public async Task AddAsync(Player player, CancellationToken cancellationToken)
{
var result = await GetAsync(player.Id, cancellationToken);

if (result is not null)
{
return;
}

_players.Add(player);
}

public Task<Player?> GetAsync(PlayerId playerId, CancellationToken cancellationToken)
{
return Task.FromResult(_players.FirstOrDefault(i => i.Id.Id == playerId.Id));
}
}
8 changes: 8 additions & 0 deletions Football.Management.Presentation/AssemblyReference.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Reflection;

namespace Football.Management.Presentation;

public class AssemblyReference
{
public static readonly Assembly Assembly = typeof(AssemblyReference).Assembly;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\Football.Management.Application\Football.Management.Application.csproj" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Microsoft.AspNetCore.Mvc;
using MediatR;
using Football.Management.Application.Players.Commands.CreatePlayer;
using Football.Management.Presentation.Players.Requests;
using Football.Management.Domain.Identities;
using Football.Management.Application.Players.Queries.GetPlayerById;
using Football.Management.Presentation.Players.Responses;

namespace Football.Management.Presentation.Players.Controllers;

[ApiController]
[Route("api/players")]
public sealed class PlayersController : ControllerBase
{
private readonly ISender _sender;

public PlayersController(ISender sender)
{
_sender = sender;
}

[HttpPost]
public async Task<IActionResult> CreatePlayer(CreatePlayerRequest request, CancellationToken cancellationToken)
{
var command = new CreatePlayerCommand(request.FirstName, request.LastName, request.AttackSkill, request.MidfieldSkill, request.DefenseSkill);
var result = await _sender.Send(command, cancellationToken);
return result.IsSuccess ? Ok(result.Value) : BadRequest(result.Errors);
}

[HttpGet("{playerId}")]
public async Task<IActionResult> GetPlayerById(Guid playerId, CancellationToken cancellationToken)
{
var query = new GetPlayerByIdQuery(new PlayerId(playerId));
var result = await _sender.Send(query, cancellationToken);
if (result.IsSuccess)
{
var player = result.Value;
var response = new GetPlayerByIdResponse(
player.Id.Id,
player.FirstName.Value,
player.LastName.Value,
player.AttackSkill.Value,
player.MidfieldSkill.Value,
player.DefenseSkill.Value);
return Ok(response);
}
return NotFound(result.Errors);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Football.Management.Presentation.Players.Requests;

public sealed record CreatePlayerRequest(string FirstName, string LastName, int AttackSkill, int MidfieldSkill, int DefenseSkill);
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace Football.Management.Presentation.Players.Responses;

public sealed record GetPlayerByIdResponse(Guid Id, string FirstName, string LastName, int AttackSkill, int MidfieldSkill, int DefenseSkill);
21 changes: 21 additions & 0 deletions Football.Management.Web/Football.Management.Web.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.2" />
<PackageReference Include="Scrutor" Version="4.2.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Football.Management.Application\Football.Management.Application.csproj" />
<ProjectReference Include="..\Football.Management.Persistence\Football.Management.Persistence.csproj" />
<ProjectReference Include="..\Football.Management.Presentation\Football.Management.Presentation.csproj" />
</ItemGroup>

</Project>
6 changes: 6 additions & 0 deletions Football.Management.Web/Football.Management.Web.http
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@Football.Management.Web_HostAddress = http://localhost:5137

GET {{Football.Management.Web_HostAddress}}/weatherforecast/
Accept: application/json

###
Loading

0 comments on commit f4a9d18

Please sign in to comment.