Maison > Article > développement back-end > Explication détaillée du didacticiel d'introduction ABP de la série ABP du cadre de développement de modèles ASP.NET
ABP est un point de départ pour de nouvelles applications Web modernes utilisant les meilleures pratiques et utilisant les outils les plus populaires. Peut être utilisé comme cadre de base ou modèle de projet pour des applications à usage général. Ensuite, cet article vous donnera une introduction détaillée au didacticiel d'introduction à l'ABP. Les amis intéressés devraient y jeter un œil ensemble
ABP est l'abréviation de "ASP.NET Boilerplate Project (ASP.NET Sample Project)". .
ASP.NET Boilerplate est un nouveau point de départ pour développer des applications WEB modernes utilisant les meilleures pratiques et technologies populaires. Il vise à devenir un cadre d'application WEB et un modèle de projet universel.
Site officiel d'ABP : http://www.aspnetboilerplate.com
Projet open source d'ABP sur Github : https://github.com/aspnetboilerplate
L'origine de l'ABP
"DRY - éviter la duplication de code" est la chose la plus importante qu'un bon développeur ait lors du développement de logiciels. Une des pensées. Nous avons tous des besoins similaires lors du développement d'applications WEB d'entreprise, telles que les pages de connexion, la gestion des utilisateurs/rôles, la vérification des autorisations, la vérification de la validité des données, le multilingue/localisation, etc. Un logiciel à grande échelle de haute qualité utilisera certaines bonnes pratiques, telles que l'architecture en couches, la conception axée sur le domaine, l'injection de dépendances, etc. Nous pouvons également utiliser des outils tels que ORM, migrations de bases de données et journalisation.
Créer une application d'entreprise à partir de zéro est une tâche fastidieuse car de nombreuses tâches de base courantes doivent être répétées. De nombreuses entreprises développent leurs propres frameworks d'applications à réutiliser dans différents projets, puis développent de nouvelles fonctionnalités basées sur ce framework. Mais toutes les entreprises ne disposent pas d’une telle force. Si nous pouvions partager davantage, nous pourrions peut-être éviter d'avoir à écrire du code similaire à plusieurs reprises pour chaque entreprise ou chaque projet. La raison pour laquelle l'auteur a nommé le projet « ASP.NET Boilerplate » est qu'il espère qu'il pourra devenir un nouveau point de départ pour le développement d'applications WEB d'entreprise générales et utiliser directement ABP comme modèle de projet.
Qu'est-ce que l'ABP ?
ABP est un point de départ pour de nouvelles applications Web modernes utilisant les meilleures pratiques et utilisant les outils les plus populaires. Peut être utilisé comme cadre de base ou modèle de projet pour des applications à usage général. Ses fonctionnalités incluent :
Côté serveur :
Basé sur la dernière technologie .NET (actuellement ASP.NET MVC 5, Web API 2, C# 5.0, sera mis à niveau après la sortie officielle d'ASP.NET 5)
Implémenter la conception basée sur le domaine (entités, entrepôts, services de domaine, événements de domaine, services d'application, objets de transfert de données , unités de travail, etc.)
La mise en œuvre d'une architecture en couches (couche de domaine, couche d'application, couche de présentation et couche d'infrastructure) fournit une infrastructure pour développer des modules réutilisables et configurables pour intégrer certains des plus frameworks/bibliothèques open source populaires, peut-être que vous en utilisez certains.
Fournit une infrastructure qui nous permet d'utiliser facilement l'injection de dépendances (en utilisant Castle Windsor comme conteneur d'injection de dépendances)
Fournit un entreposage de référentiel Le mode prend en charge différents ORM (Entity Framework, NHibernate, MangoDb et une base de données en mémoire ont été implémentés)
Prend en charge et implémente la migration de base de données (le code d'EF en premier) le développement modulaire (chaque module a un EF DbContext indépendant , la base de données peut être spécifiée séparément)
Comprend un système multilingue/localisation simple et flexible
Comprend un EventBus Implémente une gestion unifiée des exceptions de événements de domaine globaux côté serveur (la couche application n'a presque pas besoin d'écrire son propre code de gestion des exceptions)
Vérification de la validité des données (Asp.NET MVC ne peut effectuer que la vérification des paramètres d'action de la méthode, ABP implémente la vérification de la validité des paramètres de la méthode de la couche Application)
Créer automatiquement la couche Web Api via les services d'application (pas besoin d'écrire la couche ApiController)
Fournir des classes de base et des classes d'assistance pour nous permettre de mettre en œuvre facilement certaines tâches courantes
Utiliser le « principe de la convention sur la configuration »
Client :
Bootstrap, Less, AngularJs, jQuery, Modernizr et autres bibliothèques JS : jQuery.validate, jQuery.form, jQuery.blockUI, json2 , etc.
Fournit des modèles de projet pour les applications monopage (AngularJs, Durandaljs) et les applications multipages (Bootstrap+Jquery).
Créez automatiquement une couche proxy Javascript pour faciliter l'utilisation de Web Api pour encapsuler certaines fonctions Javascript et pour faciliter l'utilisation d'ajax, des boîtes de message, des composants de notification et du masque d'état occupé. couches, etc.
En plus du projet de framework ABP, un module nommé "Zéro" a également été développé, qui implémente les fonctions suivantes :
Gestion de l'authentification et des autorisations (mise en œuvre via ASP.NET Identity)
Gestion des utilisateurs et des rôles Paramètres du système Gestion des accès (niveau système, niveau locataire, niveau utilisateur , périmètre de gestion automatique)
Journal d'audit (enregistre automatiquement l'appelant et les paramètres de chaque interface)
Qu'est-ce que ABP non ?
ABP fournit un modèle de développement d'applications pour les meilleures pratiques. Il propose des classes, des interfaces et des outils de base qui facilitent la création d'applications maintenables à grande échelle.
Cependant :
Ce n'est pas un des outils RAD, conçus pour créer des applications sans codage. Au lieu de cela, ABP fournit une bonne pratique de codage.
Ce n'est pas un outil de génération de code. Bien qu'il dispose de certaines fonctionnalités permettant de créer du code dynamique au moment de l'exécution, il ne peut pas générer de code.
Ce n'est pas un framework tout-en-un. Au lieu de cela, il utilise des outils/bibliothèques populaires pour des tâches spécifiques (par exemple EF pour ORM, Log4Net pour la journalisation, Castle Windsor comme conteneur d'injection de dépendances, AngularJs pour le framework SPA).
D'après mon expérience d'utilisation d'ABP depuis plusieurs mois, bien qu'ABP ne soit pas RAD, développer des projets qui l'utilisent est nettement beaucoup plus rapide que l'architecture traditionnelle à trois niveaux.
Bien qu'ABP ne soit pas un outil de génération de code, de ce fait, le code de notre projet est plus concis et standardisé, ce qui est propice à l'utilisation d'outils de génération de code.
J'ai utilisé le générateur de code développé par Scaffolder+T4 de VS2013, qui peut générer automatiquement tous les codes et bases de données front-end et back-end basés sur le diagramme de classes UML des objets de domaine. Un simple module CURD ne nécessite presque rien. codage et a des activités complexes. Le module logique complète principalement le code de la couche de domaine. De cette façon, vous pouvez consacrer plus de temps à la conception du modèle de domaine et réduire le temps d’écriture du code.
Ce qui suit utilise l'exemple "Simple Task System" de l'auteur original pour montrer comment utiliser ABP pour développer des projets
Créer une application Web vide à partir d'un modèle
ABP fournit un modèle de démarrage pour les nouveaux projets (bien que vous puissiez créer le projet manuellement et obtenir le package ABP depuis nuget, la méthode du modèle est plus simple).
Allez sur www.aspnetboilerplate.com/Templates pour créer votre application à partir de modèles.
Vous pouvez choisir SPA (AngularJs ou DurandalJs) ou choisir le projet MPA (application multipage classique). Vous pouvez choisir Entity Framework ou NHibernate comme framework ORM.
Ici on choisit AngularJs et Entity Framework, renseignez le nom du projet "SimpleTaskSystem", cliquez sur le bouton "CREATE MY PROJECT" pour télécharger un package zip, décompressez-le pour obtenir la solution VS2013, la version .NET utilisée est 4.5.1.
Les composants Abp et autres composants tiers sont référencés dans chaque projet et doivent être téléchargés depuis Nuget.
L'icône de point d'exclamation jaune indique que ce composant n'existe pas dans le dossier local et doit être restauré à partir de Nuget. Le fonctionnement est le suivant :
Pour exécuter le projet, vous devez créer une base de données. Ce modèle suppose que vous utilisez SQL2008 ou une version plus récente. Bien entendu, elle peut également être facilement remplacée par d’autres bases de données relationnelles.
Ouvrez le fichier Web.Config pour afficher et configurer la chaîne de lien :
<add name="Default" connectionString="Server=localhost; Database=SimpleTaskSystemDb; Trusted_Connection=True;" />
(lors de l'utilisation du code EF pour la première migration de données plus tard, une base de données nommé SimpleTaskSystemDb sera automatiquement créé dans la base de données SQL Server)
Ça y est, le projet est prêt à fonctionner ! Ouvrez VS2013 et appuyez sur F5 :
Ce qui suit mettra en œuvre ce programme de système de tâches simple étape par étape
Créer des entités
Écrivez la classe d'entité dans le projet Core, car l'entité fait partie de la couche de domaine.
Un scénario d'application simple : créez des tâches et attribuez-les à des personnes. Nous avons besoin de deux entités, Task et Person.
L'entité de tâche possède plusieurs attributs : description (Description), heure de création (CreationTime), statut de la tâche (State) et attribut de navigation facultatif (AssignedPerson) pour référencer la personne.
public class Task : Entity<long> { [ForeignKey("AssignedPersonId")] public virtual Person AssignedPerson { get; set; } public virtual int? AssignedPersonId { get; set; } public virtual string Description { get; set; } public virtual DateTime CreationTime { get; set; } public virtual TaskState State { get; set; } public Task() { CreationTime = DateTime.Now; State = TaskState.Active; } }
L'entité Personne est plus simple et définit uniquement un attribut Nom :
public class Person : Entity { public virtual string Name { get; set; } }
dans ABP Dans le framework, il existe une classe de base Entity, qui possède un attribut Id. Étant donné que la classe Task hérite de Entity4db15037c2d45d75b28ec2b6a696f099, elle a un identifiant de type long. La classe Person a un identifiant de type int, car le type int est le type par défaut de l'identifiant de la classe de base Entity. Lorsque le type n'est pas spécifié, l'identifiant de l'entité est de type int.
Créer DbContext
Pour utiliser EntityFramework, vous devez d'abord définir la classe DbContext. Le modèle ABP a déjà créé le fichier DbContext. il suffit d'ajouter la classe de tâche et de personne ajoutée à IDbSet, veuillez consulter le code :
public class SimpleTaskSystemDbContext : AbpDbContext { public virtual IDbSet<Task> Tasks { get; set; } public virtual IDbSet<Person> People { get; set; } public SimpleTaskSystemDbContext() : base("Default") { } public SimpleTaskSystemDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } }
通过Database Migrations创建数据库表
我们使用EntityFramework的Code First模式创建数据库架构。ABP模板生成的项目已经默认开启了数据迁移功能,我们修改SimpleTaskSystem.EntityFramework项目下Migrations文件夹下的Configuration.cs文件:
internal sealed class Configuration : DbMigrationsConfiguration<SimpleTaskSystem.EntityFramework.SimpleTaskSystemDbContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(SimpleTaskSystem.EntityFramework.SimpleTaskSystemDbContext context) { context.People.AddOrUpdate( p => p.Name, new Person {Name = "Isaac Asimov"}, new Person {Name = "Thomas More"}, new Person {Name = "George Orwell"}, new Person {Name = "Douglas Adams"} ); } }
在VS2013底部的“程序包管理器控制台”窗口中,选择默认项目并执行命令“Add-Migration InitialCreate”
会在Migrations文件夹下生成一个xxxx-InitialCreate.cs文件,内容如下:
public partial class InitialCreate : DbMigration { public override void Up() { CreateTable( "dbo.StsPeople", c => new { Id = c.Int(nullable: false, identity: true), Name = c.String(), }) .PrimaryKey(t => t.Id); CreateTable( "dbo.StsTasks", c => new { Id = c.Long(nullable: false, identity: true), AssignedPersonId = c.Int(), Description = c.String(), CreationTime = c.DateTime(nullable: false), State = c.Byte(nullable: false), }) .PrimaryKey(t => t.Id) .ForeignKey("dbo.StsPeople", t => t.AssignedPersonId) .Index(t => t.AssignedPersonId); } public override void Down() { DropForeignKey("dbo.StsTasks", "AssignedPersonId", "dbo.StsPeople"); DropIndex("dbo.StsTasks", new[] { "AssignedPersonId" }); DropTable("dbo.StsTasks"); DropTable("dbo.StsPeople"); } }
然后继续在“程序包管理器控制台”执行“Update-Database”,会自动在数据库创建相应的数据表:
PM> Update-Database
数据库显示如下:
(以后修改了实体,可以再次执行Add-Migration和Update-Database,就能很轻松的让数据库结构与实体类的同步)
定义仓储接口
通过仓储模式,可以更好把业务代码与数据库操作代码更好的分离,可以针对不同的数据库有不同的实现类,而业务代码不需要修改。
定义仓储接口的代码写到Core项目中,因为仓储接口是领域层的一部分。
我们先定义Task的仓储接口:
public interface ITaskRepository : IRepository<Task, long> {
它继承自ABP框架中的IRepository泛型接口。
在IRepository中已经定义了常用的增删改查方法:
所以ITaskRepository默认就有了上面那些方法。可以再加上它独有的方法GetAllWithPeople(...)。
不需要为Person类创建一个仓储类,因为默认的方法已经够用了。ABP提供了一种注入通用仓储的方式,将在后面“创建应用服务”一节的TaskAppService类中看到。
实现仓储类
我们将在EntityFramework项目中实现上面定义的ITaskRepository仓储接口。
通过模板建立的项目已经定义了一个仓储基类:SimpleTaskSystemRepositoryBase(这是一种比较好的实践,因为以后可以在这个基类中添加通用的方法)。
public class TaskRepository : SimpleTaskSystemRepositoryBase<Task, long>, ITaskRepository { public List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state) { //在仓储方法中,不用处理数据库连接、DbContext和数据事务,ABP框架会自动处理。 var query = GetAll(); //GetAll() 返回一个 IQueryable<T>接口类型 //添加一些Where条件 if (assignedPersonId.HasValue) { query = query.Where(task => task.AssignedPerson.Id == assignedPersonId.Value); } if (state.HasValue) { query = query.Where(task => task.State == state); } return query .OrderByDescending(task => task.CreationTime) .Include(task => task.AssignedPerson) .ToList(); } }
TaskRepository继承自SimpleTaskSystemRepositoryBase并且实现了上面定义的ITaskRepository接口。
创建应用服务(Application Services)
在Application项目中定义应用服务。首先定义Task的应用服务层的接口:
public interface ITaskAppService : IApplicationService { GetTasksOutput GetTasks(GetTasksInput input); void UpdateTask(UpdateTaskInput input); void CreateTask(CreateTaskInput input); }
ITaskAppService继承自IApplicationService,ABP自动为这个类提供一些功能特性(比如依赖注入和参数有效性验证)。
然后,我们写TaskAppService类来实现ITaskAppService接口:
public class TaskAppService : ApplicationService, ITaskAppService { private readonly ITaskRepository _taskRepository; private readonly IRepository<Person> _personRepository; /// <summary> /// 构造函数自动注入我们所需要的类或接口 /// </summary> public TaskAppService(ITaskRepository taskRepository, IRepository<Person> personRepository) { _taskRepository = taskRepository; _personRepository = personRepository; } public GetTasksOutput GetTasks(GetTasksInput input) { //调用Task仓储的特定方法GetAllWithPeople var tasks = _taskRepository.GetAllWithPeople(input.AssignedPersonId, input.State); //用AutoMapper自动将List<Task>转换成List<TaskDto> return new GetTasksOutput { Tasks = Mapper.Map<List<TaskDto>>(tasks) }; } public void UpdateTask(UpdateTaskInput input) { //可以直接Logger,它在ApplicationService基类中定义的 Logger.Info("Updating a task for input: " + input); //通过仓储基类的通用方法Get,获取指定Id的Task实体对象 var task = _taskRepository.Get(input.TaskId); //修改task实体的属性值 if (input.State.HasValue) { task.State = input.State.Value; } if (input.AssignedPersonId.HasValue) { task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value); } //我们都不需要调用Update方法 //因为应用服务层的方法默认开启了工作单元模式(Unit of Work) //ABP框架会工作单元完成时自动保存对实体的所有更改,除非有异常抛出。有异常时会自动回滚,因为工作单元默认开启数据库事务。 } public void CreateTask(CreateTaskInput input) { Logger.Info("Creating a task for input: " + input); //通过输入参数,创建一个新的Task实体 var task = new Task { Description = input.Description }; if (input.AssignedPersonId.HasValue) { task.AssignedPersonId = input.AssignedPersonId.Value; } //调用仓储基类的Insert方法把实体保存到数据库中 _taskRepository.Insert(task); } }
TaskAppService使用仓储进行数据库操作,它通往构造函数注入仓储对象的引用。
数据验证
如果应用服务(Application Service)方法的参数对象实现了IInputDto或IValidate接口,ABP会自动进行参数有效性验证。
CreateTask方法有一个CreateTaskInput参数,定义如下:
public class CreateTaskInput : IInputDto { public int? AssignedPersonId { get; set; } [Required] public string Description { get; set; } }
Description属性通过注解指定它是必填项。也可以使用其他 Data Annotation 特性。
如果你想使用自定义验证,你可以实现ICustomValidate 接口:
public class UpdateTaskInput : IInputDto, ICustomValidate { [Range(1, long.MaxValue)] public long TaskId { get; set; } public int? AssignedPersonId { get; set; } public TaskState? State { get; set; } public void AddValidationErrors(List<ValidationResult> results) { if (AssignedPersonId == null && State == null) { results.Add(new ValidationResult("AssignedPersonId和State不能同时为空!", new[] { "AssignedPersonId", "State" })); } } }
你可以在AddValidationErrors方法中写自定义验证的代码。
创建Web Api服务
ABP可以非常轻松地把Application Service的public方法发布成Web Api接口,可以供客户端通过ajax调用。
DynamicApiControllerBuilder .ForAll<IApplicationService>(Assembly.GetAssembly(typeof (SimpleTaskSystemApplicationModule)), "tasksystem") .Build();
SimpleTaskSystemApplicationModule这个程序集中所有继承了IApplicationService接口的类,都会自动创建相应的ApiController,其中的公开方法,就会转换成WebApi接口方法。
可以通过http://xxx/api/services/tasksystem/Task/GetTasks这样的路由地址进行调用。
通过上面的案例,大致介绍了领域层、基础设施层、应用服务层的用法。
现在,可以在ASP.NET MVC的Controller的Action方法中直接调用Application Service的方法了。
Si vous utilisez la programmation SPA monopage, vous pouvez appeler directement la méthode Application Service correspondante via ajax sur le client (en créant une API Web dynamique).
Résumé
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!