Repository: CodeMazeBlog/.NET-Core-Series Branch: master Commit: 929da1e94d61 Files: 115 Total size: 75.7 KB Directory structure: gitextract_2hk3m77t/ ├── .gitignore ├── Part 1/ │ ├── Schema.mwb │ ├── Schema.mwb.bak │ └── init.sql ├── Part 2/ │ └── AccountOwnerServer/ │ ├── AccountOwnerServer/ │ │ ├── AccountOwnerServer.csproj │ │ ├── Controllers/ │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions/ │ │ │ └── ServiceExtensions.cs │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── AccountOwnerServer.sln ├── Part 3/ │ └── AccountOwnerServer/ │ ├── AccountOwnerServer/ │ │ ├── AccountOwnerServer.csproj │ │ ├── Controllers/ │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions/ │ │ │ └── ServiceExtensions.cs │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── nlog.config │ ├── AccountOwnerServer.sln │ ├── Contracts/ │ │ ├── Contracts.csproj │ │ └── ILoggerManager.cs │ └── LoggerService/ │ ├── LoggerManager.cs │ └── LoggerService.csproj ├── Part 4/ │ └── AccountOwnerServer/ │ ├── AccountOwnerServer/ │ │ ├── AccountOwnerServer.csproj │ │ ├── Controllers/ │ │ │ └── WeatherForecastController.cs │ │ ├── Extensions/ │ │ │ └── ServiceExtensions.cs │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── WeatherForecast.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── nlog.config │ ├── AccountOwnerServer.sln │ ├── Contracts/ │ │ ├── Contracts.csproj │ │ ├── IAccountRepository.cs │ │ ├── ILoggerManager.cs │ │ ├── IOwnerRepository.cs │ │ ├── IRepositoryBase.cs │ │ └── IRepositoryWrapper.cs │ ├── Entities/ │ │ ├── Entities.csproj │ │ ├── Models/ │ │ │ ├── Account.cs │ │ │ └── Owner.cs │ │ └── RepositoryContext.cs │ ├── LoggerService/ │ │ ├── LoggerManager.cs │ │ └── LoggerService.csproj │ └── Repository/ │ ├── AccountRepository.cs │ ├── OwnerRepository.cs │ ├── Repository.csproj │ ├── RepositoryBase.cs │ └── RepositoryWrapper.cs ├── Part 5/ │ └── AccountOwnerServer/ │ ├── AccountOwnerServer/ │ │ ├── AccountOwnerServer.csproj │ │ ├── Controllers/ │ │ │ └── OwnerController.cs │ │ ├── Extensions/ │ │ │ └── ServiceExtensions.cs │ │ ├── MappingProfile.cs │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── nlog.config │ ├── AccountOwnerServer.sln │ ├── Contracts/ │ │ ├── Contracts.csproj │ │ ├── IAccountRepository.cs │ │ ├── ILoggerManager.cs │ │ ├── IOwnerRepository.cs │ │ ├── IRepositoryBase.cs │ │ └── IRepositoryWrapper.cs │ ├── Entities/ │ │ ├── DataTransferObjects/ │ │ │ ├── AccountDto.cs │ │ │ └── OwnerDto.cs │ │ ├── Entities.csproj │ │ ├── Models/ │ │ │ ├── Account.cs │ │ │ └── Owner.cs │ │ └── RepositoryContext.cs │ ├── LoggerService/ │ │ ├── LoggerManager.cs │ │ └── LoggerService.csproj │ └── Repository/ │ ├── AccountRepository.cs │ ├── OwnerRepository.cs │ ├── Repository.csproj │ ├── RepositoryBase.cs │ └── RepositoryWrapper.cs ├── Part 6/ │ └── AccountOwnerServer/ │ ├── AccountOwnerServer/ │ │ ├── AccountOwnerServer.csproj │ │ ├── Controllers/ │ │ │ └── OwnerController.cs │ │ ├── Extensions/ │ │ │ └── ServiceExtensions.cs │ │ ├── MappingProfile.cs │ │ ├── Program.cs │ │ ├── Properties/ │ │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── nlog.config │ ├── AccountOwnerServer.sln │ ├── Contracts/ │ │ ├── Contracts.csproj │ │ ├── IAccountRepository.cs │ │ ├── ILoggerManager.cs │ │ ├── IOwnerRepository.cs │ │ ├── IRepositoryBase.cs │ │ └── IRepositoryWrapper.cs │ ├── Entities/ │ │ ├── DataTransferObjects/ │ │ │ ├── AccountDto.cs │ │ │ ├── OwnerDto.cs │ │ │ ├── OwnerForCreationDto.cs │ │ │ └── OwnerForUpdateDto.cs │ │ ├── Entities.csproj │ │ ├── Models/ │ │ │ ├── Account.cs │ │ │ └── Owner.cs │ │ └── RepositoryContext.cs │ ├── LoggerService/ │ │ ├── LoggerManager.cs │ │ └── LoggerService.csproj │ └── Repository/ │ ├── AccountRepository.cs │ ├── OwnerRepository.cs │ ├── Repository.csproj │ ├── RepositoryBase.cs │ └── RepositoryWrapper.cs └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ /Part 3/.vs /Part 3/AccountOwnerServer/obj /Part 3/AccountOwnerServer/AccountOwnerServer.csproj.user /Part 3/AccountOwnerServer/bin /Part 3/Contracts/obj /Part 3/Contracts/bin /Part 3/LoggerService/obj /Part 3/LoggerService/bin *.suo *.user _ReSharper.* bin obj packages /Part 4/Contracts/obj /Part 4/Contracts/bin /Part 4/Entities/obj /Part 4/Entities/bin /Part 4/LoggerService/obj /Part 4/LoggerService/bin /Part 4/Repository/obj /Part 4/Repository/bin /Part7/.vscode Projects /Part 3/AccountOwnerServer/Projects /Part 5/AccountOwnerServer/Projects /Part 4/AccountOwnerServer/Projects /Part 6/AccountOwnerServer/Projects /Part 5 - Update - OwnersByName/.vs /Part 4/.vs /Part 5/.vs /Part 2/AccountOwnerServer/.vs /Part 6/.vs /Part 16/.NET Core part - end/.vs /Part 17/.NET Core part - end/.vs ================================================ FILE: Part 1/init.sql ================================================ -- MySQL Script generated by MySQL Workbench -- Wed Jan 22 11:12:09 2025 -- Model: New Model Version: 1.0 -- MySQL Workbench Forward Engineering SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; -- ----------------------------------------------------- -- Schema AccountOwner -- ----------------------------------------------------- -- ----------------------------------------------------- -- Schema AccountOwner -- ----------------------------------------------------- CREATE SCHEMA IF NOT EXISTS `AccountOwner` DEFAULT CHARACTER SET utf8 ; USE `AccountOwner` ; -- ----------------------------------------------------- -- Table `AccountOwner`.`Owner` -- ----------------------------------------------------- DROP TABLE IF EXISTS `AccountOwner`.`Owner` ; CREATE TABLE IF NOT EXISTS `AccountOwner`.`Owner` ( `OwnerId` CHAR(36) NOT NULL, `Name` NVARCHAR(60) NOT NULL, `DateOfBirth` DATE NOT NULL, `Address` NVARCHAR(100) NOT NULL, PRIMARY KEY (`OwnerId`)) ENGINE = InnoDB; -- ----------------------------------------------------- -- Table `AccountOwner`.`Account` -- ----------------------------------------------------- DROP TABLE IF EXISTS `AccountOwner`.`Account` ; CREATE TABLE IF NOT EXISTS `AccountOwner`.`Account` ( `AccountID` CHAR(36) NOT NULL, `DateCreated` DATE NOT NULL, `AccountType` NVARCHAR(45) NOT NULL, `OwnerId` CHAR(36) NOT NULL, PRIMARY KEY (`AccountID`), INDEX `fk_Account_Owner_idx` (`OwnerId` ASC) VISIBLE, CONSTRAINT `fk_Account_Owner` FOREIGN KEY (`OwnerId`) REFERENCES `AccountOwner`.`Owner` (`OwnerId`) ON DELETE RESTRICT ON UPDATE CASCADE) ENGINE = InnoDB; SET SQL_MODE=@OLD_SQL_MODE; SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/AccountOwnerServer.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/Controllers/WeatherForecastController.cs ================================================ using Microsoft.AspNetCore.Mvc; namespace AccountOwnerServer.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; private readonly ILogger _logger; public WeatherForecastController(ILogger logger) { _logger = logger; } [HttpGet] public IEnumerable Get() { return Enumerable.Range(1, 5).Select(index => new WeatherForecast { Date = DateTime.Now.AddDays(index), TemperatureC = Random.Shared.Next(-20, 55), Summary = Summaries[Random.Shared.Next(Summaries.Length)] }) .ToArray(); } } } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/Extensions/ServiceExtensions.cs ================================================ namespace AccountOwnerServer.Extensions { public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public static void ConfigureIISIntegration(this IServiceCollection services) { services.Configure(options => { }); } } } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/Program.cs ================================================ using AccountOwnerServer.Extensions; using Microsoft.AspNetCore.HttpOverrides; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.ConfigureCors(); builder.Services.ConfigureIISIntegration(); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.MapControllers(); app.Run(); ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/Properties/launchSettings.json ================================================ { "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:40700", "sslPort": 44360 } }, "profiles": { "AccountOwnerServer": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": false, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/WeatherForecast.cs ================================================ namespace AccountOwnerServer { public class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); public string? Summary { get; set; } } } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/appsettings.Development.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" } ================================================ FILE: Part 2/AccountOwnerServer/AccountOwnerServer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccountOwnerServer", "AccountOwnerServer\AccountOwnerServer.csproj", "{0213FB50-5C53-4C34-8B2C-E515C7DC2579}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.Build.0 = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.ActiveCfg = Release|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F8E1F895-37AB-455B-8D05-ED495BE48F88} EndGlobalSection EndGlobal ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/AccountOwnerServer.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/Controllers/WeatherForecastController.cs ================================================ using Contracts; using Microsoft.AspNetCore.Mvc; namespace AccountOwnerServer.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILoggerManager _logger; public WeatherForecastController(ILoggerManager logger) { _logger = logger; } [HttpGet] public IEnumerable Get() { _logger.LogInfo("Here is info message from the controller."); _logger.LogDebug("Here is debug message from the controller."); _logger.LogWarn("Here is warn message from the controller."); _logger.LogError("Here is error message from the controller."); return new string[] { "value1", "value2" }; } } } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/Extensions/ServiceExtensions.cs ================================================ using Contracts; using LoggerService; namespace AccountOwnerServer.Extensions { public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public static void ConfigureIISIntegration(this IServiceCollection services) { services.Configure(options => { }); } public static void ConfigureLoggerService(this IServiceCollection services) { services.AddSingleton(); } } } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/Program.cs ================================================ using AccountOwnerServer.Extensions; using Microsoft.AspNetCore.HttpOverrides; using NLog; var builder = WebApplication.CreateBuilder(args); LogManager.Setup().LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/nlog.config")); builder.Services.ConfigureCors(); builder.Services.ConfigureIISIntegration(); builder.Services.ConfigureLoggerService(); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.MapControllers(); app.Run(); ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/Properties/launchSettings.json ================================================ { "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:40700", "sslPort": 44360 } }, "profiles": { "AccountOwnerServer": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": false, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/WeatherForecast.cs ================================================ namespace AccountOwnerServer { public class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); public string? Summary { get; set; } } } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/appsettings.Development.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" } ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer/nlog.config ================================================  ================================================ FILE: Part 3/AccountOwnerServer/AccountOwnerServer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccountOwnerServer", "AccountOwnerServer\AccountOwnerServer.csproj", "{0213FB50-5C53-4C34-8B2C-E515C7DC2579}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "Contracts\Contracts.csproj", "{B731D3C2-9A89-40E4-B96B-AA300B4195BB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerService", "LoggerService\LoggerService.csproj", "{7CEC76F5-80AF-4B37-B6F1-94A743E5C748}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.Build.0 = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.ActiveCfg = Release|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.Build.0 = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.Build.0 = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F8E1F895-37AB-455B-8D05-ED495BE48F88} EndGlobalSection EndGlobal ================================================ FILE: Part 3/AccountOwnerServer/Contracts/Contracts.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 3/AccountOwnerServer/Contracts/ILoggerManager.cs ================================================ namespace Contracts { public interface ILoggerManager { void LogInfo(string message); void LogWarn(string message); void LogDebug(string message); void LogError(string message); } } ================================================ FILE: Part 3/AccountOwnerServer/LoggerService/LoggerManager.cs ================================================ using Contracts; using NLog; namespace LoggerService { public class LoggerManager : ILoggerManager { private static ILogger logger = LogManager.GetCurrentClassLogger(); public void LogDebug(string message) => logger.Debug(message); public void LogError(string message) => logger.Error(message); public void LogInfo(string message) => logger.Info(message); public void LogWarn(string message) => logger.Warn(message); } } ================================================ FILE: Part 3/AccountOwnerServer/LoggerService/LoggerService.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/AccountOwnerServer.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/Controllers/WeatherForecastController.cs ================================================ using Contracts; using Microsoft.AspNetCore.Mvc; namespace AccountOwnerServer.Controllers { [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private IRepositoryWrapper _repository; public WeatherForecastController(IRepositoryWrapper repository) { _repository = repository; } [HttpGet] public IEnumerable Get() { var domesticAccounts = _repository.Account.FindByCondition(x => x.AccountType.Equals("Domestic")); var owners = _repository.Owner.FindAll(); return new string[] { "value1", "value2" }; } } } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/Extensions/ServiceExtensions.cs ================================================ using Contracts; using LoggerService; using Microsoft.EntityFrameworkCore; using Entities; using Repository; namespace AccountOwnerServer.Extensions { public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public static void ConfigureIISIntegration(this IServiceCollection services) { services.Configure(options => { }); } public static void ConfigureLoggerService(this IServiceCollection services) { services.AddSingleton(); } public static void ConfigureMySqlContext(this IServiceCollection services, IConfiguration config) { var connectionString = config["mysqlconnection:connectionString"]; services.AddDbContext(o => o.UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion)); } public static void ConfigureRepositoryWrapper(this IServiceCollection services) { services.AddScoped(); } } } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/Program.cs ================================================ using AccountOwnerServer.Extensions; using Microsoft.AspNetCore.HttpOverrides; using NLog; var builder = WebApplication.CreateBuilder(args); LogManager.Setup().LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/nlog.config")); builder.Services.ConfigureCors(); builder.Services.ConfigureIISIntegration(); builder.Services.ConfigureLoggerService(); builder.Services.ConfigureMySqlContext(builder.Configuration); builder.Services.ConfigureRepositoryWrapper(); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.MapControllers(); app.Run(); ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/Properties/launchSettings.json ================================================ { "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:40700", "sslPort": 44360 } }, "profiles": { "AccountOwnerServer": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": false, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/WeatherForecast.cs ================================================ namespace AccountOwnerServer { public class WeatherForecast { public DateTime Date { get; set; } public int TemperatureC { get; set; } public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); public string? Summary { get; set; } } } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/appsettings.Development.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "mysqlconnection": { "connectionString": "server=localhost;userid=root;password=yourpass;database=accountowner;" }, "AllowedHosts": "*" } ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer/nlog.config ================================================  ================================================ FILE: Part 4/AccountOwnerServer/AccountOwnerServer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccountOwnerServer", "AccountOwnerServer\AccountOwnerServer.csproj", "{0213FB50-5C53-4C34-8B2C-E515C7DC2579}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{B731D3C2-9A89-40E4-B96B-AA300B4195BB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerService", "LoggerService\LoggerService.csproj", "{7CEC76F5-80AF-4B37-B6F1-94A743E5C748}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entities", "Entities\Entities.csproj", "{16AAE663-A20E-493D-9087-F4F4016F6216}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repository", "Repository\Repository.csproj", "{A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.Build.0 = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.ActiveCfg = Release|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.Build.0 = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.Build.0 = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.Build.0 = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.Build.0 = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.ActiveCfg = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.Build.0 = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F8E1F895-37AB-455B-8D05-ED495BE48F88} EndGlobalSection EndGlobal ================================================ FILE: Part 4/AccountOwnerServer/Contracts/Contracts.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/Contracts/IAccountRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IAccountRepository : IRepositoryBase { } } ================================================ FILE: Part 4/AccountOwnerServer/Contracts/ILoggerManager.cs ================================================ namespace Contracts { public interface ILoggerManager { void LogInfo(string message); void LogWarn(string message); void LogDebug(string message); void LogError(string message); } } ================================================ FILE: Part 4/AccountOwnerServer/Contracts/IOwnerRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IOwnerRepository : IRepositoryBase { } } ================================================ FILE: Part 4/AccountOwnerServer/Contracts/IRepositoryBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; namespace Contracts { public interface IRepositoryBase { IQueryable FindAll(); IQueryable FindByCondition(Expression> expression); void Create(T entity); void Update(T entity); void Delete(T entity); } } ================================================ FILE: Part 4/AccountOwnerServer/Contracts/IRepositoryWrapper.cs ================================================ using System; using System.Collections.Generic; using System.Text; namespace Contracts { public interface IRepositoryWrapper { IOwnerRepository Owner { get; } IAccountRepository Account { get; } void Save(); } } ================================================ FILE: Part 4/AccountOwnerServer/Entities/Entities.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/Entities/Models/Account.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("account")] public class Account { public Guid AccountId { get; set; } [Required(ErrorMessage = "Date created is required")] public DateTime DateCreated { get; set; } [Required(ErrorMessage = "Account type is required")] public string? AccountType { get; set; } [ForeignKey(nameof(Owner))] public Guid OwnerId { get; set; } public Owner? Owner { get; set; } } } ================================================ FILE: Part 4/AccountOwnerServer/Entities/Models/Owner.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("owner")] public class Owner { public Guid OwnerId { get; set; } [Required(ErrorMessage = "Name is required")] [StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")] public string? Name { get; set; } [Required(ErrorMessage = "Date of birth is required")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Address is required")] [StringLength(100, ErrorMessage = "Address cannot be loner then 100 characters")] public string? Address { get; set; } public ICollection? Accounts { get; set; } } } ================================================ FILE: Part 4/AccountOwnerServer/Entities/RepositoryContext.cs ================================================ using Entities.Models; using Microsoft.EntityFrameworkCore; namespace Entities { public class RepositoryContext : DbContext { public RepositoryContext(DbContextOptions options) : base(options) { } public DbSet? Owners { get; set; } public DbSet? Accounts { get; set; } } } ================================================ FILE: Part 4/AccountOwnerServer/LoggerService/LoggerManager.cs ================================================ using Contracts; using NLog; namespace LoggerService { public class LoggerManager : ILoggerManager { private static ILogger logger = LogManager.GetCurrentClassLogger(); public void LogDebug(string message) => logger.Debug(message); public void LogError(string message) => logger.Error(message); public void LogInfo(string message) => logger.Info(message); public void LogWarn(string message) => logger.Warn(message); } } ================================================ FILE: Part 4/AccountOwnerServer/LoggerService/LoggerService.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/Repository/AccountRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; namespace Repository { public class AccountRepository : RepositoryBase, IAccountRepository { public AccountRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } } } ================================================ FILE: Part 4/AccountOwnerServer/Repository/OwnerRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; namespace Repository { public class OwnerRepository : RepositoryBase, IOwnerRepository { public OwnerRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } } } ================================================ FILE: Part 4/AccountOwnerServer/Repository/Repository.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 4/AccountOwnerServer/Repository/RepositoryBase.cs ================================================ using Contracts; using Entities; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; namespace Repository { public abstract class RepositoryBase : IRepositoryBase where T : class { protected RepositoryContext RepositoryContext { get; set; } public RepositoryBase(RepositoryContext repositoryContext) { RepositoryContext = repositoryContext; } public IQueryable FindAll() => RepositoryContext.Set().AsNoTracking(); public IQueryable FindByCondition(Expression> expression) => RepositoryContext.Set().Where(expression).AsNoTracking(); public void Create(T entity) => RepositoryContext.Set().Add(entity); public void Update(T entity) => RepositoryContext.Set().Update(entity); public void Delete(T entity) => RepositoryContext.Set().Remove(entity); } } ================================================ FILE: Part 4/AccountOwnerServer/Repository/RepositoryWrapper.cs ================================================ using Contracts; using Entities; namespace Repository { public class RepositoryWrapper : IRepositoryWrapper { private RepositoryContext _repoContext; private IOwnerRepository _owner; private IAccountRepository _account; public IOwnerRepository Owner { get { if (_owner == null) { _owner = new OwnerRepository(_repoContext); } return _owner; } } public IAccountRepository Account { get { if (_account == null) { _account = new AccountRepository(_repoContext); } return _account; } } public RepositoryWrapper(RepositoryContext repositoryContext) { _repoContext = repositoryContext; } public void Save() { _repoContext.SaveChanges(); } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/AccountOwnerServer.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/Controllers/OwnerController.cs ================================================ using AutoMapper; using Contracts; using Entities.DataTransferObjects; using Microsoft.AspNetCore.Mvc; namespace AccountOwnerServer.Controllers { [Route("api/owner")] [ApiController] public class OwnerController : ControllerBase { private ILoggerManager _logger; private IRepositoryWrapper _repository; private IMapper _mapper; public OwnerController(ILoggerManager logger, IRepositoryWrapper repository, IMapper mapper) { _logger = logger; _repository = repository; _mapper = mapper; } [HttpGet] public IActionResult GetAllOwners() { try { var owners = _repository.Owner.GetAllOwners(); _logger.LogInfo($"Returned all owners from database."); var ownersResult = _mapper.Map>(owners); return Ok(ownersResult); } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetAllOwners action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpGet("{id}")] public IActionResult GetOwnerById(Guid id) { try { var owner = _repository.Owner.GetOwnerById(id); if (owner is null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } else { _logger.LogInfo($"Returned owner with id: {id}"); var ownerResult = _mapper.Map(owner); return Ok(ownerResult); } } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetOwnerById action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpGet("{id}/account")] public IActionResult GetOwnerWithDetails(Guid id) { try { var owner = _repository.Owner.GetOwnerWithDetails(id); if (owner == null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } else { _logger.LogInfo($"Returned owner with details for id: {id}"); var ownerResult = _mapper.Map(owner); return Ok(ownerResult); } } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetOwnerWithDetails action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/Extensions/ServiceExtensions.cs ================================================ using Contracts; using LoggerService; using Microsoft.EntityFrameworkCore; using Entities; using Repository; namespace AccountOwnerServer.Extensions { public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public static void ConfigureIISIntegration(this IServiceCollection services) { services.Configure(options => { }); } public static void ConfigureLoggerService(this IServiceCollection services) { services.AddSingleton(); } public static void ConfigureMySqlContext(this IServiceCollection services, IConfiguration config) { var connectionString = config["mysqlconnection:connectionString"]; services.AddDbContext(o => o.UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion)); } public static void ConfigureRepositoryWrapper(this IServiceCollection services) { services.AddScoped(); } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/MappingProfile.cs ================================================ using AutoMapper; using Entities.DataTransferObjects; using Entities.Models; using System.Linq; namespace AccountOwnerServer { public class MappingProfile : Profile { public MappingProfile() { CreateMap(); CreateMap(); } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/Program.cs ================================================ using AccountOwnerServer.Extensions; using Microsoft.AspNetCore.HttpOverrides; using NLog; var builder = WebApplication.CreateBuilder(args); LogManager.Setup().LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/nlog.config")); builder.Services.ConfigureCors(); builder.Services.ConfigureIISIntegration(); builder.Services.ConfigureLoggerService(); builder.Services.ConfigureMySqlContext(builder.Configuration); builder.Services.ConfigureRepositoryWrapper(); builder.Services.AddAutoMapper(typeof(Program)); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.MapControllers(); app.Run(); ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/Properties/launchSettings.json ================================================ { "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:40700", "sslPort": 44360 } }, "profiles": { "AccountOwnerServer": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": false, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/appsettings.Development.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "mysqlconnection": { "connectionString": "server=localhost;userid=root;password=yourpass;database=accountowner;" }, "AllowedHosts": "*" } ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer/nlog.config ================================================  ================================================ FILE: Part 5/AccountOwnerServer/AccountOwnerServer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccountOwnerServer", "AccountOwnerServer\AccountOwnerServer.csproj", "{0213FB50-5C53-4C34-8B2C-E515C7DC2579}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{B731D3C2-9A89-40E4-B96B-AA300B4195BB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerService", "LoggerService\LoggerService.csproj", "{7CEC76F5-80AF-4B37-B6F1-94A743E5C748}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entities", "Entities\Entities.csproj", "{16AAE663-A20E-493D-9087-F4F4016F6216}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repository", "Repository\Repository.csproj", "{A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.Build.0 = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.ActiveCfg = Release|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.Build.0 = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.Build.0 = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.Build.0 = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.Build.0 = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.ActiveCfg = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.Build.0 = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F8E1F895-37AB-455B-8D05-ED495BE48F88} EndGlobalSection EndGlobal ================================================ FILE: Part 5/AccountOwnerServer/Contracts/Contracts.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 5/AccountOwnerServer/Contracts/IAccountRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IAccountRepository { } } ================================================ FILE: Part 5/AccountOwnerServer/Contracts/ILoggerManager.cs ================================================ namespace Contracts { public interface ILoggerManager { void LogInfo(string message); void LogWarn(string message); void LogDebug(string message); void LogError(string message); } } ================================================ FILE: Part 5/AccountOwnerServer/Contracts/IOwnerRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IOwnerRepository { IEnumerable GetAllOwners(); Owner GetOwnerById(Guid ownerId); Owner GetOwnerWithDetails(Guid ownerId); } } ================================================ FILE: Part 5/AccountOwnerServer/Contracts/IRepositoryBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; namespace Contracts { public interface IRepositoryBase { IQueryable FindAll(); IQueryable FindByCondition(Expression> expression); void Create(T entity); void Update(T entity); void Delete(T entity); } } ================================================ FILE: Part 5/AccountOwnerServer/Contracts/IRepositoryWrapper.cs ================================================ using System; using System.Collections.Generic; using System.Text; namespace Contracts { public interface IRepositoryWrapper { IOwnerRepository Owner { get; } IAccountRepository Account { get; } void Save(); } } ================================================ FILE: Part 5/AccountOwnerServer/Entities/DataTransferObjects/AccountDto.cs ================================================ using System; namespace Entities.DataTransferObjects { public class AccountDto { public Guid Id { get; set; } public DateTime DateCreated { get; set; } public string? AccountType { get; set; } } } ================================================ FILE: Part 5/AccountOwnerServer/Entities/DataTransferObjects/OwnerDto.cs ================================================ namespace Entities.DataTransferObjects { public class OwnerDto { public Guid Id { get; set; } public string? Name { get; set; } public DateTime DateOfBirth { get; set; } public string? Address { get; set; } public IEnumerable? Accounts { get; set; } } } ================================================ FILE: Part 5/AccountOwnerServer/Entities/Entities.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 5/AccountOwnerServer/Entities/Models/Account.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("account")] public class Account { [Column("AccountId")] public Guid Id { get; set; } [Required(ErrorMessage = "Date created is required")] public DateTime DateCreated { get; set; } [Required(ErrorMessage = "Account type is required")] public string? AccountType { get; set; } [ForeignKey(nameof(Owner))] public Guid OwnerId { get; set; } public Owner? Owner { get; set; } } } ================================================ FILE: Part 5/AccountOwnerServer/Entities/Models/Owner.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("owner")] public class Owner { [Column("OwnerId")] public Guid Id { get; set; } [Required(ErrorMessage = "Name is required")] [StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")] public string? Name { get; set; } [Required(ErrorMessage = "Date of birth is required")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Address is required")] [StringLength(100, ErrorMessage = "Address cannot be loner then 100 characters")] public string? Address { get; set; } public ICollection? Accounts { get; set; } } } ================================================ FILE: Part 5/AccountOwnerServer/Entities/RepositoryContext.cs ================================================ using Entities.Models; using Microsoft.EntityFrameworkCore; namespace Entities { public class RepositoryContext : DbContext { public RepositoryContext(DbContextOptions options) : base(options) { } public DbSet? Owners { get; set; } public DbSet? Accounts { get; set; } } } ================================================ FILE: Part 5/AccountOwnerServer/LoggerService/LoggerManager.cs ================================================ using Contracts; using NLog; namespace LoggerService { public class LoggerManager : ILoggerManager { private static ILogger logger = LogManager.GetCurrentClassLogger(); public void LogDebug(string message) => logger.Debug(message); public void LogError(string message) => logger.Error(message); public void LogInfo(string message) => logger.Info(message); public void LogWarn(string message) => logger.Warn(message); } } ================================================ FILE: Part 5/AccountOwnerServer/LoggerService/LoggerService.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 5/AccountOwnerServer/Repository/AccountRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; namespace Repository { public class AccountRepository : RepositoryBase, IAccountRepository { public AccountRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } } } ================================================ FILE: Part 5/AccountOwnerServer/Repository/OwnerRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; using Microsoft.EntityFrameworkCore; namespace Repository { public class OwnerRepository : RepositoryBase, IOwnerRepository { public OwnerRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } public IEnumerable GetAllOwners() { return FindAll() .OrderBy(ow => ow.Name) .ToList(); } public Owner GetOwnerById(Guid ownerId) { return FindByCondition(owner => owner.Id.Equals(ownerId)) .FirstOrDefault(); } public Owner GetOwnerWithDetails(Guid ownerId) { return FindByCondition(owner => owner.Id.Equals(ownerId)) .Include(ac => ac.Accounts) .FirstOrDefault(); } } } ================================================ FILE: Part 5/AccountOwnerServer/Repository/Repository.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 5/AccountOwnerServer/Repository/RepositoryBase.cs ================================================ using Contracts; using Entities; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; namespace Repository { public abstract class RepositoryBase : IRepositoryBase where T : class { protected RepositoryContext RepositoryContext { get; set; } public RepositoryBase(RepositoryContext repositoryContext) { RepositoryContext = repositoryContext; } public IQueryable FindAll() => RepositoryContext.Set().AsNoTracking(); public IQueryable FindByCondition(Expression> expression) => RepositoryContext.Set().Where(expression).AsNoTracking(); public void Create(T entity) => RepositoryContext.Set().Add(entity); public void Update(T entity) => RepositoryContext.Set().Update(entity); public void Delete(T entity) => RepositoryContext.Set().Remove(entity); } } ================================================ FILE: Part 5/AccountOwnerServer/Repository/RepositoryWrapper.cs ================================================ using Contracts; using Entities; namespace Repository { public class RepositoryWrapper : IRepositoryWrapper { private RepositoryContext _repoContext; private IOwnerRepository _owner; private IAccountRepository _account; public IOwnerRepository Owner { get { if (_owner == null) { _owner = new OwnerRepository(_repoContext); } return _owner; } } public IAccountRepository Account { get { if (_account == null) { _account = new AccountRepository(_repoContext); } return _account; } } public RepositoryWrapper(RepositoryContext repositoryContext) { _repoContext = repositoryContext; } public void Save() { _repoContext.SaveChanges(); } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/AccountOwnerServer.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/Controllers/OwnerController.cs ================================================ using AutoMapper; using Contracts; using Entities.DataTransferObjects; using Entities.Models; using Microsoft.AspNetCore.Mvc; namespace AccountOwnerServer.Controllers { [Route("api/owner")] [ApiController] public class OwnerController : ControllerBase { private ILoggerManager _logger; private IRepositoryWrapper _repository; private IMapper _mapper; public OwnerController(ILoggerManager logger, IRepositoryWrapper repository, IMapper mapper) { _logger = logger; _repository = repository; _mapper = mapper; } [HttpGet] public IActionResult GetAllOwners() { try { var owners = _repository.Owner.GetAllOwners(); _logger.LogInfo($"Returned all owners from database."); var ownersResult = _mapper.Map>(owners); return Ok(ownersResult); } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetAllOwners action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpGet("{id}", Name = "OwnerById")] public IActionResult GetOwnerById(Guid id) { try { var owner = _repository.Owner.GetOwnerById(id); if (owner is null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } else { _logger.LogInfo($"Returned owner with id: {id}"); var ownerResult = _mapper.Map(owner); return Ok(ownerResult); } } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetOwnerById action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpGet("{id}/account")] public IActionResult GetOwnerWithDetails(Guid id) { try { var owner = _repository.Owner.GetOwnerWithDetails(id); if (owner == null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } else { _logger.LogInfo($"Returned owner with details for id: {id}"); var ownerResult = _mapper.Map(owner); return Ok(ownerResult); } } catch (Exception ex) { _logger.LogError($"Something went wrong inside GetOwnerWithDetails action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpPost] public IActionResult CreateOwner([FromBody] OwnerForCreationDto owner) { try { if (owner is null) { _logger.LogError("Owner object sent from client is null."); return BadRequest("Owner object is null"); } if (!ModelState.IsValid) { _logger.LogError("Invalid owner object sent from client."); return BadRequest("Invalid model object"); } var ownerEntity = _mapper.Map(owner); _repository.Owner.CreateOwner(ownerEntity); _repository.Save(); var createdOwner = _mapper.Map(ownerEntity); return CreatedAtRoute("OwnerById", new { id = createdOwner.Id }, createdOwner); } catch (Exception ex) { _logger.LogError($"Something went wrong inside CreateOwner action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpPut("{id}")] public IActionResult UpdateOwner(Guid id, [FromBody] OwnerForUpdateDto owner) { try { if (owner is null) { _logger.LogError("Owner object sent from client is null."); return BadRequest("Owner object is null"); } if (!ModelState.IsValid) { _logger.LogError("Invalid owner object sent from client."); return BadRequest("Invalid model object"); } var ownerEntity = _repository.Owner.GetOwnerById(id); if (ownerEntity is null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } _mapper.Map(owner, ownerEntity); _repository.Owner.UpdateOwner(ownerEntity); _repository.Save(); return NoContent(); } catch (Exception ex) { _logger.LogError($"Something went wrong inside UpdateOwner action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } [HttpDelete("{id}")] public IActionResult DeleteOwner(Guid id) { try { var owner = _repository.Owner.GetOwnerById(id); if (owner == null) { _logger.LogError($"Owner with id: {id}, hasn't been found in db."); return NotFound(); } if (_repository.Account.AccountsByOwner(id).Any()) { _logger.LogError($"Cannot delete owner with id: {id}. It has related accounts. Delete those accounts first"); return BadRequest("Cannot delete owner. It has related accounts. Delete those accounts first"); } _repository.Owner.DeleteOwner(owner); _repository.Save(); return NoContent(); } catch (Exception ex) { _logger.LogError($"Something went wrong inside DeleteOwner action: {ex.Message}"); return StatusCode(500, "Internal server error"); } } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/Extensions/ServiceExtensions.cs ================================================ using Contracts; using LoggerService; using Microsoft.EntityFrameworkCore; using Entities; using Repository; namespace AccountOwnerServer.Extensions { public static class ServiceExtensions { public static void ConfigureCors(this IServiceCollection services) { services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public static void ConfigureIISIntegration(this IServiceCollection services) { services.Configure(options => { }); } public static void ConfigureLoggerService(this IServiceCollection services) { services.AddSingleton(); } public static void ConfigureMySqlContext(this IServiceCollection services, IConfiguration config) { var connectionString = config["mysqlconnection:connectionString"]; services.AddDbContext(o => o.UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion)); } public static void ConfigureRepositoryWrapper(this IServiceCollection services) { services.AddScoped(); } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/MappingProfile.cs ================================================ using AutoMapper; using Entities.DataTransferObjects; using Entities.Models; using System.Linq; namespace AccountOwnerServer { public class MappingProfile : Profile { public MappingProfile() { CreateMap(); CreateMap(); CreateMap(); CreateMap(); } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/Program.cs ================================================ using AccountOwnerServer.Extensions; using Microsoft.AspNetCore.HttpOverrides; using NLog; var builder = WebApplication.CreateBuilder(args); LogManager.Setup().LoadConfigurationFromFile(string.Concat(Directory.GetCurrentDirectory(), "/nlog.config")); builder.Services.ConfigureCors(); builder.Services.ConfigureIISIntegration(); builder.Services.ConfigureLoggerService(); builder.Services.ConfigureMySqlContext(builder.Configuration); builder.Services.ConfigureRepositoryWrapper(); builder.Services.AddAutoMapper(typeof(Program)); builder.Services.AddControllers(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) app.UseDeveloperExceptionPage(); else app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All }); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.MapControllers(); app.Run(); ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/Properties/launchSettings.json ================================================ { "$schema": "https://json.schemastore.org/launchsettings.json", "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl": "http://localhost:40700", "sslPort": 44360 } }, "profiles": { "AccountOwnerServer": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": false, "launchUrl": "weatherforecast", "applicationUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": false, "launchUrl": "weatherforecast", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/appsettings.Development.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } } } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/appsettings.json ================================================ { "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "mysqlconnection": { "connectionString": "server=localhost;userid=root;password=yourpass;database=accountowner;" }, "AllowedHosts": "*" } ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer/nlog.config ================================================  ================================================ FILE: Part 6/AccountOwnerServer/AccountOwnerServer.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AccountOwnerServer", "AccountOwnerServer\AccountOwnerServer.csproj", "{0213FB50-5C53-4C34-8B2C-E515C7DC2579}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contracts", "Contracts\Contracts.csproj", "{B731D3C2-9A89-40E4-B96B-AA300B4195BB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerService", "LoggerService\LoggerService.csproj", "{7CEC76F5-80AF-4B37-B6F1-94A743E5C748}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entities", "Entities\Entities.csproj", "{16AAE663-A20E-493D-9087-F4F4016F6216}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repository", "Repository\Repository.csproj", "{A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Debug|Any CPU.Build.0 = Debug|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.ActiveCfg = Release|Any CPU {0213FB50-5C53-4C34-8B2C-E515C7DC2579}.Release|Any CPU.Build.0 = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Debug|Any CPU.Build.0 = Debug|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {B731D3C2-9A89-40E4-B96B-AA300B4195BB}.Release|Any CPU.Build.0 = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Debug|Any CPU.Build.0 = Debug|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.ActiveCfg = Release|Any CPU {7CEC76F5-80AF-4B37-B6F1-94A743E5C748}.Release|Any CPU.Build.0 = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Debug|Any CPU.Build.0 = Debug|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.ActiveCfg = Release|Any CPU {16AAE663-A20E-493D-9087-F4F4016F6216}.Release|Any CPU.Build.0 = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0C0D726-5224-4B8F-8C05-BB2C12A78D9B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F8E1F895-37AB-455B-8D05-ED495BE48F88} EndGlobalSection EndGlobal ================================================ FILE: Part 6/AccountOwnerServer/Contracts/Contracts.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 6/AccountOwnerServer/Contracts/IAccountRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IAccountRepository { IEnumerable AccountsByOwner(Guid ownerId); } } ================================================ FILE: Part 6/AccountOwnerServer/Contracts/ILoggerManager.cs ================================================ namespace Contracts { public interface ILoggerManager { void LogInfo(string message); void LogWarn(string message); void LogDebug(string message); void LogError(string message); } } ================================================ FILE: Part 6/AccountOwnerServer/Contracts/IOwnerRepository.cs ================================================ using Entities.Models; namespace Contracts { public interface IOwnerRepository { IEnumerable GetAllOwners(); Owner GetOwnerById(Guid ownerId); Owner GetOwnerWithDetails(Guid ownerId); void CreateOwner(Owner owner); void UpdateOwner(Owner owner); void DeleteOwner(Owner owner); } } ================================================ FILE: Part 6/AccountOwnerServer/Contracts/IRepositoryBase.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; namespace Contracts { public interface IRepositoryBase { IQueryable FindAll(); IQueryable FindByCondition(Expression> expression); void Create(T entity); void Update(T entity); void Delete(T entity); } } ================================================ FILE: Part 6/AccountOwnerServer/Contracts/IRepositoryWrapper.cs ================================================ using System; using System.Collections.Generic; using System.Text; namespace Contracts { public interface IRepositoryWrapper { IOwnerRepository Owner { get; } IAccountRepository Account { get; } void Save(); } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/DataTransferObjects/AccountDto.cs ================================================ using System; namespace Entities.DataTransferObjects { public class AccountDto { public Guid Id { get; set; } public DateTime DateCreated { get; set; } public string? AccountType { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/DataTransferObjects/OwnerDto.cs ================================================ namespace Entities.DataTransferObjects { public class OwnerDto { public Guid Id { get; set; } public string? Name { get; set; } public DateTime DateOfBirth { get; set; } public string? Address { get; set; } public IEnumerable? Accounts { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/DataTransferObjects/OwnerForCreationDto.cs ================================================ using System; using System.ComponentModel.DataAnnotations; namespace Entities.DataTransferObjects { public class OwnerForCreationDto { [Required(ErrorMessage = "Name is required")] [StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")] public string? Name { get; set; } [Required(ErrorMessage = "Date of birth is required")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Address is required")] [StringLength(100, ErrorMessage = "Address cannot be loner then 100 characters")] public string? Address { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/DataTransferObjects/OwnerForUpdateDto.cs ================================================ using System; using System.ComponentModel.DataAnnotations; namespace Entities.DataTransferObjects { public class OwnerForUpdateDto { [Required(ErrorMessage = "Name is required")] [StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")] public string Name { get; set; } [Required(ErrorMessage = "Date of birth is required")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Address is required")] [StringLength(100, ErrorMessage = "Address cannot be loner then 100 characters")] public string Address { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/Entities.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 6/AccountOwnerServer/Entities/Models/Account.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("account")] public class Account { [Column("AccountId")] public Guid Id { get; set; } [Required(ErrorMessage = "Date created is required")] public DateTime DateCreated { get; set; } [Required(ErrorMessage = "Account type is required")] public string? AccountType { get; set; } [ForeignKey(nameof(Owner))] public Guid OwnerId { get; set; } public Owner? Owner { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/Models/Owner.cs ================================================ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Entities.Models { [Table("owner")] public class Owner { [Column("OwnerId")] public Guid Id { get; set; } [Required(ErrorMessage = "Name is required")] [StringLength(60, ErrorMessage = "Name can't be longer than 60 characters")] public string? Name { get; set; } [Required(ErrorMessage = "Date of birth is required")] public DateTime DateOfBirth { get; set; } [Required(ErrorMessage = "Address is required")] [StringLength(100, ErrorMessage = "Address cannot be loner then 100 characters")] public string? Address { get; set; } public ICollection? Accounts { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/Entities/RepositoryContext.cs ================================================ using Entities.Models; using Microsoft.EntityFrameworkCore; namespace Entities { public class RepositoryContext : DbContext { public RepositoryContext(DbContextOptions options) : base(options) { } public DbSet? Owners { get; set; } public DbSet? Accounts { get; set; } } } ================================================ FILE: Part 6/AccountOwnerServer/LoggerService/LoggerManager.cs ================================================ using Contracts; using NLog; namespace LoggerService { public class LoggerManager : ILoggerManager { private static ILogger logger = LogManager.GetCurrentClassLogger(); public void LogDebug(string message) => logger.Debug(message); public void LogError(string message) => logger.Error(message); public void LogInfo(string message) => logger.Info(message); public void LogWarn(string message) => logger.Warn(message); } } ================================================ FILE: Part 6/AccountOwnerServer/LoggerService/LoggerService.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 6/AccountOwnerServer/Repository/AccountRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; namespace Repository { public class AccountRepository : RepositoryBase, IAccountRepository { public AccountRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } public IEnumerable AccountsByOwner(Guid ownerId) => FindByCondition(a => a.OwnerId.Equals(ownerId)).ToList(); } } ================================================ FILE: Part 6/AccountOwnerServer/Repository/OwnerRepository.cs ================================================ using Contracts; using Entities; using Entities.Models; using Microsoft.EntityFrameworkCore; namespace Repository { public class OwnerRepository : RepositoryBase, IOwnerRepository { public OwnerRepository(RepositoryContext repositoryContext) : base(repositoryContext) { } public IEnumerable GetAllOwners() { return FindAll() .OrderBy(ow => ow.Name) .ToList(); } public Owner GetOwnerById(Guid ownerId) { return FindByCondition(owner => owner.Id.Equals(ownerId)) .FirstOrDefault(); } public Owner GetOwnerWithDetails(Guid ownerId) { return FindByCondition(owner => owner.Id.Equals(ownerId)) .Include(ac => ac.Accounts) .FirstOrDefault(); } public void CreateOwner(Owner owner) => Create(owner); public void UpdateOwner(Owner owner) => Update(owner); public void DeleteOwner(Owner owner) => Delete(owner); } } ================================================ FILE: Part 6/AccountOwnerServer/Repository/Repository.csproj ================================================ net9.0 enable enable ================================================ FILE: Part 6/AccountOwnerServer/Repository/RepositoryBase.cs ================================================ using Contracts; using Entities; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; namespace Repository { public abstract class RepositoryBase : IRepositoryBase where T : class { protected RepositoryContext RepositoryContext { get; set; } public RepositoryBase(RepositoryContext repositoryContext) { RepositoryContext = repositoryContext; } public IQueryable FindAll() => RepositoryContext.Set().AsNoTracking(); public IQueryable FindByCondition(Expression> expression) => RepositoryContext.Set().Where(expression).AsNoTracking(); public void Create(T entity) => RepositoryContext.Set().Add(entity); public void Update(T entity) => RepositoryContext.Set().Update(entity); public void Delete(T entity) => RepositoryContext.Set().Remove(entity); } } ================================================ FILE: Part 6/AccountOwnerServer/Repository/RepositoryWrapper.cs ================================================ using Contracts; using Entities; namespace Repository { public class RepositoryWrapper : IRepositoryWrapper { private RepositoryContext _repoContext; private IOwnerRepository _owner; private IAccountRepository _account; public IOwnerRepository Owner { get { if (_owner == null) { _owner = new OwnerRepository(_repoContext); } return _owner; } } public IAccountRepository Account { get { if (_account == null) { _account = new AccountRepository(_repoContext); } return _account; } } public RepositoryWrapper(RepositoryContext repositoryContext) { _repoContext = repositoryContext; } public void Save() { _repoContext.SaveChanges(); } } } ================================================ FILE: README.md ================================================ # .NET-Core-Series Code Maze .NET Core Series https://code-maze.com/net-core-series/