AspNetCore-Based Domain-driven rapid development template project, aspnetcore Template
AspNetCore has been paying attention to since its release. It has used its spare time to write a project template for rapid development of the project, which has been hosted on github. If you want to directly view the source code, please stamp it below
Https://github.com/huanent/WebApi
Next I will introduce the details of the project.
I. project structure
Projects are divided into three folders.
The application mainly stores external projects. protal is a webapi project. Provide external web services
The core of the domain business field, which stores the specific logic Implementation of the project business and provides interface calls to the application layer.
Infrastructure layer. Currently, only one project of file logs can be implemented, and other auxiliary services such as email can be expanded based on the needs of the project in the future.
Analyze the entire project injection field from the startup File
First, we can see that Domain is injected into ConfigureServices, which is our core business logic. There are two parameters.
1. SQL service type
2. connection string
Domain currently I use two types of databases, small projects use sqlite, large use of sqlserver, you can directly input the enumeration value to specify, the detailed implementation of the field will be described below.
Expanded text logs
In Configure, the official default log provider provides log output for debugging in the console and editor. in actual production, we prefer to have a log record in the text format, therefore, we added a text file record provider in the red box. The specific implementation is Logging in the infrastructure. textWriter project.
Ii. Damain Domain Layer DomainService. veriactions
This project stores the service and repository interfaces of domain services without specific implementation. It is obtained and called in protal Controller.
The interfaces in the RepositoryInterface and ServiceInterface must implement the parent interfaces used by the base folder, because only in this way can they be automatically injected into the system's dependent containers, the implementation of its automatic injection will be in the DomainService project. implementation in Implement
DomainService. Implement
The DomainService. Implement project implements the corresponding warehousing or service interfaces in DomainService. gateactions and inherits their parent classes from the base folder, such as the DemoRepository class.
Public class DemoRepository: RepositoryBase <Demo>, IDemoRepository
Classes implemented in this way will be automatically bound to the IDemoRepository interface. The method for automatic binding is in AddDomainExtention.
Public static class AddDomainExtention {// <summary> // register a domain /// </summary> /// <param name = "services"> </param> public static void AddDomain (this IServiceCollection services, ESql sqlType, string ConnectionString) {services. addDbContext <AppDbContext> (option => {switch (sqlType) {case ESql. sqlServer: option. useSqlServer (ConnectionString); break; case ESql. sqlite: option. useSqlite (ConnectionStr Ing); break; default: break;}); RegisterService (services, typeof (IRepository <>), typeof (RepositoryBase <>); RegisterService (services, typeof (IDomainService), typeof (ServiceBase ));} /// <summary> /// register services in batches /// </summary> /// <param name = "services"> service container </param> /// <param name = "baseInterface"> base interface </param> // <param name = "baseType"> base class </param> private static void RegisterService (IServiceCollectio N services, Type baseInterface, Type baseType) {string baseTypeName = baseType. getTypeInfo (). name; var assembly = baseType. getTypeInfo (). assembly; var types = assembly. getTypes (). where (t => t. getTypeInfo (). baseType. name = baseTypeName); foreach (var item in types) {var typeInterface = item. getTypeInfo (). implementedInterfaces. firstOrDefault (t => t. getTypeInfo (). implementedInterfaces. any (a =>. N Ame = baseInterface. Name); if (typeInterface! = Null) {services. AddScoped (typeInterface, item );}}}}
View Code
As shown above, this method registers repository and service respectively. Specifically, reflection is used to find the interface type and implementation type inherited from the specified parent class, and then registration is added through IServiceCollection.
Entities, Entities. TypeConfig
These two items define and configure EF entities, and entitis defines basic object types.
public class Demo : EntityBase { public string Name { get; set; } }
Entity constraints, foreign key navigation, and other settings in Entities. TypeConfig
Public class DemoConfig: entityTypeConfigBase <Demo >{/// <summary> /// entity configuration class /// use the Builder integrated with the parent class to configure it. // The configuration result will be displayed when the program starts. dbContext // </summary> public override void ConfigType () of the automatic injection program () {Builder. property (p => p. name ). hasMaxLength (10 );}}
For the objects defined in these two projects, the object configuration must inherit from their own default interfaces, so that EF can automatically register to DBContext. The OnModelCreating method of AppDbContext can be implemented in this way.
Protected override void OnModelCreating (ModelBuilder modelBuilder) {# region registers the object type configuration var typeInfo = typeof (EntityTypeConfigBase <> ). getTypeInfo (); string typeName = typeInfo. name; var assembly = typeInfo. assembly; var types = assembly. getTypes (); foreach (var item in types) {if (item. getTypeInfo (). baseType. name = typeName) {dynamic instance = assembly. createInstance (item. fullName); instance. modelBuilder = modelBuilder; instance. configType () ;}# endregion registers the object type configuration base. onModelCreating (modelBuilder );}
Usage
This template is easy to use. Take adding a Product as an example. The process is as follows:
1. added the Product class inheritance EntityBase to Entitis.
2. Entities. TypeConfig adds the ProductConfig class to inherit EntityTypeConfigBase, and configures the specific field constraints of the Product. The foreign key
3. Added IProductRepository for DomainService. Abstractions to implement IRepository.
4. DomainService. Implement added ProductRepository to inherit Repository <Product> to Implement IProductRepository
5. In the Controller of Protal, the constructor obtains the dependency IProductRepository and calls the business method.
Summary
AspNetCore is a very good platform. Many of the design patterns are worthy of our reference and learning. I am not familiar with them, but I am still happy to learn them. I have a wrong understanding of concepts in this article, you are welcome to criticize and correct me. I will also learn with an empty mind. I hope we can work together to promote it. net development in China.