Skip to content

Commit

Permalink
Merge pull request #1 from neozhu/dev
Browse files Browse the repository at this point in the history
migrate from dev
  • Loading branch information
neozhu authored Feb 11, 2022
2 parents e2c46b8 + 8fe0a66 commit aaa4c65
Show file tree
Hide file tree
Showing 89 changed files with 3,039 additions and 449 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,6 @@ MigrationBackup/

# Ionide (cross platform F# VS Code tools) working folder
.ionide/


**/Files/
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
# CleanArchitectureWithBlazorServer
This is a repository for creating a Blazor Server application following the principles of Clean Architecture
## Live Demo
- Blazor webassembly mode: https://mudblazor.dotnet6.cn/
- Blazor Server mode: https://mudblazor-s.dotnet6.cn/
## Screenshots
![doc/login_screenshot.png](doc/login_screenshot.png)
![doc/main_screenshot.png](doc/main_screenshot.png)
## Screenshots and video
![doc/main_screenshot.png](doc/main_screenshot.png)

## Development Enviroment
- Microsoft Visual Studio Community 2022 (64-bit)
- Docker
- .NET 6.0
## Code generation
- CleanArchitectureCodeGenerator
- https://github.com/neozhu/CleanArchitectureCodeGenerator
## Why develop with blazor server mode
- Develop fast
- Runing fast
- Most simple

## Characteristic
- Clean principles
- Simple principles
- Easy to start with

## About
Coming up.



## License
Apache 2.0
11 changes: 6 additions & 5 deletions src/Application/Application.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>CleanArchitecture.Blazor.Application</RootNamespace>
<AssemblyName>CleanArchitecture.Blazor.Application</AssemblyName>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
Expand All @@ -23,12 +24,12 @@
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="10.3.6" />
<PackageReference Include="LazyCache" Version="2.4.0" />
<PackageReference Include="LazyCache.AspNetCore" Version="2.4.0" />
<PackageReference Include="MediatR" Version="10.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.0" />
<PackageReference Include="MediatR" Version="10.0.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />
<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="6.0.2" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.2.15" />
</ItemGroup>

Expand Down
8 changes: 4 additions & 4 deletions src/Application/Common/Models/PaginatedData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace CleanArchitecture.Blazor.Application.Common.Models;

public class PaginatedData<T>
{
public int total { get; set; }
public IEnumerable<T> rows { get; set; }
public int TotalItems { get; set; }
public IEnumerable<T> Items { get; set; }
public PaginatedData(IEnumerable<T> items, int total)
{
this.rows = items;
this.total = total;
this.Items = items;
this.TotalItems = total;
}
public static async Task<PaginatedData<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
Expand Down
23 changes: 23 additions & 0 deletions src/Application/Common/Models/PaginationFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace CleanArchitecture.Blazor.Application.Common.Models;

public partial class PaginationFilter : BaseFilter
{
public int PageNumber { get; set; }
public int PageSize { get; set; }
public string OrderBy { get; set; }
public string SortDirection { get; set; }
}

public class BaseFilter
{
public Search AdvancedSearch { get; set; }

public string Keyword { get; set; }
}

public partial class Search
{
public ICollection<string> Fields { get; set; }
public string Keyword { get; set; }

}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace CleanArchitecture.Blazor.Application.Features.Products.Commands.AddEdit;

public class AddEditProductCommandValidator : AbstractValidator<AddEditProductCommand>
public class AddEditProductCommandValidator : AbstractValidator<AddEditProductCommand>
{
public AddEditProductCommandValidator()
{
public AddEditProductCommandValidator()
{
//TODO:Implementing AddEditProductCommandValidator method
//ex. RuleFor(v => v.Name)
// .MaximumLength(256)
// .NotEmpty();
throw new System.NotImplementedException();
}

RuleFor(v => v.Name)
.MaximumLength(256)
.NotEmpty();
RuleFor(v => v.Unit)
.MaximumLength(2)
.NotEmpty();
RuleFor(v => v.Price)
.GreaterThanOrEqualTo(0);

}

public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
{
var result = await ValidateAsync(ValidationContext<AddEditProductCommand>.CreateWithOptions((AddEditProductCommand)model, x => x.IncludeProperties(propertyName)));
if (result.IsValid)
return Array.Empty<string>();
return result.Errors.Select(e => e.ErrorMessage);
};
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace CleanArchitecture.Blazor.Application.Features.Products.Commands.Delete;
Expand All @@ -7,18 +7,18 @@ public class DeleteProductCommandValidator : AbstractValidator<DeleteProductComm
{
public DeleteProductCommandValidator()
{
//TODO:Implementing DeleteProductCommandValidator method
//ex. RuleFor(v => v.Id).NotNull().GreaterThan(0);
throw new System.NotImplementedException();

RuleFor(v => v.Id).NotNull().GreaterThan(0);

}
}
public class DeleteCheckedProductsCommandValidator : AbstractValidator<DeleteCheckedProductsCommand>
{
public DeleteCheckedProductsCommandValidator()
{
//TODO:Implementing DeleteProductCommandValidator method
//ex. RuleFor(v => v.Id).NotNull().NotEmpty();
throw new System.NotImplementedException();

RuleFor(v => v.Id).NotNull().NotEmpty();

}
}

Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,29 @@ IMapper mapper
}
public async Task<Result> Handle(ImportProductsCommand request, CancellationToken cancellationToken)
{
//TODO:Implementing ImportProductsCommandHandler method

var result = await _excelService.ImportAsync(request.Data, mappers: new Dictionary<string, Func<DataRow, ProductDto, object>>
{
//ex. { _localizer["Name"], (row,item) => item.Name = row[_localizer["Name"]]?.ToString() },

{ _localizer["Product Name"], (row,item) => item.Name = row[_localizer["Product Name"]]?.ToString() },
{ _localizer["Description"], (row,item) => item.Description = row[_localizer["Description"]]?.ToString() },
{ _localizer["Unit"], (row,item) => item.Unit = row[_localizer["Unit"]]?.ToString() },
{ _localizer["Price of unit"], (row,item) => item.Price =row.IsNull(_localizer["Price of unit"])? 0m:Convert.ToDecimal(row[_localizer["Price of unit"]]) },
{ _localizer["Pictures"], (row,item) => item.Pictures =row.IsNull(_localizer["Pictures"])? null:row[_localizer["Pictures"]].ToString().Split(",").ToList() },
}, _localizer["Products"]);
throw new System.NotImplementedException();
if (result.Succeeded)
{
foreach(var dto in result.Data)
{
var item = _mapper.Map<Product>(dto);
await _context.Products.AddAsync(item,cancellationToken);
}
await _context.SaveChangesAsync(cancellationToken);
return Result.Success();
}
else
{
return Result.Failure(result.Errors);
}
}
public async Task<byte[]> Handle(CreateProductsTemplateCommand request, CancellationToken cancellationToken)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace CleanArchitecture.Blazor.Application.Features.Products.Commands.Import;
Expand All @@ -7,11 +7,11 @@ public class ImportProductsCommandValidator : AbstractValidator<ImportProductsCo
{
public ImportProductsCommandValidator()
{
//TODO:Implementing ImportProductCommandValidator method
//ex. RuleFor(v => v.Data)
// .NotNull()
// .NotEmpty();
throw new System.NotImplementedException();

RuleFor(v => v.Data)
.NotNull()
.NotEmpty();

}
}

8 changes: 5 additions & 3 deletions src/Application/Features/Products/DTOs/ProductDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ namespace CleanArchitecture.Blazor.Application.Features.Products.DTOs;
public class ProductDto:IMapFrom<Product>
{

public TrackingState TrackingState { get; set; }
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? Unit { get; set; }
public decimal Price { get; set; }
public IList<string>? Pictures { get; set; }
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.


Expand All @@ -8,10 +8,10 @@ namespace CleanArchitecture.Blazor.Application.Features.Products.Queries.Export;

public class ExportProductsQuery : IRequest<byte[]>
{
public string FilterRules { get; set; }
public string Sort { get; set; } = "Id";
public string Order { get; set; } = "desc";
}
public string OrderBy { get; set; } = "Id";
public string SortDirection { get; set; } = "Desc";
public string Keyword { get; set; } = String.Empty;
}

public class ExportProductsQueryHandler :
IRequestHandler<ExportProductsQuery, byte[]>
Expand All @@ -36,16 +36,18 @@ IStringLocalizer<ExportProductsQueryHandler> localizer

public async Task<byte[]> Handle(ExportProductsQuery request, CancellationToken cancellationToken)
{
//TODO:Implementing ExportProductsQueryHandler method
var filters = PredicateBuilder.FromFilter<Product>(request.FilterRules);
var data = await _context.Products.Where(filters)
.OrderBy("{request.Sort} {request.Order}")
var data = await _context.Products.Where(x=>x.Name.Contains(request.Keyword) || x.Description.Contains(request.Keyword))
.OrderBy($"{request.OrderBy} {request.SortDirection}")
.ProjectTo<ProductDto>(_mapper.ConfigurationProvider)
.ToListAsync(cancellationToken);
var result = await _excelService.ExportAsync(data,
new Dictionary<string, Func<ProductDto, object>>()
{
//{ _localizer["Id"], item => item.Id },
{ _localizer["Product Name"], item => item.Name },
{ _localizer["Description"], item => item.Description },
{ _localizer["Price of unit"], item => item.Price },
{ _localizer["Unit"], item => item.Unit },
{ _localizer["Pictures"], item => item.Pictures!=null?string.Join(",",item.Pictures):null },
}
, _localizer["Products"]);
return result;
Expand Down
Loading

0 comments on commit aaa4c65

Please sign in to comment.