Ausführliche Erläuterung des ABP-Einführungs-Tutorials der ABP-Reihe des ASP.NET-Vorlagenentwicklungsframeworks

黄舟
Freigeben: 2017-10-14 10:00:27
Original
8248 Leute haben es durchsucht

ABP ist ein Ausgangspunkt für neue moderne Webanwendungen unter Verwendung von Best Practices und der Verwendung der beliebtesten Tools. Kann als Basis-Framework oder Projektvorlage für allgemeine Anwendungen verwendet werden. Als nächstes erhalten Sie in diesem Artikel eine detaillierte Einführung in das ABP-Einführungs-Tutorial. Interessierte Freunde sollten einen Blick darauf werfen.

ABP ist die Abkürzung für „ASP.NET Boilerplate Project (ASP.NET Sample Project)“. .

ASP.NET Boilerplate ist ein neuer Ausgangspunkt für die Entwicklung moderner WEB-Anwendungen unter Verwendung von Best Practices und gängigen Technologien. Ziel ist es, ein universelles WEB-Anwendungsframework und eine Projektvorlage zu werden.

Offizielle Website von ABP: http://www.aspnetboilerplate.com

Open-Source-Projekt von ABP auf Github: https://github.com/aspnetboilerplate

Der Ursprung von ABP

„DRY – Duplizierung von Code vermeiden“ ist das Wichtigste, was ein guter Entwickler bei der Entwicklung von Software hat. Einer der Gedanken. Wir alle haben ähnliche Anforderungen bei der Entwicklung von Unternehmens-WEB-Anwendungen, wie Anmeldeseiten, Benutzer-/Rollenverwaltung, Berechtigungsüberprüfung, Überprüfung der Datengültigkeit, Mehrsprachigkeit/Lokalisierung usw. Eine hochwertige, groß angelegte Software verwendet einige Best Practices, wie z. B. mehrschichtige Architektur, domänengesteuertes Design, Abhängigkeitsinjektion usw. Wir können auch Tools wie ORM, Datenbankmigrationen und Protokollierung verwenden.

Das Erstellen einer Unternehmensanwendung von Grund auf ist eine mühsame Aufgabe, da viele allgemeine Grundaufgaben wiederholt werden müssen. Viele Unternehmen entwickeln ihre eigenen Anwendungsframeworks zur Wiederverwendung in verschiedenen Projekten und entwickeln dann einige neue Funktionen basierend auf dem Framework. Aber nicht jedes Unternehmen verfügt über eine solche Stärke. Wenn wir mehr teilen könnten, könnten wir vielleicht vermeiden, für jedes Unternehmen oder jedes Projekt wiederholt ähnlichen Code schreiben zu müssen. Der Autor nannte das Projekt „ASP.NET Boilerplate“, weil er hofft, dass es ein neuer Ausgangspunkt für die Entwicklung allgemeiner Unternehmens-WEB-Anwendungen werden und ABP direkt als Projektvorlage verwenden kann.

Was ist ABP?

ABP ist ein Ausgangspunkt für neue moderne Webanwendungen unter Verwendung von Best Practices und unter Verwendung der beliebtesten Tools. Kann als Basis-Framework oder Projektvorlage für allgemeine Anwendungen verwendet werden. Zu seinen Funktionen gehören:

Serverseite:

  • Basierend auf der neuesten .NET-Technologie (derzeit ASP.NET MVC 5, Web API 2, C# 5.0, wird nach der offiziellen Veröffentlichung von ASP.NET 5 aktualisiert)

  • Domänengesteuertes Design implementieren (Entitäten, Warehousing, Domänendienste, Domänenereignisse, Anwendungsdienste, Datenübertragungsobjekte). , Arbeitseinheiten usw.)

  • Die Implementierung einer Schichtarchitektur (Domänenschicht, Anwendungsschicht, Präsentationsschicht und Infrastrukturschicht) bietet eine Infrastruktur zur Entwicklung wiederverwendbarer und konfigurierbarer Module zur Integration einiger der meisten Beliebte Open-Source-Frameworks/Bibliotheken, vielleicht verwenden Sie einige davon.

  • Bietet eine Infrastruktur, die uns die einfache Verwendung der Abhängigkeitsinjektion ermöglicht (unter Verwendung von Castle Windsor als Abhängigkeitsinjektionscontainer).

  • Bietet Repository-Warehousing. Der Modus unterstützt verschiedene ORMs (Entity Framework, NHibernate, MangoDb und In-Memory-Datenbank wurden implementiert)

  • Unterstützt und implementiert die Datenbankmigration (EFs Code zuerst) modulare Entwicklung (jedes Modul verfügt über einen unabhängigen EF DbContext , Datenbank kann separat angegeben werden)

  • Enthält ein einfaches und flexibles Mehrsprachen-/Lokalisierungssystem

  • Enthält einen EventBus. Implementieren Sie eine einheitliche Ausnahmebehandlung von globale Domänenereignisse auf der Serverseite (die Anwendungsschicht muss fast keinen eigenen Ausnahmebehandlungscode schreiben)

  • Überprüfung der Datengültigkeit (Asp.NET MVC kann nur die Überprüfung von Aktionsparametern durchführen Die Methode implementiert ABP die Überprüfung der Parametergültigkeit der Anwendungsschichtmethode)

  • Erstellen Sie automatisch die Web-API-Schicht über Application Services (die ApiController-Schicht muss nicht geschrieben werden)

  • Stellen Sie Basisklassen und Hilfsklassen bereit, damit wir einige allgemeine Aufgaben einfach implementieren können

  • Verwenden Sie das Prinzip „Konvention vor Konfiguration“

Client:

  • Bootstrap, Less, AngularJs, jQuery, Modernizr und andere JS-Bibliotheken: jQuery.validate, jQuery.form, jQuery.blockUI, json2 usw.

  • Bietet Projektvorlagen für einseitige Anwendungen (AngularJs, Durandaljs) und mehrseitige Anwendungen (Bootstrap+Jquery).

  • Erstellen Sie automatisch eine Javascript-Proxy-Ebene, um die Verwendung von Web API zum Einkapseln einiger Javascript-Funktionen zu vereinfachen und die Verwendung von Ajax, Meldungsfeldern, Benachrichtigungskomponenten und Besetztmaskenebenen zu vereinfachen usw.

Zusätzlich zum ABP-Framework-Projekt wurde auch ein Modul namens „Zero“ entwickelt, das folgende Funktionen implementiert:

  • Authentifizierungs- und Berechtigungsverwaltung (implementiert durch ASP.NET Identity)

  • Benutzer- und Rollenverwaltung, Systemeinstellungen, Zugriffsverwaltung (Systemebene, Mandantenebene, Benutzerebene, automatische Verwaltung des Bereichs)

  • Audit-Protokoll (zeichnet automatisch den Aufrufer und die Parameter jeder Schnittstelle auf)

Was ist ABP? nicht?

ABP bietet ein Anwendungsentwicklungsmodell für Best Practices. Es verfügt über grundlegende Klassen, Schnittstellen und Tools, die es einfach machen, wartbare Großanwendungen zu erstellen.

Allerdings:

Es gehört nicht zu den RAD-Tools, die darauf ausgelegt sind, Anwendungen ohne Codierung zu erstellen. Stattdessen bietet ABP eine Best Practice für die Codierung.

Es handelt sich nicht um ein Tool zur Codegenerierung. Es verfügt zwar über einige Funktionen zum Erstellen dynamischen Codes zur Laufzeit, kann jedoch keinen Code generieren.

Es handelt sich nicht um ein All-in-One-Framework. Stattdessen werden beliebte Tools/Bibliotheken für bestimmte Aufgaben verwendet (z. B. EF für ORM, Log4Net für die Protokollierung, Castle Windsor als Abhängigkeitsinjektionscontainer, AngularJs für das SPA-Framework).

Basierend auf meiner mehrmonatigen Verwendung von ABP ist die Entwicklung von Projekten mit ABP auf jeden Fall viel schneller als mit der herkömmlichen dreistufigen Architektur, obwohl es sich nicht um RAD handelt.

Obwohl ABP kein Codegenerierungstool ist, ist der Code unseres Projekts dadurch prägnanter und standardisierter, was der Verwendung von Codegenerierungstools förderlich ist.

Ich habe den von Scaffolder + T4 von VS2013 entwickelten Codegenerator verwendet, der alle Front-End- und Back-End-Codes und Datenbanken basierend auf dem UML-Klassendiagramm von Domänenobjekten automatisch generieren kann. Ein einfaches CURD-Modul erfordert fast keine Codierung und komplexe Geschäfte Das logische Modul ergänzt hauptsächlich den Domänenschichtcode. Auf diese Weise können Sie mehr Zeit für den Entwurf des Domänenmodells aufwenden und den Zeitaufwand für das Schreiben von Code reduzieren.

Im Folgenden wird anhand des „Simple Task System“-Beispiels des ursprünglichen Autors gezeigt, wie ABP zum Entwickeln von Projekten verwendet wird.

Erstellen Sie eine leere Webanwendung aus einer Vorlage.

ABP bietet eine Startvorlage für neue Projekte (obwohl Sie das Projekt manuell erstellen und das ABP-Paket von Nuget erhalten können, ist die Vorlage mit der Vorlage einfacher).

Gehen Sie zu www.aspnetboilerplate.com/Templates, um Ihre Anwendung aus Vorlagen zu erstellen.

Sie können ein SPA-Projekt (AngularJs oder DurandalJs) oder ein MPA-Projekt (klassische mehrseitige Anwendung) wählen. Als ORM-Framework können Sie Entity Framework oder NHibernate wählen.

Hier wählen wir AngularJs und Entity Framework aus, geben den Projektnamen „SimpleTaskSystem“ ein, klicken auf die Schaltfläche „MEIN PROJEKT ERSTELLEN“, um ein ZIP-Paket herunterzuladen, dekomprimieren es, um die VS2013-Lösung und die verwendete .NET-Version zu erhalten ist 4.5.1.

Abp-Komponenten und andere Komponenten von Drittanbietern werden in jedem Projekt referenziert und müssen von Nuget heruntergeladen werden.

Das gelbe Ausrufezeichen-Symbol zeigt an, dass diese Komponente nicht im lokalen Ordner vorhanden ist und von Nuget wiederhergestellt werden muss. Der Vorgang ist wie folgt:

Um das Projekt auszuführen, müssen Sie eine Datenbank erstellen. Bei dieser Vorlage wird davon ausgegangen, dass Sie SQL2008 oder höher verwenden. Selbstverständlich lässt es sich auch problemlos durch andere relationale Datenbanken ersetzen.

Öffnen Sie die Web.Config-Datei, um die Linkzeichenfolge anzuzeigen und zu konfigurieren:


<add name="Default" connectionString="Server=localhost; Database=SimpleTaskSystemDb; Trusted_Connection=True;" />
Nach dem Login kopieren

(bei Verwendung von EFs Code, erste Datenmigration, später eine Datenbank mit dem Namen SimpleTaskSystemDb wird automatisch in der SQL Server-Datenbank erstellt)

Das war’s, das Projekt ist bereit zur Ausführung! Öffnen Sie VS2013 und drücken Sie F5:

Im Folgenden wird dieses einfache Aufgabensystemprogramm Schritt für Schritt implementiert

Entitäten erstellen

Schreiben Sie die Entitätsklasse im Kernprojekt, da die Entität Teil der Domänenschicht ist.

Ein einfaches Anwendungsszenario: Erstellen Sie einige Aufgaben und weisen Sie sie Personen zu. Wir brauchen zwei Entitäten, Aufgabe und Person.

Die Aufgabenentität verfügt über mehrere Attribute: Beschreibung (Description), Erstellungszeit (CreationTime), Aufgabenstatus (State) und ein optionales Navigationsattribut (AssignedPerson) zur Referenzierung einer Person.


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;
 }
}
Nach dem Login kopieren

Die Person-Entität ist einfacher und definiert nur ein Namensattribut:


public class Person : Entity
{
 public virtual string Name { get; set; }
}
Nach dem Login kopieren

in ABP Im Framework gibt es eine Entity-Basisklasse, die über ein Id-Attribut verfügt. Da die Task-Klasse von Entity erbt, hat sie eine Id vom Typ long. Die Person-Klasse hat eine ID vom Typ int, da der Typ int der Standardtyp der Entity-Basisklassen-ID ist. Wenn der Typ nicht angegeben ist, ist die ID der Entität vom Typ int.

DbContext erstellen

Um EntityFramework zu verwenden, müssen Sie zuerst die DbContext-Klasse definieren Es müssen nur die zu IDbSet hinzugefügte Aufgaben- und Personenklasse hinzugefügt werden. Weitere Informationen finden Sie im 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)
 {
   
 }
}
Nach dem Login kopieren

通过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"}
   );
 }
}
Nach dem Login kopieren

在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");
 }
}
Nach dem Login kopieren

然后继续在“程序包管理器控制台”执行“Update-Database”,会自动在数据库创建相应的数据表:


PM> Update-Database
Nach dem Login kopieren

数据库显示如下:

(以后修改了实体,可以再次执行Add-Migration和Update-Database,就能很轻松的让数据库结构与实体类的同步)

定义仓储接口

通过仓储模式,可以更好把业务代码与数据库操作代码更好的分离,可以针对不同的数据库有不同的实现类,而业务代码不需要修改。

定义仓储接口的代码写到Core项目中,因为仓储接口是领域层的一部分。

我们先定义Task的仓储接口:


public interface ITaskRepository : IRepository<Task, long>
{
Nach dem Login kopieren

它继承自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();
  }
}
Nach dem Login kopieren

TaskRepository继承自SimpleTaskSystemRepositoryBase并且实现了上面定义的ITaskRepository接口。

创建应用服务(Application Services)

Application项目中定义应用服务。首先定义Task的应用服务层的接口:


public interface ITaskAppService : IApplicationService
{
  GetTasksOutput GetTasks(GetTasksInput input);
  void UpdateTask(UpdateTaskInput input);
  void CreateTask(CreateTaskInput input);
}
Nach dem Login kopieren

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);
  }
}
Nach dem Login kopieren

TaskAppService使用仓储进行数据库操作,它通往构造函数注入仓储对象的引用。

数据验证

如果应用服务(Application Service)方法的参数对象实现了IInputDto或IValidate接口,ABP会自动进行参数有效性验证。

CreateTask方法有一个CreateTaskInput参数,定义如下:


public class CreateTaskInput : IInputDto
{
  public int? AssignedPersonId { get; set; }

  [Required]
  public string Description { get; set; }
}
Nach dem Login kopieren

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" }));
    }
  }
}
Nach dem Login kopieren

你可以在AddValidationErrors方法中写自定义验证的代码。

创建Web Api服务

ABP可以非常轻松地把Application Service的public方法发布成Web Api接口,可以供客户端通过ajax调用。


DynamicApiControllerBuilder
  .ForAll<IApplicationService>(Assembly.GetAssembly(typeof (SimpleTaskSystemApplicationModule)), "tasksystem")
  .Build();
Nach dem Login kopieren

SimpleTaskSystemApplicationModule这个程序集中所有继承了IApplicationService接口的类,都会自动创建相应的ApiController,其中的公开方法,就会转换成WebApi接口方法。

可以通过http://xxx/api/services/tasksystem/Task/GetTasks这样的路由地址进行调用。

通过上面的案例,大致介绍了领域层、基础设施层、应用服务层的用法。

现在,可以在ASP.NET MVC的Controller的Action方法中直接调用Application Service的方法了。

Wenn Sie die SPA-Einzelseitenprogrammierung verwenden, können Sie die entsprechende Anwendungsdienstmethode direkt über Ajax auf dem Client aufrufen (indem Sie eine dynamische Web-API erstellen).

Zusammenfassung

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung des ABP-Einführungs-Tutorials der ABP-Reihe des ASP.NET-Vorlagenentwicklungsframeworks. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage