Skip to content

Commit 5874153

Browse files
authored
Update README.md
1 parent 1058a90 commit 5874153

File tree

1 file changed

+75
-164
lines changed

1 file changed

+75
-164
lines changed

README.md

Lines changed: 75 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -106,187 +106,100 @@ The below image represents aspnetrun approach of development architecture of run
106106
![DDD_png_pure](https://user-images.githubusercontent.com/1147445/54773098-e1efe700-4c19-11e9-9150-74f7e770de42.png)
107107

108108
### Structure of Project
109-
Repository include layers divided by **4 project**;
110-
* Core
111-
* Entities
112-
* Interfaces
113-
* Specifications
114-
* ValueObjects
115-
* Exceptions
116-
* Application
117-
* Interfaces
118-
* Services
119-
* Dtos
120-
* Mapper
121-
* Exceptions
122-
* Infrastructure
123-
* Data
124-
* Repository
125-
* Services
126-
* Migrations
127-
* Logging
128-
* Exceptions
129-
* Web
130-
* Interfaces
131-
* Services
132-
* Pages
133-
* ViewModels
134-
* Extensions
135-
* Mapper
136-
137-
### Core Layer
138-
Development of Domain Logic with abstraction. Interfaces drives business requirements with light implementation. The Core project is the **center of the Clean Architecture** design, and all other project dependencies should point toward it.
139-
140-
#### Entities
141-
Includes Entity Framework Core Entities which creates sql table with **Entity Framework Core Code First Aproach**. Some Aggregate folders holds entity and aggregates.
142-
You can see example of **code-first** Entity definition as below;
143-
144-
```csharp
145-
public class Product : BaseEntity
146-
{
147-
public string ProductName { get; set; }
148-
public string QuantityPerUnit { get; set; }
149-
public decimal? UnitPrice { get; set; }
150-
public short? UnitsInStock { get; set; }
151-
public short? UnitsOnOrder { get; set; }
152-
public short? ReorderLevel { get; set; }
153-
public bool Discontinued { get; set; }
154-
public int CategoryId { get; set; }
155-
public Category Category { get; set; }
156-
157-
public static Product Create(int productId, int categoryId, string name, decimal? unitPrice = null, short? unitsInStock = null, short? unitsOnOrder = null, short? reorderLevel = null, bool discontinued = false)
158-
{
159-
var product = new Product
160-
{
161-
Id = productId,
162-
CategoryId = categoryId,
163-
ProductName = name,
164-
UnitPrice = unitPrice,
165-
UnitsInStock = unitsInStock,
166-
UnitsOnOrder = unitsOnOrder,
167-
ReorderLevel = reorderLevel,
168-
Discontinued = discontinued
169-
};
170-
return product;
171-
}
172-
}
173-
```
174-
Applying domain driven approach, Product class responsible to create Product instance.
175-
176-
#### Interfaces
177-
Abstraction of Repository - Domain repositories (IAsyncRepository - IProductRepository) - Specifications etc.. This interfaces include database operations without any application and ui responsibilities.
178-
179-
#### Specifications
180-
This folder is implementation of **[specification pattern](https://en.wikipedia.org/wiki/Specification_pattern)**. Creates custom scripts with using **ISpecification** interface. Using BaseSpecification managing Criteria, Includes, OrderBy, Paging.
181-
This specs runs when EF commands working with passing spec. This specs implemented SpecificationEvaluator.cs and creates query to AspnetRunRepository.cs in ApplySpecification method.This helps create custom queries.
182-
183-
### Infrastructure Layer
184-
Implementation of Core interfaces in this project with **Entity Framework Core** and other dependencies.
185-
Most of your application's dependence on external resources should be implemented in classes defined in the Infrastructure project. These classes must implement the interfaces defined in Core. If you have a very large project with many dependencies, it may make sense to have more than one Infrastructure project (eg Infrastructure.Data), but in most projects one Infrastructure project that contains folders works well.
186-
This could be includes, for example, **e-mail providers, file access, web api clients**, etc. For now this repository only dependend sample data access and basic domain actions, by this way there will be no direct links to your Core or UI projects.
187-
188-
#### Data
109+
AspnetRunBasic has only **one solution** and into this solution only **one web application project** which include all components of project structure. The idea is that **fast implementation, minimum development, bootstrap your idea, create Minimum Viable Product (MVP), idea validation, startup development implementation** for a **limited time** and **limited resources** with using asp.net core and entity framework core.
110+
111+
Repository include folders for group implementations;
112+
* Data
113+
* AspnetRunContext
114+
* AspnetRunContextSeed
115+
* Entities
116+
* Product
117+
* Category
118+
* Migrations
119+
* Generated by scaffolding from ef.core
120+
* Pages
121+
* Default Razor Web Application Template of Asp.Net Core
122+
* Repositories
123+
* IProductRepository
124+
* ProductRepository
125+
126+
### Data Folder
189127
Includes **Entity Framework Core Context** and tables in this folder. When new entity created, it should add to context and configure in context.
190128
The Infrastructure project depends on Microsoft.**EntityFrameworkCore.SqlServer** and EF.Core related nuget packages, you can check nuget packages of Infrastructure layer. If you want to change your data access layer, it can easily be replaced with a lighter-weight ORM like Dapper.
191129

192130
#### Migrations
193131
EF add-migration classes.
194132
#### Repository
195-
EF Repository and Specification implementation. This class responsible to create queries, includes, where conditions etc..
196-
#### Services
197-
Custom services implementation, like email, cron jobs etc.
133+
EF Repository implementation. This class responsible to create queries, includes, where conditions etc..
198134

199-
### Application Layer
200-
Development of **Domain Logic with implementation**. Interfaces drives business requirements and implementations in this layer.
201-
Application layer defines that user required actions in app services classes as below way;
135+
#### Entities Folder
136+
Includes Entity Framework Core Entities which creates sql table with **Entity Framework Core Code First Aproach**. Some Aggregate folders holds entity and aggregates.
137+
You can see example of **code-first** Entity definition as below;
202138

203139
```csharp
204-
public interface IProductAppService
205-
{
206-
Task<IEnumerable<ProductDto>> GetProductList();
207-
Task<ProductDto> GetProductById(int productId);
208-
Task<IEnumerable<ProductDto>> GetProductByName(string productName);
209-
Task<IEnumerable<ProductDto>> GetProductByCategory(int categoryId);
210-
Task<ProductDto> Create(ProductDto entityDto);
211-
Task Update(ProductDto entityDto);
212-
Task Delete(ProductDto entityDto);
213-
}
214-
```
215-
Also implementation located same places in order to choose different implementation at runtime when DI bootstrapped.
216-
```csharp
217-
public class ProductAppService : IProductAppService
218-
{
219-
private readonly IProductRepository _productRepository;
220-
private readonly IAppLogger<ProductAppService> _logger;
221-
222-
public ProductAppService(IProductRepository productRepository, IAppLogger<ProductAppService> logger)
140+
public class Product
223141
{
224-
_productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
225-
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
226-
}
142+
public int Id { get; set; }
227143

228-
public async Task<IEnumerable<ProductDto>> GetProductList()
229-
{
230-
var productList = await _productRepository.GetProductListAsync();
231-
var mapped = ObjectMapper.Mapper.Map<IEnumerable<ProductDto>>(productList);
232-
return mapped;
144+
[Required, StringLength(80)]
145+
public string Name { get; set; }
146+
147+
[Required, StringLength(255)]
148+
public string Description { get; set; }
149+
150+
public int UnitPrice { get; set; }
151+
152+
public int CategoryId { get; set; }
153+
public Category Category { get; set; }
233154
}
234-
}
235155
```
236-
In this layer we can add validation , authorization, logging, exception handling etc. -- cross cutting activities should be handled in here.
237156

238-
### Web Layer
239-
Development of UI Logic with implementation. Interfaces drives business requirements and implementations in this layer.
240-
The application's main **starting point** is the ASP.NET Core web project. This is a classical console application, with a public static void Main method in Program.cs. It currently uses the default **ASP.NET Core project template** which based on **Razor Pages** templates. This includes appsettings.json file plus environment variables in order to stored configuration parameters, and is configured in Startup.cs.
157+
### Repository Folder
158+
Implementation of Core interfaces in this project with **Entity Framework Core** and other dependencies.
159+
Most of your application's dependence on external resources should be implemented in classes defined in the Infrastructure project. These classes must implement the interfaces defined in Core. If you have a very large project with many dependencies, it may make sense to have more than one Infrastructure project (eg Infrastructure.Data), but in most projects one Infrastructure project that contains folders works well.
160+
This could be includes, for example, **e-mail providers, file access, web api clients**, etc. For now this repository only dependend sample data access and basic domain actions, by this way there will be no direct links to your Core or UI projects.
241161

242-
Web layer defines that user required actions in page services classes as below way;
243162
```csharp
244-
public interface IProductPageService
245-
{
246-
Task<IEnumerable<ProductViewModel>> GetProducts(string productName);
247-
Task<ProductViewModel> GetProductById(int productId);
248-
Task<IEnumerable<ProductViewModel>> GetProductByCategory(int categoryId);
249-
Task<IEnumerable<CategoryViewModel>> GetCategories();
250-
Task<ProductViewModel> CreateProduct(ProductViewModel productViewModel);
251-
Task UpdateProduct(ProductViewModel productViewModel);
252-
Task DeleteProduct(ProductViewModel productViewModel);
253-
}
163+
public interface IProductRepository
164+
{
165+
Task<IEnumerable<Product>> GetProductListAsync();
166+
Task<Product> GetProductByIdAsync(int id);
167+
Task<IEnumerable<Product>> GetProductByNameAsync(string name);
168+
Task<IEnumerable<Product>> GetProductByCategoryAsync(int categoryId);
169+
Task<Product> AddAsync(Product product);
170+
Task UpdateAsync(Product product);
171+
Task DeleteAsync(Product product);
172+
Task<IEnumerable<Category>> GetCategories();
173+
}
254174
```
255175
Also implementation located same places in order to choose different implementation at runtime when DI bootstrapped.
256176
```csharp
257-
public class ProductPageService : IProductPageService
258-
{
259-
private readonly IProductAppService _productAppService;
260-
private readonly ICategoryAppService _categoryAppService;
261-
private readonly IMapper _mapper;
262-
private readonly ILogger<ProductPageService> _logger;
263-
264-
public ProductPageService(IProductAppService productAppService, ICategoryAppService categoryAppService, IMapper mapper, ILogger<ProductPageService> logger)
177+
public class ProductRepository : IProductRepository
265178
{
266-
_productAppService = productAppService ?? throw new ArgumentNullException(nameof(productAppService));
267-
_categoryAppService = categoryAppService ?? throw new ArgumentNullException(nameof(categoryAppService));
268-
_mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
269-
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
270-
}
179+
protected readonly AspnetRunContext _dbContext;
271180

272-
public async Task<IEnumerable<ProductViewModel>> GetProducts(string productName)
273-
{
274-
if (string.IsNullOrWhiteSpace(productName))
181+
public ProductRepository(AspnetRunContext dbContext)
275182
{
276-
var list = await _productAppService.GetProductList();
277-
var mapped = _mapper.Map<IEnumerable<ProductViewModel>>(list);
278-
return mapped;
183+
_dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
279184
}
280185

281-
var listByName = await _productAppService.GetProductByName(productName);
282-
var mappedByName = _mapper.Map<IEnumerable<ProductViewModel>>(listByName);
283-
return mappedByName;
284-
}
285-
}
186+
public async Task<IEnumerable<Product>> GetProductListAsync()
187+
{
188+
return await _dbContext.Products.ToListAsync();
189+
}
190+
191+
public async Task<Product> GetProductByIdAsync(int id)
192+
{
193+
return await _dbContext.Products
194+
.Include(p => p.Category)
195+
.FirstOrDefaultAsync(p => p.Id == id);
196+
}
286197
```
287-
### Test Layer
288-
For each layer, there is a test project which includes intended layer dependencies and mock classes. So that means Core-Application-Infrastructure and Web layer has their own test layer. By this way this test projects also divided by **unit, functional and integration tests** defined by in which layer it is implemented.
289-
Test projects using **xunit and Mock libraries**. xunit, because that's what ASP.NET Core uses internally to test the product. Moq, because perform to create fake objects clearly and its very modular.
198+
199+
200+
### Pages Folder
201+
Development of UI Logic with implementation. Interfaces drives business requirements and implementations in this layer.
202+
The application's main **starting point** is the ASP.NET Core web project. This is a classical console application, with a public static void Main method in Program.cs. It currently uses the default **ASP.NET Core project template** which based on **Razor Pages** templates. This includes appsettings.json file plus environment variables in order to stored configuration parameters, and is configured in Startup.cs.
290203

291204

292205
## Technologies
@@ -297,16 +210,14 @@ Test projects using **xunit and Mock libraries**. xunit, because that's what AS
297210
* Razor Pages
298211
* AutoMapper
299212

300-
## Architecture
301-
* Clean Architecture
302-
* Full architecture with responsibility separation of concerns
303-
* SOLID and Clean Code
304-
* Domain Driven Design (Layers and Domain Model Pattern)
305-
* Unit of Work
306-
* Repository and Generic Repository
213+
## Used Components
214+
* Asp.Net Core
215+
* Entity Framework Core
216+
* Razor Pages
217+
* Repository Design Pattern
307218
* Multiple Page Web Application (MPA)
308219
* Monolitic Deployment Architecture
309-
* Specification Pattern
220+
* SOLID and Clean Code
310221

311222
## Disclaimer
312223

0 commit comments

Comments
 (0)