Skip to content

Commit 334addd

Browse files
committed
add helper application
1 parent 9f063fb commit 334addd

File tree

27 files changed

+650
-34
lines changed

27 files changed

+650
-34
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Publish Modular Monolithic Architecture Helper Domain
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
paths: [ 'src/Modular.Monolithic.Architecture.Helper.Application/**' ]
7+
workflow_dispatch:
8+
9+
env:
10+
NET_VERSION: '9.x'
11+
PROJECT_NAME: src/Modular.Monolithic.Architecture.Helper.Application
12+
PROJECT_FILE: Modular.Monolithic.Architecture.Helper.Application.csproj
13+
RELEASE_NAME: Niko_olas.ModularMonolith.Helper.Application
14+
TAG_NAME: Domain
15+
16+
jobs:
17+
build:
18+
name: Publish Modular Monolithic Helper Application on NuGet
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v3
24+
with:
25+
fetch-depth: 0 # avoid shallow clone so nbgv can do its work.
26+
27+
- name: Setup .NET SDK ${{ env.NET_VERSION }}
28+
uses: actions/setup-dotnet@v3
29+
with:
30+
dotnet-version: ${{ env.NET_VERSION }}
31+
dotnet-quality: 'ga'
32+
33+
- name: Nerdbank.GitVersioning
34+
uses: dotnet/nbgv@v0.4
35+
id: nbgv
36+
with:
37+
path: ${{ env.PROJECT_NAME }}
38+
39+
- name: Package
40+
run: dotnet pack -c Release -o . '${{ env.PROJECT_NAME }}/${{ env.PROJECT_FILE }}'
41+
42+
- name: Publish on NuGet
43+
run: dotnet nuget push *.nupkg -k ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json
44+
45+
- name: Create release
46+
uses: actions/create-release@v1
47+
env:
48+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49+
with:
50+
tag_name: ${{ env.TAG_NAME }}_v${{ steps.nbgv.outputs.NuGetPackageVersion }}
51+
release_name: ${{ env.RELEASE_NAME }} ${{ steps.nbgv.outputs.NuGetPackageVersion }}
52+
draft: false
53+
prerelease: false

Modular.Monolithic.Architecture.Helper.sln

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ EndProject
88
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Elementi di soluzione", "Elementi di soluzione", "{763967AF-FDF9-427C-8A27-449D887B7923}"
99
ProjectSection(SolutionItems) = preProject
1010
.editorconfig = .editorconfig
11+
src\Directory.Build.props = src\Directory.Build.props
1112
EndProjectSection
1213
EndProject
1314
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modular.Monolithic.Architecture.Helper.Domain.Test", "test\Modular.Monolithic.Architecture.Helper.Domain.Test\Modular.Monolithic.Architecture.Helper.Domain.Test.csproj", "{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}"
1415
EndProject
1516
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6C83A596-D32D-B35F-00DD-F0C99B673980}"
1617
EndProject
18+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modular.Monolithic.Architecture.Helper.Application", "src\Modular.Monolithic.Architecture.Helper.Application\Modular.Monolithic.Architecture.Helper.Application.csproj", "{6577591F-63C3-4AE6-B5D2-FD32AE0D1E42}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Modular.Monolithic.Architecture.Helper.Application.Test", "test\Modular.Monolithic.Architecture.Helper.Application.Test\Modular.Monolithic.Architecture.Helper.Application.Test.csproj", "{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9}"
21+
EndProject
22+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalApi", "samples\MinimalApi\MinimalApi.csproj", "{7D72E1D0-C486-4484-8473-697492C6EA78}"
23+
EndProject
24+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{EDD876FA-E2B5-4771-89A6-746892CDFFB2}"
25+
EndProject
1726
Global
1827
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1928
Debug|Any CPU = Debug|Any CPU
@@ -28,12 +37,26 @@ Global
2837
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
2938
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
3039
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{6577591F-63C3-4AE6-B5D2-FD32AE0D1E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{6577591F-63C3-4AE6-B5D2-FD32AE0D1E42}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{6577591F-63C3-4AE6-B5D2-FD32AE0D1E42}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{6577591F-63C3-4AE6-B5D2-FD32AE0D1E42}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{7D72E1D0-C486-4484-8473-697492C6EA78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{7D72E1D0-C486-4484-8473-697492C6EA78}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{7D72E1D0-C486-4484-8473-697492C6EA78}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{7D72E1D0-C486-4484-8473-697492C6EA78}.Release|Any CPU.Build.0 = Release|Any CPU
3152
EndGlobalSection
3253
GlobalSection(SolutionProperties) = preSolution
3354
HideSolutionNode = FALSE
3455
EndGlobalSection
3556
GlobalSection(NestedProjects) = preSolution
3657
{2EEB3EA9-A09D-41DF-B700-16281D2CBA2B} = {6C83A596-D32D-B35F-00DD-F0C99B673980}
58+
{D7BE28AD-2120-4671-8A91-B2AEFA0F49C9} = {6C83A596-D32D-B35F-00DD-F0C99B673980}
59+
{7D72E1D0-C486-4484-8473-697492C6EA78} = {EDD876FA-E2B5-4771-89A6-746892CDFFB2}
3760
EndGlobalSection
3861
GlobalSection(ExtensibilityGlobals) = postSolution
3962
SolutionGuid = {9BD29F4F-0728-467B-BD44-53B15DB15620}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Modular.Monolithic.Architecture.Helper.Application.Command;
5+
using Modular.Monolithic.Architecture.Helper.Domain.Results;
6+
7+
namespace MinimalApi.Application.Core.Orders.Command.CreateOrder
8+
{
9+
public sealed record class CreateOrderCommand(IEnumerable<ItemToAdd> Items) : ICommand<Result<Guid>>;
10+
11+
public class ItemToAdd
12+
{
13+
public string ItemId { get; set; }
14+
public string Description { get; set; }
15+
public decimal Price { get; set; }
16+
17+
public ItemToAdd(string itemId, string description, decimal price)
18+
{
19+
ItemId = itemId;
20+
Description = description;
21+
Price = price;
22+
}
23+
}
24+
25+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using MinimalApi.Domain.Orders;
5+
using MinimalApi.Infrastructure;
6+
using Modular.Monolithic.Architecture.Helper.Application.Command;
7+
using Modular.Monolithic.Architecture.Helper.Domain.Results;
8+
9+
namespace MinimalApi.Application.Core.Orders.Command.CreateOrder
10+
{
11+
public class CreateOrderCommandHandler(MinimalApiDbContext context) : ICommandHandler<CreateOrderCommand, Result<Guid>>
12+
{
13+
public async Task<Result<Guid>> Handle(CreateOrderCommand command, CancellationToken cancellationToken)
14+
{
15+
var order = Order.Create();
16+
17+
foreach (ItemToAdd item in command.Items)
18+
{
19+
var orderItem = OrderItem.Create(item.ItemId, item.Description, item.Price, order.Id);
20+
21+
order.AddOrderItem(orderItem);
22+
}
23+
24+
context.Add(order);
25+
26+
await context.SaveChangesAsync();
27+
28+
return Result.Success(order.Id);
29+
}
30+
}
31+
32+
33+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Modular.Monolithic.Architecture.Helper.Application.Query;
5+
using Modular.Monolithic.Architecture.Helper.Domain.Results;
6+
7+
namespace MinimalApi.Application.Core.Orders.Query.GetOrderById;
8+
9+
public sealed record class GetOrderByIdQuery(Guid orderId) : IQuery<Result<OrderDto>>;
10+
11+
public sealed class OrderDto
12+
{
13+
public Guid Id { get; set; }
14+
15+
public IReadOnlyList<ItemDto> Items { get; set; }
16+
}
17+
18+
public sealed class ItemDto
19+
{
20+
public string ItemId { get; set; }
21+
22+
public decimal Price { get; set; }
23+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.EntityFrameworkCore;
5+
using MinimalApi.Infrastructure;
6+
using Modular.Monolithic.Architecture.Helper.Application.Query;
7+
using Modular.Monolithic.Architecture.Helper.Domain.Errors;
8+
using Modular.Monolithic.Architecture.Helper.Domain.Results;
9+
10+
namespace MinimalApi.Application.Core.Orders.Query.GetOrderById
11+
{
12+
public class GetOrderByIdQueryHandler(MinimalApiDbContext context) : IQueryHandler<GetOrderByIdQuery, Result<OrderDto>>
13+
{
14+
public async Task<Result<OrderDto>> Handle(GetOrderByIdQuery command, CancellationToken cancellationToken = default)
15+
{
16+
var result = await context.Orders
17+
.Select(x => new OrderDto()
18+
{
19+
Id = x.Id,
20+
Items = x.OrderItems.Select(x => new ItemDto() { ItemId = x.ItemId, Price = x.Price }).ToList()
21+
})
22+
.FirstOrDefaultAsync(x => x.Id == command.orderId, cancellationToken);
23+
24+
if (result is null)
25+
{
26+
return Result.Failure<OrderDto>(DomainErrors.General.ItemNotFound());
27+
}
28+
29+
return result;
30+
}
31+
}
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Collections.Immutable;
5+
using Modular.Monolithic.Architecture.Helper.Domain.Abstractions;
6+
using Modular.Monolithic.Architecture.Helper.Domain.Core;
7+
8+
namespace MinimalApi.Domain.Orders
9+
{
10+
public class Order : AggregateRoot, IAuditableEntity, ISoftDeletableEntity
11+
{
12+
public DateTime CreatedOn { get; private set; }
13+
14+
public DateTime? ModifiedOn { get; private set; }
15+
16+
public DateTime? DeletedOn { get; private set; }
17+
18+
public bool Deleted { get; private set; }
19+
20+
private ICollection<OrderItem> _orderItems { get; }
21+
public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.ToImmutableList();
22+
23+
private Order(DateTime createdOn, DateTime? modifiedOn = null, DateTime? deletedOn = null, bool deleted = false) : base(Guid.CreateVersion7())
24+
{
25+
CreatedOn = createdOn;
26+
ModifiedOn = modifiedOn;
27+
DeletedOn = deletedOn;
28+
Deleted = deleted;
29+
_orderItems = [];
30+
}
31+
32+
public static Order Create()
33+
{
34+
return new Order(DateTime.UtcNow);
35+
}
36+
37+
public void AddOrderItem(OrderItem orderItem)
38+
{
39+
_orderItems.Add(orderItem);
40+
}
41+
}
42+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Modular.Monolithic.Architecture.Helper.Domain.Core;
5+
6+
namespace MinimalApi.Domain.Orders
7+
{
8+
public class OrderItem : Entity
9+
{
10+
public string Description { get; private set; }
11+
12+
public string ItemId { get; private set; }
13+
14+
public decimal Price { get; private set; }
15+
16+
public Guid OrderId { get; private set; }
17+
18+
private OrderItem(string itemId, string description, decimal price, Guid orderId) : base(Guid.CreateVersion7())
19+
{
20+
Description = description;
21+
ItemId = itemId;
22+
Price = price;
23+
OrderId = orderId;
24+
}
25+
26+
public static OrderItem Create(string itemId, string description, decimal price, Guid orderId)
27+
{
28+
return new OrderItem(itemId, description, price, orderId);
29+
}
30+
}
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Microsoft.EntityFrameworkCore;
5+
using MinimalApi.Domain.Orders;
6+
7+
namespace MinimalApi.Infrastructure
8+
{
9+
public class MinimalApiDbContext : DbContext
10+
{
11+
public DbSet<Order> Orders { get; set; }
12+
13+
public DbSet<OrderItem> OrderItem { get; set; }
14+
15+
16+
public MinimalApiDbContext(DbContextOptions<MinimalApiDbContext> options) : base(options)
17+
{
18+
}
19+
20+
protected override void OnModelCreating(ModelBuilder modelBuilder)
21+
{
22+
base.OnModelCreating(modelBuilder);
23+
}
24+
}
25+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\..\src\Modular.Monolithic.Architecture.Helper.Application\Modular.Monolithic.Architecture.Helper.Application.csproj" />
11+
<ProjectReference Include="..\..\src\Modular.Monolithic.Architecture.Helper.Domain\Modular.Monolithic.Architecture.Helper.Domain.csproj" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.5" />
16+
<PackageReference Include="Scrutor" Version="6.0.1" />
17+
</ItemGroup>
18+
19+
</Project>

0 commit comments

Comments
 (0)