Skip to content

Commit 629416b

Browse files
committed
refactor code product-service
1 parent 9a639c3 commit 629416b

File tree

16 files changed

+137
-133
lines changed

16 files changed

+137
-133
lines changed

README.md

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,13 @@
22

33
The practical repository uses coolstore domain which is mainly borrowed from `https://github.com/zkavtaskin/Domain-Driven-Design-Example` to demonstrate how to apply Domain Driven Design seamlessly with Clean Architecture.
44

5+
## Show your support
56

6-
# Business Usecases
7-
8-
![](assets/usecase_diagram.png)
9-
10-
# High level context
11-
12-
![](assets/context_diagram.png)
13-
14-
# ERD
7+
If you **cannot give a star** :star: for `practical-clean-ddd` repository, **try it again**!
158

16-
![](assets/class_diagram.png)
9+
Why? Because it doesn't only **help strengthen our .NET community** but also **helps to improve cloud-native apps development on the .NET platform**. Thank you very much :+1:
1710

18-
# Testing Application
11+
# Give it a try!
1912

2013
- Prerequisite
2114
- .NET SDK: 5.0.200-preview.21079.7
@@ -46,13 +39,28 @@ $ npm run dev
4639
>
4740
> Tye Dashboard: [http://localhost:8000](http://localhost:8000)
4841
42+
# Business Usecases
43+
44+
![](assets/usecase_diagram.png)
45+
46+
# High level context
47+
48+
![](assets/context_diagram.png)
49+
50+
# ERD
51+
52+
![](assets/class_diagram.png)
53+
4954
# Clean Domain Driven-design
5055

5156
Domain-driven Design demonstrates it can help the business tidy and organized in many years. But it is hard to approach and use, we need to make it easier to use in the real project when we get started.
5257

5358
Clean Architecture helps the project structure easier to refactor and evolve in medium and big projects. Especially in the Microservice world, we always want to do and try with a lot of time in the project lifetime.
5459

5560
Clean Domain-driven Design is a collection of basic building blocks and project structure to help we get starting the project with less code boilerplate and effortless. We focus on the Microservice approach of how can we organize code, the project with the monorepo approach, and you can use it for modular monolith project as well.
61+
62+
![](assets/projects_structure.png)
63+
5664
## Core project
5765
### Domain
5866

@@ -70,9 +78,6 @@ TODO
7078

7179
TODO
7280

73-
## Api project
74-
75-
TODO
7681
# Public CRUD interface
7782

7883
In medium and large software projects, we normally implement the CRUD actions over and over again. And it might take around 40-50% codebase just to do CRUD in the projects. The question is can we make standardized CRUD APIs, then we can use them in potential projects in the future? That is in my mind for a long time when I started and finished many projects, and I decide to take time to research and define the public interfaces for it as below
@@ -83,11 +88,19 @@ In medium and large software projects, we normally implement the CRUD actions ov
8388
public record ResultModel<T>(T Data, bool IsError = false, string? ErrorMessage = default);
8489
```
8590

91+
```csharp
92+
public interface ICommand<T> : IRequest<ResultModel<T>> {}
93+
```
94+
95+
```csharp
96+
public interface IQuery<T> : IRequest<ResultModel<T>> {}
97+
```
98+
8699
## [R]etrieve
87100

88101
```csharp
89102
// input model for list query (normally using for the table UI control with paging, filtering and sorting)
90-
public interface IListQueryInput : ICrudInput
103+
public interface IListQuery<TResponse> : IQuery<TResponse>
91104
{
92105
public List<string> Includes { get; init; }
93106
public List<FilterModel> Filters { get; init; }
@@ -103,50 +116,40 @@ public record ListResponseModel<T>(List<T> Items, long TotalItems, int Page, int
103116
```
104117

105118
```csharp
106-
public interface IItemQueryInput<TId> : ICrudInput where TId : struct
119+
public interface IItemQuery<TId, TResponse> : IQuery<TResponse>
107120
{
108-
public List<string> Includes { get; init; }
109-
public TId Id { get; init; }
121+
public List<string> Includes { get; init; }
122+
public TId Id { get; init; }
110123
}
111124
```
112125

113126
## [C]reate
114127

115128
```csharp
116-
public interface ICreateInput<T> : ICrudInput
129+
public interface ICreateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
117130
{
118-
public T Model { get; init; }
131+
public TRequest Model { get; init; }
119132
}
120133
```
121134

122135
## [U]pdate
123136

124137
```csharp
125-
public interface IUpdateInput<T> : ICrudInput
138+
public interface IUpdateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
126139
{
127-
public T Model { get; init; }
140+
public TRequest Model { get; init; }
128141
}
129142
```
130143

131144
## [D]elete
132145

133146
```csharp
134-
public interface IDeleteInput<TId> : ICrudInput where TId : struct
147+
public interface IDeleteCommand<TId, TResponse> : ICommand<TResponse> where TId : struct
135148
{
136149
public TId Id { get; init; }
137150
}
138151
```
139152

140-
# CQRS interface
141-
142-
```csharp
143-
public interface ICommand<T> : IRequest<ResultModel<T>> {}
144-
```
145-
146-
```csharp
147-
public interface IQuery<T> : IRequest<ResultModel<T>> {}
148-
```
149-
150153
# Sample pages
151154

152155
![](assets/products_screen.png)

assets/projects_structure.png

65 KB
Loading

restclient.http

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ POST {{host}}/api/products-query HTTP/1.1
55
content-type: {{contentType}}
66

77
{
8-
"includes": ["Returns", "Code"],
98
"filters": [
109
{
1110
"fieldName": "Name",
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System.Collections.Generic;
2+
using MediatR;
3+
4+
namespace N8T.Core.Domain
5+
{
6+
public interface ICommand<T> : IRequest<ResultModel<T>>
7+
{
8+
}
9+
10+
public interface IQuery<T> : IRequest<ResultModel<T>>
11+
{
12+
}
13+
14+
public interface ICreateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
15+
{
16+
public TRequest Model { get; init; }
17+
}
18+
19+
public interface IUpdateCommand<TRequest, TResponse> : ICommand<TResponse>, ITxRequest
20+
{
21+
public TRequest Model { get; init; }
22+
}
23+
24+
public interface IDeleteCommand<TId, TResponse> : ICommand<TResponse> where TId : struct
25+
{
26+
public TId Id { get; init; }
27+
}
28+
29+
public interface IListQuery<TResponse> : IQuery<TResponse>
30+
{
31+
public List<string> Includes { get; init; }
32+
public List<FilterModel> Filters { get; init; }
33+
public List<string> Sorts { get; init; }
34+
public int Page { get; init; }
35+
public int PageSize { get; init; }
36+
}
37+
38+
public interface IItemQuery<TId, TResponse> : IQuery<TResponse>
39+
{
40+
public List<string> Includes { get; init; }
41+
public TId Id { get; init; }
42+
}
43+
44+
public record FilterModel(string FieldName, string Comparision, string FieldValue);
45+
46+
public record ResultModel<T>(T Data, bool IsError = false, string? ErrorMessage = default);
47+
48+
public record ListResponseModel<T>(List<T> Items, long TotalItems, int Page, int PageSize);
49+
}

src/BuildingBlocks/N8T.Core/Domain/IAggregateRoot.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ namespace N8T.Core.Domain
33
public interface IAggregateRoot
44
{
55
}
6+
7+
public interface ITxRequest { }
68
}

src/BuildingBlocks/N8T.Core/Domain/ICommand.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/BuildingBlocks/N8T.Core/Domain/ICrudInput.cs

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/BuildingBlocks/N8T.Core/Domain/IQuery.cs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/BuildingBlocks/N8T.Infrastructure.EfCore/TxBehavior.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
namespace N8T.Infrastructure.EfCore
1414
{
15-
public interface ITxRequest { }
16-
1715
//[DebuggerStepThrough]
1816
public class TxBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
1917
where TRequest : notnull, IRequest<TResponse>

src/Product/ProductService.Application/Anchor.cs

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)