Skip to content

Commit

Permalink
Pull Request: Migrate Project to .NET 8 and Improve Yield Calculation (
Browse files Browse the repository at this point in the history
…#7)

* core: migrate domain to net8.0

* update EF to v8

* fix: not adding new operation when setting a new yield

* fix(ef): add the account as a member of AccountOperation to fix the relationship

* fix(ef): add account to relationship mapping

* refactor: the yield calculator should not set value on account directly, only calculates the yield and then the handle will be responsible for it

* test: update tests to compare values returned from YieldService

* style: remove unused namespaces

* chore: create config to enable debugging on vs code

* docs: update .net version on readme

* setup CI on a project

* ci: add MySQL db to GA configuration
  • Loading branch information
almeidaalex authored Aug 13, 2024
1 parent 04b4d7f commit c4f69b1
Show file tree
Hide file tree
Showing 19 changed files with 169 additions and 78 deletions.
4 changes: 2 additions & 2 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
]
},
"dotnet-ef": {
"version": "6.0.26",
"version": "8.0.7",
"commands": [
"dotnet-ef"
]
}
}
}
}
34 changes: 34 additions & 0 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# This workflow will build a .NET project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net

name: .NET

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
services:
mysql:
image: mysql:9.0.1
env:
MYSQL_ROOT_PASSWORD: b@nk1
MYSQL_DATABASE: bank_db
ports:
- "3307:3306"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
33 changes: 33 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Bank.Api/bin/Debug/net6.0/Bank.Api.dll",
"args": [],
"cwd": "${workspaceFolder}/Bank.Api",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}
41 changes: 41 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/Bank.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/Bank.sln",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/Bank.sln"
],
"problemMatcher": "$msCompile"
}
]
}
6 changes: 3 additions & 3 deletions Bank.Api/Bank.Api.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\Bank</DockerfileContext>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
Expand All @@ -9,10 +9,10 @@
<PackageReference Include="MediatR" Version="10.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.26" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bank.Domain\Bank.Domain.csproj" />
<ProjectReference Include="..\Bank.Infra\Bank.Infra.csproj" />
</ItemGroup>
</Project>
</Project>
4 changes: 2 additions & 2 deletions Bank.Api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
Expand Down
14 changes: 10 additions & 4 deletions Bank.Api/Handlers/IncomeRequestHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,18 @@ public IncomeRequestHandler(BankDbContext context, IYieldService yieldService)
_yieldService = yieldService;
}

public async Task<Unit> Handle(CalculateIncomeCommand request, CancellationToken cancellationToken)
public Task<Unit> Handle(CalculateIncomeCommand request, CancellationToken cancellationToken)
{
var accounts = this._context.Accounts.ToArray();
_yieldService.CalculateInterestFor(request.ForDate, accounts, request.InterestRate, cancellationToken, days: 1);
await _context.SaveChangesAsync(cancellationToken);
return Unit.Value;

foreach (var account in accounts)
{
var yield = _yieldService.CalculateInterestFor(request.ForDate, account, request.InterestRate, days: 1);
account.SetYield(yield, request.ForDate);
}

_context.SaveChanges();
return Unit.Task;
}
}
}
12 changes: 0 additions & 12 deletions Bank.Api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

using Bank.Api.Handlers;
using Bank.Domain;
using Bank.Domain.Contracts;
using Bank.Domain.Events;
using Bank.Domain.SeedWork;
using Bank.Infra;

using MediatR;
using MediatR.Pipeline;

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;

namespace Bank.Api
Expand Down
3 changes: 2 additions & 1 deletion Bank.Api/appsettings.Development.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.EntityFrameworkCore.Database.Command": "Information"
}
},
"ConnectionStrings": {
Expand Down
5 changes: 3 additions & 2 deletions Bank.Domain/Account.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,16 @@ public void ChargePayment(Invoice invoice)
public void AddOperation(AccountOperation accountOperation) =>
_operations.Add(accountOperation);

public IReadOnlyCollection<AccountOperation> Operations => _operations;
public IReadOnlyCollection<AccountOperation> Operations => _operations.AsReadOnly();

public DateTime? LastYieldedDate { get; private set; }

public void SetYield(decimal yield, DateTime currentDate)
{
this.AddOperation(new AccountOperation(currentDate, $"Rendimento em {currentDate}", yield, EventType.Income));
this.Balance += yield;
this.LastYieldedDate = currentDate;
this.AddDomainEvent(new CalculatedIncomeEvent(this, yield));
}
}
}
}
5 changes: 3 additions & 2 deletions Bank.Domain/AccountOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public AccountOperation(DateTime date, string description, decimal amount, Event
public string Description { get; private set; }
public decimal Amount { get; private set; }
public EventType Operation { get; private set; }
public int AccountNo { get; private set; }
public int AccountNo { get; set; }
public Account Account { get; set; }
}
}
}
4 changes: 2 additions & 2 deletions Bank.Domain/Bank.Domain.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="10.0.1" />
</ItemGroup>
</Project>
</Project>
10 changes: 2 additions & 8 deletions Bank.Domain/Contracts/IYieldService.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Bank.Domain.Contracts
{
public interface IYieldService
{
void CalculateInterestFor(DateTime currentDate, IYieldAccount account, double interestRate, uint days = 1);
void CalculateInterestFor(DateTime currentDate, IEnumerable<IYieldAccount> accounts, double interestRate, CancellationToken cancellationToken, uint days = 1);
decimal CalculateInterestFor(DateTime currentDate, IYieldAccount account, double interestRate, uint days = 1);
}
}
}
19 changes: 6 additions & 13 deletions Bank.Domain/YieldService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,21 @@ namespace Bank.Domain
{
public class YieldService : IYieldService
{
public void CalculateInterestFor(DateTime forDate, IYieldAccount account, double interestRate, uint days = 1)
public decimal CalculateInterestFor(DateTime forDate, IYieldAccount account, double interestRate, uint days = 1)
{
if (HasPositiveBalance(account)
&& ItHasAlreadyBeenCalculated(forDate, account.LastYieldedDate.GetValueOrDefault(), days))
{
decimal calc = Convert.ToDecimal(Math.Pow(1 + interestRate / 100d, days / 252d) - 1);
var balance = Math.Round(calc * account.Balance, 2);
account.SetYield(balance, forDate);
var yield = Math.Round(calc * account.Balance, 2);
return yield;
}
return 0;
}

public void CalculateInterestFor(DateTime forDate, IEnumerable<IYieldAccount> accounts, double interestRate, CancellationToken cancellationToken, uint days = 1)
{
var paralleOptions = new ParallelOptions { CancellationToken = cancellationToken };

Parallel.ForEach(accounts, paralleOptions, account =>
this.CalculateInterestFor(forDate, account, interestRate, days));
}


private static bool ItHasAlreadyBeenCalculated(DateTime forDate, DateTime lastYieldedDate, uint days) =>
forDate > lastYieldedDate.AddDays(days);

private static bool HasPositiveBalance(IYieldAccount account) => account.Balance > 0;
}
}
}
15 changes: 6 additions & 9 deletions Bank.Infra/Bank.Infra.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MediatR" Version="10.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.26">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.25" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.26" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.26" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bank.Domain\Bank.Domain.csproj" />
</ItemGroup>
</Project>
</Project>
4 changes: 2 additions & 2 deletions Bank.Infra/BankContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private void ConfigureAccount(ModelBuilder builder)
account.Property(a => a.OwnerId);

account.HasMany(a => a.Operations)
.WithOne()
.WithOne(o => o.Account)
.HasForeignKey(h => h.AccountNo)
.OnDelete(DeleteBehavior.Cascade);

Expand All @@ -106,4 +106,4 @@ private static void CleanEvents(IEnumerable<IEntity> entities)
entity.ClearEvents();
}
}
}
}
8 changes: 4 additions & 4 deletions Bank.Tests/Bank.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
</PropertyGroup>
Expand All @@ -22,12 +22,12 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.26" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.26" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Bank.Api\Bank.Api.csproj" />
<ProjectReference Include="..\Bank.Domain\Bank.Domain.csproj" />
<ProjectReference Include="..\Bank.Infra\Bank.Infra.csproj" />
</ItemGroup>
</Project>
</Project>
Loading

0 comments on commit c4f69b1

Please sign in to comment.