Asp. NET Template Development Framework ABP Series ABP Introductory Tutorial

Source: Internet
Author: User
Tags app service exception handling
ABP is a starting point for using best practices and using the most popular tools for new modern web applications. An underlying framework or project template that can be used as a general-purpose application. Next through this article to give you a detailed introduction to the ABP Introductory tutorial, interested friends to see it together





The ABP is "ASP. Boilerplate Project (ASP. NET Template project) "for short.



ASP. Boilerplate is a new starting point for developing modern web applications with best practices and popular technologies, and is designed to be a common Web application framework and project template.



ABP's official website: http://www.aspnetboilerplate.com



ABP's Open source project on GitHub: Https://github.com/aspnetboilerplate



The origin of ABP



"dry--avoids duplicate code" is one of the most important ideas that a good developer has when developing software. We have similar requirements when developing enterprise Web applications, such as the need for login pages, user/role management, permission validation, data validation, multilanguage/localization, and so on. A large, high-quality software uses some best practices, such as tiered architecture, domain-driven design, dependency injection, and so on. We may also use tools such as ORM, database migrations, and Logging (Logging).



Creating an enterprise application from scratch is a tedious task because there are a number of common basic tasks that need to be repeated. Many companies are developing their own application frameworks to reuse different projects, and then develop new capabilities based on frameworks. But not every company has that kind of strength. If we can share more, maybe we can avoid repeating similar code for each company or project. The reason why the author named the project "ASP. Boilerplate" is that it can be a new starting point for developing general enterprise Web applications and directly use ABP as a project template.



What is ABP?



ABP is a starting point for using best practices and using the most popular tools for new modern web applications. An underlying framework or project template that can be used as a general-purpose application. Its features include:



Server-side:


    • Based on the latest. NET Technology (currently ASP 5, Web API 2, C # 5.0, will be upgraded after ASP. 5 is officially released)

    • Implement domain-driven design (entities, warehousing, Domain Services, domain events, application services, data transfer objects, work units, etc.)

    • Implementing a tiered architecture (domain, application, presentation, and infrastructure tiers) provides an infrastructure to develop reusable configurable modules to integrate some of the most popular open source frameworks/libraries, perhaps some of which you are using.

    • Provides an infrastructure that makes it easy to use dependency injection (using Castle Windsor as a container for dependency injection)

    • Provides repository warehousing mode support for different ORM (entity Framework, NHibernate, Mangodb, and memory databases implemented)

    • Support and implement database migration (EF Code first) modular development (each module has its own EF DbContext, which can be specified separately)

    • Includes a simple and flexible multi-lingual/localized system

    • Includes a eventbus to implement server-side global domain event uniform exception handling (the application layer hardly needs to handle its own write exception handling code)

    • Data validation (ASP. NET MVC can only do the parameter validation of the action method, the ABP implements the parameter validation of the application layer method)

    • Automatically create the Web API layer with application services (no need to write Apicontroller layer)

    • Providing base classes and helper classes allows us to easily implement some common tasks

    • Using "Conventions over configuration principles"


Client:


    • Bootstrap, less, AngularJs, JQuery, Modernizr, and other JS libraries: Jquery.validate, Jquery.form, Jquery.blockui, Json2, etc.

    • Project templates are provided for single-page applications (AngularJs, DURANDALJS) and multi-page applications (bootstrap+jquery).

    • Automatically create a proxy layer of JavaScript to make it easier to use the Web API to encapsulate some JavaScript functions, making it easier to use AJAX, message boxes, notification components, matte layers of busy states, and more


In addition to the ABP Framework project, a module called "Zero" has been developed to achieve the following functions:


    • Authentication and authorization management (implemented through ASP. NET identity)

    • User & Role Management system settings access management (System level, tenant level, user level, scope automatic management)

    • Audit logs (automatically record callers and parameters for each interface)


What is ABP?



The ABP provides an application development model for best practices. It has basic classes, interfaces, and tools that make it easy to build large, maintainable applications.



However:



It is not one of the RAD tools, and the purpose of RAD tools is to create applications without coding. Instead, the ABP provides a coding best practice.



It is not a code generation tool. While it is running, it has some features that build dynamic code, but it cannot generate code.



It is not an integrated framework. Instead, it uses popular tools/libraries to accomplish specific tasks (such as using EF as an ORM, logging with Log4net, and making Castle Windsor a container for AngularJs for the SPA framework).



In my experience with ABP for several months, although ABP is not rad, it is definitely much faster to develop projects with it than a traditional three-tier architecture.



Although the ABP is not a code generation tool, it is advantageous to use code generation tools because it makes the code of our project more concise and prescriptive.



I myself use VS2013 's SCAFFOLDER+T4 developed code generator, can automatically generate all the front and back end code and database according to the domain object's UML class diagram, the simple curd module almost does not need to write the code, the module which has the complex business logic mainly complements the domain layer code. This allows you to spend more time on the design of the domain model, reducing the time to write code.



The following is an example of the original author's "Simple Task system", demonstrating how to use the ABP development project



Create an empty Web application from a template



ABP provides a startup template for new projects (although you can manually create projects and get ABP packages from NuGet, templates are easier to do).



Go to Www.aspnetboilerplate.com/Templates to create your application from the template.






You can choose the Spa (Angularjs or DURANDALJS) or choose the MPA (Classic multi-page app) project. You can select the Entity Framework or NHibernate as the ORM framework.



Here we select the Angularjs and entity Framework, fill in the project name "Simpletasksystem", click the "CREATE MY Project" button can download a zip compression package, decompression to get VS2013 solution, Use of. NET version is 4.5.1.






ABP components and other third-party components are referenced in each project and need to be downloaded from NuGet.






The yellow exclamation point icon indicates that the component does not exist in the local folder and needs to be restored from NuGet. The operation is as follows:









To get the project up and running, you have to create a database. This template assumes that you are using SQL2008 or a newer version. Of course, it is also easy to switch to other relational databases.



Open the Web. config file to view and configure the link string:






<add name= "Default" connectionstring= "server=localhost; Database=simpletasksystemdb; trusted_connection=true; "/>


(a database named Simpletasksystemdb is automatically created in the SQL Server database when the code First Data Migration for EF is later used.) )



That's it, the project is ready to run! Open VS2013 and press F5:






This simple task-system program will be implemented gradually



Create entity



Write the entity class in the core project, because the entity is part of the domain layer.



A simple scenario: create some tasks and assign them to people. We need both the task and person entities.



The task entity has several properties: Description (Description), creation time (CreationTime), task status (state), and optional navigation properties (Assignedperson) to refer to 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;

 }

}



The person entity is simpler and defines only one name attribute:






public class person:entity{Public virtual string Name {get; set;}}


In the ABP framework, there is an entity base class that has an id attribute. Because the task class inherits from Entity<long>, it has a long type ID. The person class has an ID of type int, because the int type is the default type for the entity base class ID, and the ID of the entity is an int type when no particular type is specified.



Create DbContext



To use entityframework you need to define the DbContext class first, the ABP template has created the DbContext file, we just need to add the task and person class to the Idbset, see the 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)

 {

    

 }

}


To create a database table from migrations



We use EntityFramework's code first mode to create the database schema. The project generated by the ABP template already has the data migration feature turned on by default, and we modify the Configuration.cs file under the Migrations folder under the Simpletasksystem.entityframework project:


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"}

   );

 }

}



In the Package Manager console window at the bottom of VS2013, select the default project and execute the command "Add-migration initialcreate"






A Xxxx-initialcreate.cs file is generated under the Migrations folder with the following contents:


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");

 }

}



Then continue executing "update-database" in the Package Manager console, which will automatically create the appropriate data table in the database:






Pm> Update-database


The database appears as follows:






(after modifying the entity, you can execute add-migration and update-database again, it is easy to synchronize the database structure with the entity class.)



Defining warehousing Interfaces



Through the warehousing mode, the business code can be better separated from the database operation code, and there are different implementation classes for different databases, and the business code does not need to be modified.



The code that defines the warehousing interface is written to the core project because the warehousing interface is part of the domain layer.



Let's define the storage interface for the task first:






Public interface Itaskrepository:irepository<task, long>{


It inherits from the IRepository generic interface in the ABP framework.



In the irepository has already defined the commonly used additions and deletions to change the method:






So Itaskrepository has the above methods by default. It is possible to add its own method getallwithpeople (...).



There is no need to create a warehousing class for the person class, because the default method is sufficient. The ABP provides a way to inject generic warehousing, which will be seen in the Taskappservice class in the "Creating app Service" section later.



Realization of warehousing class



We will implement the Itaskrepository warehousing interface defined above in the EntityFramework project.



A project created from a template already defines a repository base class: Simpletasksystemrepositorybase (This is a good practice because you can add common methods to this base class later).


Public class TaskRepository : SimpleTaskSystemRepositoryBase<Task, long>, ITaskRepository

{

   Public List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state)

   {

     / / In the warehousing method, the ABP framework will automatically handle the database connection, DbContext and data transactions.

       

     Var query = GetAll(); //GetAll() returns an IQueryable<T> interface type

       

     //Add some Where conditions

 

     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 inherits from Simpletasksystemrepositorybase and implements the Itaskrepository interface defined above.



Create an app service (application services)



define the app service in the application project. First define the interface of the application service layer for the task:



Itaskappservice inherits from IAPPLICATIONSERVICE,ABP automatically provides some feature features (such as dependency injection and parameter validation) for this class.



Then we write the Taskappservice class to implement the Itaskappservice interface:


Public class TaskAppService : ApplicationService, ITaskAppService

{

  Private readonly ITaskRepository _taskRepository;

  Private readonly IRepository<Person> _personRepository;

     

  /// <summary>

  /// The constructor automatically injects the class or interface we need

  /// </summary>

  Public TaskAppService(ITaskRepository taskRepository, IRepository<Person> personRepository)

  {

    _taskRepository = taskRepository;

    _personRepository = personRepository;

  }

     

  Public GetTasksOutput GetTasks(GetTasksInput input)

  {

    / / Call the specific method of the Task ware GetAllWithPeople

    Var tasks = _taskRepository.GetAllWithPeople(input.AssignedPersonId, input.State);

 

    / / Use AutoMapper to automatically convert List<Task> to List<TaskDto>

    Return new GetTasksOutput

        {

          Tasks = Mapper.Map<List<TaskDto>>(tasks)

        };

  }

     

  Public void UpdateTask(UpdateTaskInput input)

  {

    / / Can be directly Logger, it is defined in the ApplicationService base class

    Logger.Info("Updating a task for input: " + input);

 

    / / Get the Task entity object of the specified Id through the general method Get of the storage base class

    Var task = _taskRepository.Get(input.TaskId);

 

    / / Modify the attribute value of the task entity

    If (input.State.HasValue)

    {

      task.State = input.State.Value;

    }

 

    If (input.AssignedPersonId.HasValue)

    {

      task.AssignedPerson = _personRepository.Load(input.AssignedPersonId.Value);

    }

 

    / / We do not need to call the Update method

    / / Because the application service layer method has turned on the unit of work mode (Unit of Work)

    // The ABP framework automatically saves all changes to the entity when the unit of work is completed, unless an exception is thrown. When there is an exception, it will automatically roll back because the unit of work opens the database transaction by default.

  }

 

  Public void CreateTask(CreateTaskInput input)

  {

    Logger.Info("Creating a task for input: " + input);

 

    / / Create a new Task entity by entering parameters

    Var task = new Task { Description = input.Description };

 

    If (input.AssignedPersonId.HasValue)

    {

      task.AssignedPersonId = input.AssignedPersonId.Value;

    }

 

    / / Call the storage base class Insert method to save the entity to the database

    _taskRepository.Insert(task);

  }

}


Taskappservice uses warehousing for database operations, which leads to references to constructor injection warehousing objects.



Data validation



If the parameter object of the application services (application Service) method implements the Iinputdto or Ivalidate interface, the ABP automatically validates the parameter validation.



The CreateTask method has a createtaskinput parameter, which is defined as follows:






public class createtaskinput:iinputdto{public  int? Assignedpersonid {get; set;}  [Required]  public string Description {get; set;}}


The Description property specifies that it is required by annotations. You can also use other Data Annotation features.



If you want to use custom validation, you can implement the Icustomvalidate interface:


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 and State cannot be empty at the same time!", new[] { "AssignedPersonId", "State" }));

     }

   }

}



You can write code for custom validation in the Addvalidationerrors method.



Create a Web API service



The ABP makes it very easy to publish the public method of the application service as a Web API interface that can be called by the client through Ajax.


DynamicApiControllerBuilder

  .ForAll<IApplicationService>(Assembly.GetAssembly(typeof (SimpleTaskSystemApplicationModule)), "tasksystem")

  .Build();



Simpletasksystemapplicationmodule all classes that inherit the Iapplicationservice interface in this assembly will automatically create the corresponding Apicontroller, the public method, will be converted to the Webapi interface method.



This can be called through a routing address such as Http://xxx/api/services/tasksystem/Task/GetTasks.



Through the above cases, the usage of domain layer, infrastructure layer and application service layer are introduced.



The application service method can now be called directly in the action method of the Controller of ASP.



If you are programming with a spa single page, you can invoke the corresponding application service method directly on the client via Ajax (by creating a Dynamic Web Api).



Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.