diff --git a/src/GitHubActionsDemo.Api/Controllers/LibraryController.cs b/src/GitHubActionsDemo.Api/Controllers/LibraryController.cs index b9a0509..f9e1fce 100644 --- a/src/GitHubActionsDemo.Api/Controllers/LibraryController.cs +++ b/src/GitHubActionsDemo.Api/Controllers/LibraryController.cs @@ -43,7 +43,7 @@ public class LibraryController : ControllerBase } [HttpPost(Name = "AddAuthor")] - public async Task AddauthorAsync(AuthorRequest authorRequest) + public async Task AddAuthorAsync(AuthorRequest authorRequest) { var author = await _libraryService.AddAuthorAsync(authorRequest.Map()); return author.Map(); diff --git a/src/GitHubActionsDemo.Api/GitHubActionsDemo.Api.csproj b/src/GitHubActionsDemo.Api/GitHubActionsDemo.Api.csproj index c3b2f07..9a28efe 100644 --- a/src/GitHubActionsDemo.Api/GitHubActionsDemo.Api.csproj +++ b/src/GitHubActionsDemo.Api/GitHubActionsDemo.Api.csproj @@ -14,6 +14,7 @@ + diff --git a/src/GitHubActionsDemo.Api/Program.cs b/src/GitHubActionsDemo.Api/Program.cs index 0c58634..60385d4 100644 --- a/src/GitHubActionsDemo.Api/Program.cs +++ b/src/GitHubActionsDemo.Api/Program.cs @@ -1,4 +1,5 @@ -using GitHubActionsDemo.Service; +using GitHubActionsDemo.Service.Infrastructure; +using GitHubActionsDemo.Persistance.Infrastructure; var builder = WebApplication.CreateBuilder(args); @@ -6,8 +7,11 @@ builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); +builder.Services.Configure(builder.Configuration.GetSection("DbSettings")); + // DI -builder.Services.AddScoped(); +builder.Services.AddServiceDependencies(); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -17,6 +21,10 @@ if (app.Environment.IsDevelopment()) app.UseSwaggerUI(); } +{ + await app.InitDatabase(); +} + app.UseAuthorization(); app.MapControllers(); app.Run(); diff --git a/src/GitHubActionsDemo.Api/appsettings.Development.json b/src/GitHubActionsDemo.Api/appsettings.Development.json index ff66ba6..971f863 100644 --- a/src/GitHubActionsDemo.Api/appsettings.Development.json +++ b/src/GitHubActionsDemo.Api/appsettings.Development.json @@ -1,4 +1,8 @@ { + "DbSettings": { + "ConnectionString": "Server=localhost; Database=library; Uid=root; Pwd=libraryDbPassword;", + "Database": "library" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/src/GitHubActionsDemo.Api/appsettings.json b/src/GitHubActionsDemo.Api/appsettings.json index 4d56694..cb136aa 100644 --- a/src/GitHubActionsDemo.Api/appsettings.json +++ b/src/GitHubActionsDemo.Api/appsettings.json @@ -1,4 +1,8 @@ { + "DbSettings": { + "ConnectionString": "Server=localhost; Database=library; Uid=root; Pwd=libraryDbPassword;", + "Database": "library" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/src/GitHubActionsDemo.Persistance/DbContext.cs b/src/GitHubActionsDemo.Persistance/DbContext.cs new file mode 100644 index 0000000..64449a0 --- /dev/null +++ b/src/GitHubActionsDemo.Persistance/DbContext.cs @@ -0,0 +1,79 @@ +using Dapper; +using MySql.Data.MySqlClient; +using System.Data; +using GitHubActionsDemo.Persistance.Infrastructure; +using Microsoft.Extensions.Options; + +namespace GitHubActionsDemo.Persistance; + +public class DbContext : IDbContext +{ + private readonly DbSettings _dbSettings; + + public DbContext(IOptions dbSettings) + { + _dbSettings = dbSettings?.Value ?? throw new ArgumentNullException(nameof(dbSettings)); + } + + public IDbConnection CreateConnection() + { + return new MySqlConnection(_dbSettings.ConnectionString); + } + + public async Task Init() + { + await InitDatabase(); + await InitTables(); + } + + private async Task InitDatabase() + { + // create database if it doesn't exist + using var connection = new MySqlConnection(_dbSettings.ConnectionString); + var sql = $"CREATE DATABASE IF NOT EXISTS `{_dbSettings.Database}`;"; + await connection.ExecuteAsync(sql); + } + + private async Task InitTables() + { + // create tables if they don't exist + using var connection = CreateConnection(); + await _initAuthors(); + await _initBooks(); + + async Task _initAuthors() + { + var sql = """ + CREATE TABLE IF NOT EXISTS Authors ( + AuthorId INT NOT NULL AUTO_INCREMENT, + FirstName VARCHAR(255) NOT NULL, + LastName VARCHAR(255) NOT NULL, + DateCreated DATETIME NOT NULL, + DateModified DATETIME NOT NULL, + PRIMARY KEY (AuthorId) + ); + """; + await connection.ExecuteAsync(sql); + } + + async Task _initBooks() + { + var sql = """ + CREATE TABLE IF NOT EXISTS Books( + BookId INT NOT NULL AUTO_INCREMENT, + Title VARCHAR(255), + AuthorId INT NOT NULL, + Isbn VARCHAR(13) NOT NULL, + DatePublished DATETIME NOT NULL, + DateCreated DATETIME NOT NULL, + DateModified DATETIME NOT NULL, + PRIMARY KEY(BookId), + FOREIGN KEY(AuthorId) REFERENCES Authors(AuthorId) + ); + """; + await connection.ExecuteAsync(sql); + } + + + } +} diff --git a/src/GitHubActionsDemo.Persistance/GitHubActionsDemo.Persistance.csproj b/src/GitHubActionsDemo.Persistance/GitHubActionsDemo.Persistance.csproj index 360ddbe..4132621 100644 --- a/src/GitHubActionsDemo.Persistance/GitHubActionsDemo.Persistance.csproj +++ b/src/GitHubActionsDemo.Persistance/GitHubActionsDemo.Persistance.csproj @@ -7,7 +7,9 @@ - + + + diff --git a/src/GitHubActionsDemo.Persistance/IDbContext.cs b/src/GitHubActionsDemo.Persistance/IDbContext.cs new file mode 100644 index 0000000..53d26d0 --- /dev/null +++ b/src/GitHubActionsDemo.Persistance/IDbContext.cs @@ -0,0 +1,9 @@ +using System.Data; + +namespace GitHubActionsDemo.Persistance; + +public interface IDbContext +{ + IDbConnection CreateConnection(); + Task Init(); +} \ No newline at end of file diff --git a/src/GitHubActionsDemo.Persistance/Infrastructure/DbSettings.cs b/src/GitHubActionsDemo.Persistance/Infrastructure/DbSettings.cs new file mode 100644 index 0000000..5d5c779 --- /dev/null +++ b/src/GitHubActionsDemo.Persistance/Infrastructure/DbSettings.cs @@ -0,0 +1,7 @@ +namespace GitHubActionsDemo.Persistance.Infrastructure; + +public class DbSettings +{ + public string ConnectionString { get; set; } + public string Database { get; set; } +} \ No newline at end of file diff --git a/src/GitHubActionsDemo.Persistance/Infrastructure/InfrastructureExtensions.cs b/src/GitHubActionsDemo.Persistance/Infrastructure/InfrastructureExtensions.cs index 711f26c..ca31f7a 100644 --- a/src/GitHubActionsDemo.Persistance/Infrastructure/InfrastructureExtensions.cs +++ b/src/GitHubActionsDemo.Persistance/Infrastructure/InfrastructureExtensions.cs @@ -1,13 +1,20 @@ -using GitHubActionsDemo.Persistance; +using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; -namespace GitHubActionsDemo.Service.Infrastructure +namespace GitHubActionsDemo.Persistance.Infrastructure; + +public static class InfrastructureExtensions { - public static class InfrastructureExtensions + public static IServiceCollection AddPersistanceDependencies(this IServiceCollection services) { - public static IServiceCollection AddPersistanceDependencies(this IServiceCollection services) - { - return services.AddSingleton(); - } + return services.AddSingleton() + .AddScoped(); } -} \ No newline at end of file + + public static async Task InitDatabase(this WebApplication app) + { + using var scope = app.Services.CreateScope(); + var context = scope.ServiceProvider.GetRequiredService(); + await context.Init(); + } +} diff --git a/src/GitHubActionsDemo.Service/Infrastructure/InfrastructureExtensions.cs b/src/GitHubActionsDemo.Service/Infrastructure/InfrastructureExtensions.cs index f928db3..71e1bc8 100644 --- a/src/GitHubActionsDemo.Service/Infrastructure/InfrastructureExtensions.cs +++ b/src/GitHubActionsDemo.Service/Infrastructure/InfrastructureExtensions.cs @@ -1,4 +1,4 @@ -using GitHubActionsDemo.Persistance; +using GitHubActionsDemo.Persistance.Infrastructure; using Microsoft.Extensions.DependencyInjection; namespace GitHubActionsDemo.Service.Infrastructure @@ -8,8 +8,8 @@ namespace GitHubActionsDemo.Service.Infrastructure public static IServiceCollection AddServiceDependencies(this IServiceCollection services) { return services - .AddScoped() - .AddPersistanceDependencies(); + .AddPersistanceDependencies() + .AddScoped(); } } } \ No newline at end of file diff --git a/src/GitHubActionsDemo.Service/LibraryService.cs b/src/GitHubActionsDemo.Service/LibraryService.cs index 47e7283..1bff707 100644 --- a/src/GitHubActionsDemo.Service/LibraryService.cs +++ b/src/GitHubActionsDemo.Service/LibraryService.cs @@ -34,6 +34,6 @@ public class LibraryService : ILibraryService public async Task> GetBooksAsync(int page, int pageSize) { var books = await _libraryRepository.GetBooksAsync(page, pageSize); - return books.Select(book => book.Map()); + return books?.Select(book => book.Map()) ?? new List(); } } \ No newline at end of file