This commit is contained in:
2024-11-14 21:42:59 -07:00
commit 23fa7a553e
28 changed files with 1219 additions and 0 deletions

View File

@ -0,0 +1,80 @@
using Microsoft.AspNetCore.Mvc;
using OneReview.Domain;
using OneReview.Services;
namespace OneReview.Controllers;
[ApiController]
[Route("[controller]")]
public class ProductsController(ProductService productService) : ControllerBase
{
private readonly ProductService _ProductService = productService;
[HttpPost]
public IActionResult Create(CreateProductRequest request)
{
// mapping to internal representation
Product product = request.ToDomain();
// invoke the use case
_ProductService.Create(product);
// mapping to external representation
ProductResponse productResponse = ProductResponse.FromDomain(product);
// return 201 created response
return CreatedAtAction(
actionName: nameof(Get),
routeValues: new { ProductId = product.Id },
value: productResponse);
}
[HttpGet("{productId:guid}")]
public IActionResult Get(Guid productId)
{
//get the product
Product? product = _ProductService.Get(productId);
// mapping to external representation
ProductResponse? productResponse = ProductResponse.FromDomain(product);
// return 200 ok response
return productResponse is null
? Problem(statusCode: StatusCodes.Status404NotFound, detail: $"Product not found {productId}")
: Ok(productResponse);
}
public record CreateProductRequest(
string Name,
string Category,
string SubCategory)
{
public Product ToDomain() =>
new()
{
Name = Name,
Category = Category,
SubCategory = SubCategory,
};
}
public record ProductResponse(
Guid Id,
string Name,
string Category,
string SubCategory)
{
public static ProductResponse? FromDomain(Product? product) =>
product is null ? null : new ProductResponse(
Id: product.Id,
Name: product.Name,
Category: product.Category,
SubCategory: product.SubCategory);
}
}

View File

@ -0,0 +1,14 @@
using OneReview.Services;
namespace OneReview.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddScoped<ProductService>();
return services;
}
}

View File

@ -0,0 +1,13 @@
namespace OneReview.Domain;
public class Product
{
public Guid Id { get; init; } = Guid.NewGuid();
public required string Name { get; init; }
public required string Category { get; init; }
public required string SubCategory { get; init; }
// Business concerns
}

View File

@ -0,0 +1,14 @@
namespace OneReview.Domain;
public class User
{
public Guid Id { get; init; } = Guid.NewGuid();
public List<Product> Products { get; init; } = [];
internal void AddProduct(Product product) =>
Products.Add(product);
// Business concerns
}

View File

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,8 @@
namespace OneReview.Persistence.Database;
public static class DbConstants
{
public const string DefaultConnectionStringPath = "Database:ConnectionStrings:DefaultConnection";
}

16
src/OneReview/Program.cs Normal file
View File

@ -0,0 +1,16 @@
using OneReview.DependencyInjection;
using OneReview.RequestPipeline;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
{
// configure services (DI)
_ = builder.Services.AddServices();
_ = builder.Services.AddControllers();
}
WebApplication app = builder.Build();
{
// configure request pipeline
_ = app.MapControllers();
_ = app.InitializeDatabase();
}
app.Run();

View File

@ -0,0 +1,12 @@
namespace OneReview.RequestPipeline;
public static class WebApplicationExtensions
{
public static WebApplication InitializeDatabase(this WebApplication application)
{
// DBInitializer.Initialize(application.Configuration[DbConstants.DefaultConnectionStringPath]!);
return application;
}
}

View File

@ -0,0 +1,32 @@
using OneReview.Domain;
namespace OneReview.Services;
public class ProductService
{
private static readonly List<Product> _ProductsRepository = [];
// private static readonly List<User> _UsersRepository = [];
// 1. fetch user
// 1. fetch product
// 1. check wether the user reached the
// 1. update the user
// 1. save the product
public void Create(Product product)
{
// Guid userId,
if (product is null)
throw new ArgumentNullException(nameof(product));
// User user = _UsersRepository.Find(x => x.Id == userId)
// ?? throw new InvalidOperationException();
// user.AddProduct(product);
_ProductsRepository.Add(product);
}
public Product? Get(Guid productId) =>
_ProductsRepository.Find(x => x.Id == productId);
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}