diff --git a/src/Supermarket.API/Controllers/BaseApiController.cs b/src/Supermarket.API/Controllers/BaseApiController.cs new file mode 100644 index 0000000..52b0e7a --- /dev/null +++ b/src/Supermarket.API/Controllers/BaseApiController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Supermarket.API.Controllers +{ + [Route("/api/[controller]")] + [Produces("application/json")] + [ApiController] + public class BaseApiController : ControllerBase + { + + } +} \ No newline at end of file diff --git a/src/Supermarket.API/Controllers/CategoriesController.cs b/src/Supermarket.API/Controllers/CategoriesController.cs index 63e5dbe..875ada2 100644 --- a/src/Supermarket.API/Controllers/CategoriesController.cs +++ b/src/Supermarket.API/Controllers/CategoriesController.cs @@ -8,10 +8,7 @@ namespace Supermarket.API.Controllers { - [Route("/api/categories")] - [Produces("application/json")] - [ApiController] - public class CategoriesController : Controller + public class CategoriesController : BaseApiController { private readonly ICategoryService _categoryService; private readonly IMapper _mapper; diff --git a/src/Supermarket.API/Controllers/ProductsController.cs b/src/Supermarket.API/Controllers/ProductsController.cs index a389208..a7f8574 100644 --- a/src/Supermarket.API/Controllers/ProductsController.cs +++ b/src/Supermarket.API/Controllers/ProductsController.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Threading.Tasks; using AutoMapper; using Microsoft.AspNetCore.Mvc; @@ -9,10 +8,7 @@ namespace Supermarket.API.Controllers { - [Route("/api/products")] - [Produces("application/json")] - [ApiController] - public class ProductsController : Controller + public class ProductsController : BaseApiController { private readonly IProductService _productService; private readonly IMapper _mapper; diff --git a/src/Supermarket.API/Persistence/Contexts/AppDbContext.cs b/src/Supermarket.API/Persistence/Contexts/AppDbContext.cs index ba119b2..ad0046c 100644 --- a/src/Supermarket.API/Persistence/Contexts/AppDbContext.cs +++ b/src/Supermarket.API/Persistence/Contexts/AppDbContext.cs @@ -1,58 +1,19 @@ +using System.Reflection; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.InMemory.ValueGeneration.Internal; using Supermarket.API.Domain.Models; namespace Supermarket.API.Persistence.Contexts { public class AppDbContext : DbContext { + public AppDbContext(DbContextOptions options) : base(options) { } public DbSet Categories { get; set; } public DbSet Products { get; set; } - public AppDbContext(DbContextOptions options) : base(options) { } - protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); - - builder.Entity().ToTable("Categories"); - builder.Entity().HasKey(p => p.Id); - builder.Entity().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd();//.HasValueGenerator>(); - builder.Entity().Property(p => p.Name).IsRequired().HasMaxLength(30); - builder.Entity().HasMany(p => p.Products).WithOne(p => p.Category).HasForeignKey(p => p.CategoryId); - - builder.Entity().HasData - ( - new Category { Id = 100, Name = "Fruits and Vegetables" }, // Id set manually due to in-memory provider - new Category { Id = 101, Name = "Dairy" } - ); - - builder.Entity().ToTable("Products"); - builder.Entity().HasKey(p => p.Id); - builder.Entity().Property(p => p.Id).IsRequired().ValueGeneratedOnAdd(); - builder.Entity().Property(p => p.Name).IsRequired().HasMaxLength(50); - builder.Entity().Property(p => p.QuantityInPackage).IsRequired(); - builder.Entity().Property(p => p.UnitOfMeasurement).IsRequired(); - - builder.Entity().HasData - ( - new Product - { - Id = 100, - Name = "Apple", - QuantityInPackage = 1, - UnitOfMeasurement = EUnitOfMeasurement.Unity, - CategoryId = 100 - }, - new Product - { - Id = 101, - Name = "Milk", - QuantityInPackage = 2, - UnitOfMeasurement = EUnitOfMeasurement.Liter, - CategoryId = 101, - } - ); + builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); } } } \ No newline at end of file diff --git a/src/Supermarket.API/Persistence/Contexts/Configurations/CategoryConfiguration.cs b/src/Supermarket.API/Persistence/Contexts/Configurations/CategoryConfiguration.cs new file mode 100644 index 0000000..f73a040 --- /dev/null +++ b/src/Supermarket.API/Persistence/Contexts/Configurations/CategoryConfiguration.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Supermarket.API.Domain.Models; + +namespace Supermarket.API.Persistence.Contexts.Configurations +{ + public class CategoryConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Categories"); + builder.HasKey(p => p.Id); + builder.Property(p => p.Id).IsRequired().ValueGeneratedOnAdd();//.HasValueGenerator>(); + builder.Property(p => p.Name).IsRequired().HasMaxLength(30); + builder.HasMany(p => p.Products).WithOne(p => p.Category).HasForeignKey(p => p.CategoryId); + } + } +} \ No newline at end of file diff --git a/src/Supermarket.API/Persistence/Contexts/Configurations/ProductConfiguration.cs b/src/Supermarket.API/Persistence/Contexts/Configurations/ProductConfiguration.cs new file mode 100644 index 0000000..5a7bc0f --- /dev/null +++ b/src/Supermarket.API/Persistence/Contexts/Configurations/ProductConfiguration.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Supermarket.API.Domain.Models; + +namespace Supermarket.API.Persistence.Contexts.Configurations +{ + public class ProductConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Products"); + builder.HasKey(p => p.Id); + builder.Property(p => p.Id).IsRequired().ValueGeneratedOnAdd(); + builder.Property(p => p.Name).IsRequired().HasMaxLength(50); + builder.Property(p => p.QuantityInPackage).IsRequired(); + builder.Property(p => p.UnitOfMeasurement).IsRequired(); + } + } +} \ No newline at end of file diff --git a/src/Supermarket.API/Persistence/Contexts/SeedData.cs b/src/Supermarket.API/Persistence/Contexts/SeedData.cs new file mode 100644 index 0000000..a7e82f8 --- /dev/null +++ b/src/Supermarket.API/Persistence/Contexts/SeedData.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Supermarket.API.Domain.Models; + +namespace Supermarket.API.Persistence.Contexts +{ + public static class SeedData + { + public static async Task Seed(AppDbContext context) + { + var products = new List + { + new Product + { + Id = 100, + Name = "Apple", + QuantityInPackage = 1, + UnitOfMeasurement = EUnitOfMeasurement.Unity, + CategoryId = 100 + }, + new Product + { + Id = 101, + Name = "Milk", + QuantityInPackage = 2, + UnitOfMeasurement = EUnitOfMeasurement.Liter, + CategoryId = 101, + } + }; + + var categories = new List + { + new Category { Id = 100, Name = "Fruits and Vegetables" }, // Id set manually due to in-memory provider + new Category { Id = 101, Name = "Dairy" } + }; + + context.Products.AddRange(products); + context.Categories.AddRange(categories); + + await context.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Supermarket.API/Program.cs b/src/Supermarket.API/Program.cs index a486c8c..5d5cd9d 100644 --- a/src/Supermarket.API/Program.cs +++ b/src/Supermarket.API/Program.cs @@ -1,6 +1,9 @@ -using Microsoft.AspNetCore.Hosting; +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; using Supermarket.API.Persistence.Contexts; namespace Supermarket.API @@ -9,17 +12,23 @@ namespace Supermarket.API #pragma warning disable CS1591 public class Program { - public static void Main(string[] args) + public static async Task Main(string[] args) { var host = CreateHostBuilder(args).Build(); - - using (var scope = host.Services.CreateScope()) - using (var context = scope.ServiceProvider.GetService()) + using var scope = host.Services.CreateScope(); + var services = scope.ServiceProvider; + try + { + var context = services.GetRequiredService(); + await SeedData.Seed(context); + } + catch (Exception ex) { - context.Database.EnsureCreated(); + var logger = services.GetRequiredService>(); + logger.LogError(ex, "An error occured during Seeding Data"); } - host.Run(); + await host.RunAsync(); } public static IHostBuilder CreateHostBuilder(string[] args) => diff --git a/src/Supermarket.API/Startup.cs b/src/Supermarket.API/Startup.cs index 78bb3c3..318e8a5 100644 --- a/src/Supermarket.API/Startup.cs +++ b/src/Supermarket.API/Startup.cs @@ -17,13 +17,10 @@ namespace Supermarket.API { public class Startup { - public IConfiguration Configuration { get; } - - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } + private readonly IConfiguration Configuration; + public Startup(IConfiguration configuration) => Configuration = configuration; + public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); diff --git a/src/Supermarket.API/Supermarket.API.csproj b/src/Supermarket.API/Supermarket.API.csproj index d463e24..85144cc 100644 --- a/src/Supermarket.API/Supermarket.API.csproj +++ b/src/Supermarket.API/Supermarket.API.csproj @@ -1,21 +1,21 @@  - netcoreapp3.1 + net5.0 - bin\Debug\netcoreapp3.1\Supermarket.API.xml - bin\Debug\netcoreapp3.1\ + bin\Debug\net5.0\Supermarket.API.xml + bin\Debug\net5.0 1701;1702;1591; - - - - - + + + + + diff --git a/src/Supermarket.API/appsettings.Development.json b/src/Supermarket.API/appsettings.Development.json index a2880cb..1730e58 100644 --- a/src/Supermarket.API/appsettings.Development.json +++ b/src/Supermarket.API/appsettings.Development.json @@ -1,9 +1,9 @@ { "Logging": { "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" + "Default": "Information", + "Microsoft": "Information", + "Microsoft.Hosting.Lifetime": "Information" } } }