In this section we mainly deal with the domain layer. First, we need to make a one-to-one correspondence between the architecture of ABP and the solutions created from the template. There are code generators available online to simplify our task at this step, but they are not recommended for beginners.
1. First, let’s take a look at the ABP architecture
The domain layer is the business layer and is the core of a project. All business rules should be in the domain layer accomplish.
Entity: Entity represents data and operations in the business domain. In practice, it is used to map it into a database table.
Repository: Repository is used to operate the database for data access. The warehousing interface is defined at the domain layer, while the warehousing implementation class should be written at the infrastructure layer.
Domain service: When the business rules processed span two (or more) entities, they should be written in the domain service method.
Domain Event: Domain events can be triggered when some specific situations occur in the domain layer, and they can be captured and processed in the corresponding places.
Unit of Work: Unit of Work is a design pattern used to maintain a list of business objects that have been modified (such as added, deleted, updated, etc.). It is responsible for coordinating the persistence and concurrency issues of these business objects.
2. Let’s take a look at the solution again
After determining which layer each project under the solution corresponds to, we started to create the Task entity.
3. Create Task entity
1. Create the Tasks folder in the domain layer and create the Task entity class;
2. All entity classes in ABP inherit from Entity, and Entity implements the IEntity interface; and the IEntity interface is a generic interface that specifies the primary key Id type through generics. The default primary key type of Entity is the int type.
When creating a Task, you definitely need to save the creation time. This general function can be achieved by implementing IHasCreationTime in the audit module. The code is as follows:
namespace LearningMpaAbp.Tasks{ public class Task : Entity, IHasCreationTime { public const int MaxTitleLength = 256; public const int MaxDescriptionLength = 64 * 1024;//64kb public long? AssignedPersonId { get; set; } [ForeignKey("AssignedPersonId")] public User AssignedPerson { get; set; } [Required] [MaxLength(MaxTitleLength)] public string Title { get; set; } [Required] [MaxLength(MaxDescriptionLength)] public string Description { get; set; } public TaskState State { get; set; } public DateTime CreationTime { get; set; } public Task() { CreationTime = Clock.Now; State = TaskState.Open; ; } public Task(string title, string description = null) : this() { Title = title; Description = description; } } public enum TaskState : byte { Open = 0, Completed = 1 }}
The TaskState state enumeration is defined. And added the AssignedPerson navigation attribute to save assigned tasks to a user. The [Required] and [MaxLength] features are used for input verification.
3. After defining the entity, we need to define the DbSet corresponding to the entity in DbContext to apply Code First data migration. Find our basic service layer, that is, in the project ending with EntityFramework, find the DbContext class and add the following code
//TODO: Define an IDbSet for your Entities... public IDbSet<Task> Tasks { get; set; }
4. Perform Code First data migration.
Open the package manager console and select the project corresponding to Entityframework as the default project. Execute Add-Migration Add_Task_Entity to create migration.
After successful creation, a class file in the format of time_Add_Task_Entity will be created in the Migrations folder. If we observe carefully, we will find that there is a SeedData folder under the Migrations folder. As the name suggests, the classes in this folder are mainly used to preset seed data. We can refer to the writing method of existing classes to preset two Tasks. Create the DefaultTestDataForTask class with the following code:
namespace LearningMpaAbp.Migrations.SeedData{public class DefaultTestDataForTask{ private readonly LearningMpaAbpDbContext _context; private static readonly List<Task> _tasks; public DefaultTestDataForTask(LearningMpaAbpDbContext context) { _context = context; } static DefaultTestDataForTask() { _tasks = new List<Task>() { new Task("Learning ABP deom", "Learning how to use abp framework to build a MPA application."), new Task("Make Lunch", "Cook 2 dishs") }; } public void Create() { foreach (var task in _tasks) { _context.Tasks.Add(task); _context.SaveChanges(); } } } }
Then in the Seed method in the Configuration class, add the following code.
new DefaultTestDataForTask(context).Create();
In the package manager console, enter Update-Database and press Enter to perform migration. After the execution is successful, check the database and see that the Tasks table is successfully created and two pieces of test data already exist in the table.
At this point, the Task entity class is successfully created.
The source code has been uploaded to Github-LearningMpaAbp, you can refer to it yourself.
ABP introductory series directory - practical exercises for learning the Abp framework
The above is the ABP introductory series (3) - the content of creating entities in the domain layer. For more related content, please pay attention to PHP Chinese website (www.php.cn)!