From da67b8eda22d7cab4b723bbb3696750ed545075a Mon Sep 17 00:00:00 2001 From: luxick Date: Thu, 5 Mar 2020 18:17:45 +0100 Subject: [PATCH] Drinks: models and boilerplate --- EstusShots.Client/EstusShotsClient.cs | 2 + EstusShots.Client/Routes/Drinks.cs | 34 +++++ .../Controllers/DrinksController.cs | 54 ++++++++ EstusShots.Server/Mapping/Profiles.cs | 3 + EstusShots.Server/Models/Drink.cs | 13 ++ EstusShots.Server/Services/DrinksService.cs | 25 ++++ .../Services/EstusShotsContext.cs | 1 + EstusShots.Server/Startup.cs | 1 + EstusShots.Shared/Dto/Drink.cs | 13 ++ .../Interfaces/IDrinksController.cs | 30 ++++ .../Models/Parameters/DrinkParameters.cs | 129 ++++++++++++++++++ 11 files changed, 305 insertions(+) create mode 100644 EstusShots.Client/Routes/Drinks.cs create mode 100644 EstusShots.Server/Controllers/DrinksController.cs create mode 100644 EstusShots.Server/Models/Drink.cs create mode 100644 EstusShots.Server/Services/DrinksService.cs create mode 100644 EstusShots.Shared/Dto/Drink.cs create mode 100644 EstusShots.Shared/Interfaces/IDrinksController.cs create mode 100644 EstusShots.Shared/Models/Parameters/DrinkParameters.cs diff --git a/EstusShots.Client/EstusShotsClient.cs b/EstusShots.Client/EstusShotsClient.cs index f66437b..b42bae5 100644 --- a/EstusShots.Client/EstusShotsClient.cs +++ b/EstusShots.Client/EstusShotsClient.cs @@ -24,6 +24,7 @@ namespace EstusShots.Client public Seasons Seasons { get; } public Episodes Episodes { get; } public Players Players { get; } + public Drinks Drinks { get; } /// /// Creates a new instance of @@ -37,6 +38,7 @@ namespace EstusShots.Client Seasons = new Seasons(this); Episodes = new Episodes(this); Players = new Players(this); + Drinks = new Drinks(this); } /// diff --git a/EstusShots.Client/Routes/Drinks.cs b/EstusShots.Client/Routes/Drinks.cs new file mode 100644 index 0000000..5b06d11 --- /dev/null +++ b/EstusShots.Client/Routes/Drinks.cs @@ -0,0 +1,34 @@ +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using EstusShots.Shared.Interfaces; +using EstusShots.Shared.Models; +using EstusShots.Shared.Models.Parameters; + +namespace EstusShots.Client.Routes +{ + /// + public class Drinks : IDrinksController + { + private readonly EstusShotsClient _client; + + public Drinks(EstusShotsClient client) + { + _client = client; + } + + private string ActionUrl([CallerMemberName]string caller = "") => + $"{_client.ApiUrl}{GetType().Name}/{caller}"; + + /// + public async Task> GetDrinks(GetDrinksParameter parameter) + => await _client.PostToApi(ActionUrl(), parameter); + + /// + public async Task> GetDrinkDetails(GetDrinkDetailsParameter parameter) + => await _client.PostToApi(ActionUrl(), parameter); + + /// + public async Task> SaveDrink(SaveDrinkParameter parameter) + => await _client.PostToApi(ActionUrl(), parameter); + } +} \ No newline at end of file diff --git a/EstusShots.Server/Controllers/DrinksController.cs b/EstusShots.Server/Controllers/DrinksController.cs new file mode 100644 index 0000000..54f1ba6 --- /dev/null +++ b/EstusShots.Server/Controllers/DrinksController.cs @@ -0,0 +1,54 @@ +using System; +using System.Threading.Tasks; +using EstusShots.Server.Services; +using EstusShots.Shared.Interfaces; +using EstusShots.Shared.Models; +using EstusShots.Shared.Models.Parameters; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace EstusShots.Server.Controllers +{ + [ApiController] + [Route("/api/[controller]/[action]")] + public class DrinksController : ControllerBase, IDrinksController + { + private readonly ILogger _logger; + private readonly DrinksService _service; + + public DrinksController(ILogger logger, DrinksService drinksService) + { + _logger = logger; + _service = drinksService; + } + + [HttpPost] + public async Task> GetDrinks(GetDrinksParameter parameter) + => await ServiceCall(() => _service.GetDrinks(parameter)); + + [HttpPost] + public async Task> GetDrinkDetails(GetDrinkDetailsParameter parameter) + => await ServiceCall(() => _service.GetDrinkDetails(parameter)); + + [HttpPost] + public async Task> SaveDrink(SaveDrinkParameter parameter) + => await ServiceCall(() => _service.SaveDrink(parameter)); + + private async Task> ServiceCall(Func>> serviceCall) + where T : class, IApiResponse, new() + { + try + { + if (!ModelState.IsValid) _logger.LogError($"Model invalid"); + _logger.LogInformation( + $"Request received from client '{Request.HttpContext.Connection.RemoteIpAddress}'"); + return await serviceCall(); + } + catch (Exception e) + { + _logger.LogError(e, "Exception Occured"); + return new ApiResponse(new OperationResult(e)); + } + } + } +} \ No newline at end of file diff --git a/EstusShots.Server/Mapping/Profiles.cs b/EstusShots.Server/Mapping/Profiles.cs index a9bf2bc..cf60037 100644 --- a/EstusShots.Server/Mapping/Profiles.cs +++ b/EstusShots.Server/Mapping/Profiles.cs @@ -15,6 +15,9 @@ namespace EstusShots.Server.Mapping CreateMap(); CreateMap(); + + CreateMap(); + CreateMap(); } } } \ No newline at end of file diff --git a/EstusShots.Server/Models/Drink.cs b/EstusShots.Server/Models/Drink.cs new file mode 100644 index 0000000..f277478 --- /dev/null +++ b/EstusShots.Server/Models/Drink.cs @@ -0,0 +1,13 @@ +using System; + +namespace EstusShots.Server.Models +{ + public class Drink + { + public Guid DrinkId { get; set; } + + public string Name { get; set; } = default!; + + public double Vol { get; set; } + } +} \ No newline at end of file diff --git a/EstusShots.Server/Services/DrinksService.cs b/EstusShots.Server/Services/DrinksService.cs new file mode 100644 index 0000000..f9f3ab3 --- /dev/null +++ b/EstusShots.Server/Services/DrinksService.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using EstusShots.Shared.Interfaces; +using EstusShots.Shared.Models; +using EstusShots.Shared.Models.Parameters; + +namespace EstusShots.Server.Services +{ + public class DrinksService : IDrinksController + { + public Task> GetDrinks(GetDrinksParameter parameter) + { + throw new System.NotImplementedException(); + } + + public Task> GetDrinkDetails(GetDrinkDetailsParameter parameter) + { + throw new System.NotImplementedException(); + } + + public Task> SaveDrink(SaveDrinkParameter parameter) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/EstusShots.Server/Services/EstusShotsContext.cs b/EstusShots.Server/Services/EstusShotsContext.cs index b28ecb1..812be06 100644 --- a/EstusShots.Server/Services/EstusShotsContext.cs +++ b/EstusShots.Server/Services/EstusShotsContext.cs @@ -13,6 +13,7 @@ namespace EstusShots.Server.Services public DbSet Seasons { get; set; } = default!; public DbSet Episodes { get; set; } = default!; public DbSet Players { get; set; } = default!; + public DbSet Drinks { get; set; } = default!; protected override void OnModelCreating(ModelBuilder modelBuilder) { diff --git a/EstusShots.Server/Startup.cs b/EstusShots.Server/Startup.cs index a15fd2f..7566fec 100644 --- a/EstusShots.Server/Startup.cs +++ b/EstusShots.Server/Startup.cs @@ -48,6 +48,7 @@ namespace EstusShots.Server services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/EstusShots.Shared/Dto/Drink.cs b/EstusShots.Shared/Dto/Drink.cs new file mode 100644 index 0000000..b6b0eed --- /dev/null +++ b/EstusShots.Shared/Dto/Drink.cs @@ -0,0 +1,13 @@ +using System; + +namespace EstusShots.Shared.Dto +{ + public class Drink + { + public Guid DrinkId { get; set; } + + public string Name { get; set; } + + public double Vol { get; set; } + } +} \ No newline at end of file diff --git a/EstusShots.Shared/Interfaces/IDrinksController.cs b/EstusShots.Shared/Interfaces/IDrinksController.cs new file mode 100644 index 0000000..1ac7473 --- /dev/null +++ b/EstusShots.Shared/Interfaces/IDrinksController.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using EstusShots.Shared.Models; +using EstusShots.Shared.Models.Parameters; + +namespace EstusShots.Shared.Interfaces +{ + public interface IDrinksController + { + /// + /// Load all drinks from the database + /// + /// An instance + /// An ApiResponse instance of type + Task> GetDrinks(GetDrinksParameter parameter); + + /// + /// Load detailed information on a single drink + /// + /// An instance + /// An ApiResponse instance of type + Task> GetDrinkDetails(GetDrinkDetailsParameter parameter); + + /// + /// Creates or Updates a drink object + /// + /// An instance + /// An ApiResponse instance of type + Task> SaveDrink(SaveDrinkParameter parameter); + } +} \ No newline at end of file diff --git a/EstusShots.Shared/Models/Parameters/DrinkParameters.cs b/EstusShots.Shared/Models/Parameters/DrinkParameters.cs new file mode 100644 index 0000000..88d0975 --- /dev/null +++ b/EstusShots.Shared/Models/Parameters/DrinkParameters.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Generic; +using EstusShots.Shared.Dto; +using EstusShots.Shared.Interfaces; + +namespace EstusShots.Shared.Models.Parameters +{ + # region GetDrinks + + /// + /// Parameter class for the GetDrinks API controller. + /// + public class GetDrinksParameter : IApiParameter + { + public GetDrinksParameter() + { + } + } + + /// + /// Parameter class returned from the GetDrinks API controller. + /// + public class GetDrinksResponse : IApiResponse + { + /// + /// List of all drinks in the database + /// + public List Drinks { get; set; } + + public GetDrinksResponse(List drinks) + { + Drinks = drinks; + } + + public GetDrinksResponse() + { + } + } + + # endregion + + # region GetDrinkDetails + + /// + /// Parameter class for the GetDrinkDetails API controller. + /// + public class GetDrinkDetailsParameter : IApiParameter + { + /// + /// ID of the drink for which to load details + /// + public Guid DrinkId { get; set; } + + public GetDrinkDetailsParameter(Guid drinkId) + { + DrinkId = drinkId; + } + + public GetDrinkDetailsParameter() + { + } + } + + /// + /// Parameter class returned from the GetDrinkDetails API controller. + /// + public class GetDrinkDetailsResponse : IApiResponse + { + /// + /// Detailed information on a drink + /// + public Drink Drink { get; set; } + + public GetDrinkDetailsResponse(Drink drink) + { + Drink = drink; + } + + public GetDrinkDetailsResponse() + { + } + } + + # endregion + + # region SaveDrink + + /// + /// Parameter class for the SaveDrink API controller. + /// + public class SaveDrinkParameter : IApiParameter + { + /// + /// The object to save in the database + /// + public Drink Drink { get; set; } + + public SaveDrinkParameter(Drink drink) + { + Drink = drink; + } + + public SaveDrinkParameter() + { + } + } + + /// + /// Parameter class returned from the SaveDrink API controller. + /// + public class SaveDrinkResponse : IApiResponse + { + /// + /// ID of the created or updated drink object + /// + public Guid DrinkId { get; set; } + + public SaveDrinkResponse(Guid drinkId) + { + DrinkId = drinkId; + } + + public SaveDrinkResponse() + { + } + } + + # endregion +} \ No newline at end of file