什么是DNTFrameworkCore ?
DNTFrameworkCore是一种基于ASP.NET Core的高质量Web应用程序的轻巧且可扩展的基础架构,并具有以下目标:
基于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创建您的第一个项目,您可以安装以下软件包:
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
\”>
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
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");
}
}
}\”>
[ 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 Result<PriceType> New(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>(\"PriceType Title Should Be Unique\"); // // priceType.AddDomainEvent(new PriceTypeCreatedDomainEvent(priceType)); // // return Ok(priceType); // } }
ValueObject
public class Title : ValueObject
{
private Title ( )
{
}public Title ( string value )
{
value ??= string . Empty ;switch ( value . Length )
{
case 0 :
ThrowDomainException ( \"title should not be empty\" ) ;
break ;
case > 100 :
ThrowDomainException ( \"title is too long\" ) ;
break ;
}
}public string Value { get ; private set ; }
protected override IEnumerable < object > EqualityValues
{
get { <spa
