什么是DNTFrameworkCore ?
DNTFrameworkCore是一种基于ASP.NET Core的高质量Web应用程序的轻巧且可扩展的基础架构,并具有以下目标:
- 在各种应用中的常见结构,例如横切问题等
- 遵循干燥原则以关注主要业务逻辑
- 减少开发时间
- 较少的错误和停止错误传播
- 减少对OOP和OOD了解的新开发人员的培训时间
基于Crud的思维
申请服务
public interface IBlogService : IEntityService < int , BlogModel >
{
}
public class BlogService : EntityService < Blog , int , BlogModel > , IBlogService
{
private readonly IMapper _mapper ;
public BlogService (
IDbContext dbContext ,
IEventBus bus ,
IMapper mapper ) : base ( dbContext , bus )
{
_mapper = mapper ?? throw new ArgumentNullException ( nameof ( mapper ) ) ;
}
public override Task < IPagedResult < BlogModel > > FetchPagedListAsync ( FilteredPagedRequest request ,
CancellationToken cancellationToken = default )
{
return EntitySet . AsNoTracking ( )
. Select ( b => new BlogModel
{
Id = b . Id ,
Version = b . Version ,
Url = b . Url ,
Title = b . Title
} ) . ToPagedListAsync ( request , cancellationToken ) ;
}
protected override void MapToEntity ( BlogModel model , Blog blog )
{
_mapper . Map ( model , blog ) ;
}
protected override BlogModel MapToModel ( Blog blog )
{
return _mapper . Map < BlogModel > ( blog ) ;
}
}ASP.NET Core WebAPI
[ Route ( "api/[controller]" ) ]
public class BlogsController : EntityController < IBlogService , int , BlogModel >
{
public BlogsController ( IBlogService service ) : base ( service )
{
}
protected override string CreatePermissionName => PermissionNames . Blogs_Create ;
protected override string EditPermissionName => PermissionNames . Blogs_Edit ;
protected override string ViewPermissionName => PermissionNames . Blogs_View ;
protected override string DeletePermissionName => PermissionNames . Blogs_Delete ;
}ASP.NET核心MVC
public class BlogsController : EntityController < IBlogService , int , BlogModel >
{
public BlogsController ( IBlogService service ) : base ( service )
{
}
protected override string CreatePermissionName => PermissionNames . Blogs_Create ;
protected override string EditPermissionName => PermissionNames . Blogs_Edit ;
protected override string ViewPermissionName => PermissionNames . Blogs_View ;
protected override string DeletePermissionName => PermissionNames . Blogs_Delete ;
protected override string ViewName => "_BlogPartial" ;
}_blogpartial.cshtml
@inherits EntityFormRazorPage < BlogModel > @{ Layout = " _EntityFormLayout " ; EntityName = " Blog " ; DeletePermission = PermissionNames . Blogs_Delete ; CreatePermission = PermissionNames . Blogs_Create ; EditPermission = PermissionNames . Blogs_Edit ; EntityDisplayName = " Blog " ; } < div class = " form-group row " > < div class = " col col-md-8 " > < label asp-for = " Title " class = " col-form-label text-md-left " > label > < input asp-for = " Title " autocomplete = " off " class = " form-control " /> < span asp-validation-for = " Title " class = " text-danger " > span > div > div > < div class = " form-group row " > < div class = " col " > < label asp-for = " Url " class = " col-form-label text-md-left " > label > < input asp-for = " Url " class = " form-control " type = " url " /> < span asp-validation-for = " Url " class = " text-danger " > span > div > div >
安装
要根据DNTFrameworkCore创建您的第一个项目,您可以安装以下软件包:
PM> Install-Package DNTFrameworkCore
PM> Install-Package DNTFrameworkCore .EFCore
PM> Install-Package DNTFrameworkCore .EFCore.SqlServer
PM> Install-Package DNTFrameworkCore .Web
PM> Install-Package DNTFrameworkCore .Web.Tenancy
PM> Install-Package DNTFrameworkCore .Web.EFCore
PM> Install-Package DNTFrameworkCore .Licensing
PM> Install-Package DNTFrameworkCore .FluentValidation
或者
1-运行以下命令以基于ASP.NET Core Web API和DNTFrameworkCore安装样板项目模板:
dotnet new --install DNTFrameworkCore TemplateAPI::*
2-使用安装模板创建新项目:
dotnet new dntcore-api
现在,您有了下面的解决方案,其中包含完整的身份管理功能包括用户,角色和动态许可管理,并与持续的JWT身份验证机制集成在一起:
有关模板的更多信息,您可以观看DNTFrameworkCore模板存储库
特征
- 应用程序输入验证
- 交易管理
- 事件
- EntityGraph Tracking(Master-detail)
- 编号
- 功能编程错误处理
- 许可授权
- 实体服务
- EntityController(API和MVC)
- 基于EFCORE的DBLOGGER提供商
- protectionKey Efcore商店
- 钩子
- SoftDelete
- 租赁
- 跟踪机制(iCreationTracking,Imodification Tracking)
- 荧光验证整合
- BackowdTaskqueue
- Rowintegrity
- 起始仪机制
- CQRS(即将推出)
- 实体历史(即将推出)
用法
DNTFrameworkCore .testapi完成ASP.NET核心Web API
创建实体
public class Task : Entity < int > , INumberedEntity , IHasRowVersion , IHasRowIntegrity , ICreationTracking , IModificationTracking
{
public const int MaxTitleLength = 256 ;
public const int MaxDescriptionLength = 1024 ;
public string Title { get ; set ; }
public string NormalizedTitle { get ; set ; }
public string Number { get ; set ; }
public string Description { get ; set ; }
public TaskState State { get ; set ; } = TaskState . Todo ;
public byte [ ] Version { get ; set ; }
}实现从DBContextCore继承的ProjectDbContext
public class ProjectDbContext : DbContextCore
{
public ProjectDbContext ( DbContextOptions < ProjectDbContext > options , IEnumerable < IHook > hooks ) : base ( options , hooks )
{
}
protected override void OnModelCreating ( ModelBuilder modelBuilder )
{
modelBuilder . ApplyConfigurationsFromAssembly ( Assembly . GetExecutingAssembly ( ) ) ;
modelBuilder . AddJsonFields ( ) ;
modelBuilder . AddTrackingFields < long > ( ) ;
modelBuilder . AddIsDeletedField ( ) ;
modelBuilder . AddRowVersionField ( ) ;
modelBuilder . AddRowIntegrityField ( ) ;
modelBuilder . NormalizeDateTime ( ) ;
modelBuilder . NormalizeDecimalPrecision ( ) ;
base . OnModelCreating ( modelBuilder ) ;
}
}创建模型/DTO
[ LocalizationResource ( Name = "SharedResource" , Location = " DNTFrameworkCore .TestAPI" ) ] public class TaskModel : MasterModel < int > , IValidatableObject { public string Title { get ; set ; } [ MaxLength ( 50 , ErrorMessage = "Validation from DataAnnotations" ) ] public string Number { get ; set ; } public string Description { get ; set ; } public TaskState State { get ; set ; } = TaskState . Todo ; public IEnumerable < ValidationResult > Validate ( ValidationContext validationContext ) { if ( Title == "IValidatableObject" ) { yield return new ValidationResult ( "Validation from IValidatableObject" ) ; } } }
注意:基于验证基础结构,您可以使用多种方法验证模型/DTO,使用DataAnnotation ValidateAttribute,实现IvalIdatableObject,或实现DNTFrameworkCore软件包中存在的Imodelvalidator。
public class TaskValidator : ModelValidator < TaskModel >
{
public override IEnumerable < ModelValidationResult > Validate ( TaskModel model )
{
if ( ! Enum . IsDefined ( typeof ( TaskState ) , model . State ) )
{
yield return new ModelValidationResult ( nameof ( TaskModel . State ) , "Validation from IModelValidator" ) ;
}
}
}同样,在大多数情况下,一种模型/DTO可以满足您对创建/编辑/查看实体的要求。但是,您可以创建以下方式创建重新模型:
public class TaskReadModel : ReadModel < int >
{
public string Title { get ; set ; }
public string Number { get ; set ; }
public TaskState State { get ; set ; } = TaskState . Todo ;
}实施服务
public interface ITaskService : IEntityService < int , TaskReadModel , TaskModel , TaskFilteredPagedRequest >
{
}
public class TaskService : EntityService < Task , int , TaskReadModel , TaskModel , TaskFilteredPagedRequest > ,
ITaskService
{
private readonly IMapper _mapper ;
public TaskService ( IDbContext dbContext , IEventBus bus , IMapper mapper ) : base ( dbContext , bus )
{
_mapper = mapper ?? throw new ArgumentNullException ( nameof ( mapper ) ;
}
public override Task < IPagedResult < TaskReadModel > > FetchPagedListAsync ( TaskFilteredPagedRequest request ,
CancellationToken cancellationToken = default )
{
return EntitySet . AsNoTracking ( )
. WhereIf ( model . State . HasValue , t => t . State == model . State )
. Select ( t => new TaskReadModel
{
Id = t . Id ,
Title = t . Title ,
State = t . State ,
Number = t . Number
} ) . ToPagedListAsync ( request , cancellationToken ) ;
}
protected override void MapToEntity ( TaskModel model , Task task )
{
_mapper . Map ( model , task ) ;
}
protected override TaskModel MapToModel ( Task task )
{
return _mapper . Map < TaskModel > ( task ) ;
}
}在DNTFrameworkCore .efcore中,自动应用程序或其他映射器库没有依赖性,然后您可以通过实现maptomodel和maptoentity抽象方法来手动进行映射。
实现API控制器
[ Route ( "api/[controller]" ) ]
public class
TasksController : EntityController < ITaskService , int , TaskReadModel , TaskModel , TaskFilteredPagedRequest >
{
public TasksController ( ITaskService service ) : base ( service )
{
}
protected override string CreatePermissionName => PermissionNames . Tasks_Create ;
protected override string EditPermissionName => PermissionNames . Tasks_Edit ;
protected override string ViewPermissionName => PermissionNames . Tasks_View ;
protected override string DeletePermissionName => PermissionNames . Tasks_Delete ;
} [ Route ( "api/[controller]" ) ]
public class BlogsController : EntityController < IBlogService , int , BlogModel >
{
public BlogsController ( IBlogService service ) : base ( service )
{
}
protected override string CreatePermissionName => PermissionNames . Blogs_Create ;
protected override string EditPermissionName => PermissionNames . Blogs_Edit ;
protected override string ViewPermissionName => PermissionNames . Blogs_View ;
protected override string DeletePermissionName => PermissionNames . Blogs_Delete ;
} 基于任务的思维
丰富的领域模型
public class PriceType : Entity < long > , IAggregateRoot { private PriceType ( Title title ) { Title = title ; } public PriceType ( Title title , IPriceTypePolicy policy ) { if ( title == null ) throw new ArgumentNullException ( nameof ( title ) ) ; if ( policy == null ) throw new ArgumentNullException ( nameof ( policy ) ) ; Title = title ; if ( ! policy . IsUnique ( this ) ) ThrowDomainException ( "PriceType Title Should Be Unique" ) ; AddDomainEvent ( new PriceTypeCreatedDomainEvent ( this ) ) ; } public Title Title { get ; private set ; } // public static ResultNew(Title title, IPriceTypePolicy policy) // { // if (title == null) throw new ArgumentNullException(nameof(title)); // if (policy == null) throw new ArgumentNullException(nameof(policy)); // // var priceType = new PriceType(title); // if (!policy.IsUnique(priceType)) return Fail("PriceType Title Should Be Unique"); // // priceType.AddDomainEvent(new PriceTypeCreatedDomainEvent(priceType)); // // return Ok(priceType); // } }
ValueObject