# Module Development Specification

This document introduces the module development specification of the EasyAbp organization. Follow these rules and designs if you want to join and contribute.

# Basic Knowledges

Please read through the ABP official document: Module Development (opens new window).

# Standardization

We have some standards based on the official document: Module Development Best Practices & Conventions (opens new window).

# Abstraction

Try to design an abstract module and provide more implementations.

  • Good practice: EasyAbp.Abp.Sms, EasyAbp.Abp.Sms.Aws, EasyAbp.Abp.Sms.Azure.
  • Bad practice: EasyAbp.Abp.AzureSms.

# Module Naming

Example of module solution name:

  • Application module: EasyAbp.TodoManagement.
  • Framework module: EasyAbp.Abp.Todo (including the prefix Abp.).

For framework modules, the better name of XxxxxxModule class for framework module is AbpXxxxxxModule.

# Domain Services

  • Add a [UnitOfWork] attribute to the method that uses repositories.
  • Don't use any write-operation method of repositories. That also means you will never add a [UnitOfWork(IsTransactional = true)] attribute.

# Distributed Events


# Solution Structure

Read the document Getting Start to Develop Modules (opens new window) and follow it to adjust your module solution from the startup template.

# More Virtual Methods

According to https://github.com/abpframework/abp/issues/3166

  • Make all public/protected methods virtual (including entities, domain services, application services, page models, view components...) to make them easily overridable.
  • Make all private methods of domain & application services "protected virtual" to also be able to override them.

Generally, please virtualize the above methods, but you should also think about maintainability and consider protecting some methods if necessary.

# Multi-tenancy

  • Let your entities implement IMultiTenant if your module can be designed to support multi-tenancy.
  • Make sure permissions are host-side only if they should be hidden from tenant users and vice versa.

Refer to the MenuContributor demo (opens new window).

  • The name of menu item should have a CompanyName+ModuleName prefix, for example: EasyAbpGiftCardManagementGiftCard is the GiftCard using the EasyAbpGiftCardManagement prefix.
  • Create a CompanyName+ModuleName menu item as the root of the module and put other menu items into it, hide it if there is nosub menu item inside.

# Retain a Parameterless Constructor

Always retain a protected or public parameterless constructor, since serializers need it.

public class Book
    protected Book() { }

# User Data

There are two ways to get user data (such as UserName and PhoneNumber):

  1. Get from ABP's identity module.

    • Use IExternalUserLookupServiceProvider instead of IIdentityUserRepository or IIdentityUserAppService in all your code to get user's data.
  2. Create an local extra user entity (like BlogUser) and synchronize data from IdentityUser.

# Inherits ExtensibleObject

Classes with IHasExtraProperties should inherit ExtensibleObject.

Otherwise, you should make sure:

  1. The class has [Serializable] attribute.
  2. The ExtraProperties property has [JsonInclude] attribute.
  3. The ExtraProperties property has a protected setter.

# Using IClock

Use IClock.Now instead of DateTime.Now or DateTime.UtcNow in all your code to get current date time.

# Using ConfigureAwait.Fody

Refer to the common.props (opens new window) and the FodyWeavers.xml (opens new window) demos.

  • Add Fody and ConfigureAwait.Fody references to module projects.
  • Set <ConfigureAwait ContinueOnCapturedContext="false" />.

# Don't Use the Auto API Controllers

The ABP auto API controllers is not friendly to tiered solutions, so please use the AbpHelper (opens new window) to generate controllers manually.

# Change and Use Name Constants

  • Open MyModuleNamePermissions.cs and change GroupName to EasyAbp.MyModuleName.
  • Open MyModuleNameSettings.cs and change GroupName to EasyAbp.MyModuleName.
  • Open MyModuleNameRemoteServiceConsts.cs and change RemoteServiceName to EasyAbpMyModuleName.
  • Open MyModuleNameRemoteServiceConsts.cs and change ModuleName to easyAbpMyModuleName.
  • Open MyModuleNameResource.cs and replace [LocalizationResourceName("MyModuleName")] with [LocalizationResourceName("EasyAbpMyModuleName")].
  • Open MyModuleNameController.cs and add [Area(MyModuleNameServiceConsts.ModuleName)] attribute.

# Depend on Other Modules


# Testing


# common.props

Follow the steps below:

  1. Copy the common.props (opens new window) demo to your module.
  2. Edit Version, Description, PackageTags and PackageLicenseExpression. (Don't follow the ABP framework's version.)


Refer to the README.md (opens new window) demo. You can customize the structure, but in fact similar formats are more readable.

# Packaging and Publishing

Refer to the GitHub Action demo (opens new window), configure your project publication jobs. The NuGet packages will be automatic built and published after you commit code to the master branch with a new module version.

# Continuous Updating

  • EasyAbp modules always follow the latest version of ABP framework, so when a new version ABP released, you should upgrade your modules as soon as possible.
  • Write down the roadmap in README.md with reference to this demo (opens new window) and implement them when you have time and inspiration.
  • Create a new GitHub release and announce all the breaking changes before publish new version pacakges to NuGet.

# Contribute to EasyAbp

Welcome to contribute to EasyAbp organization, you can publish new modules or improve existing modules for us.

# Publish New Modules

If you want to contribute a new module to EasyAbp, please create an issue here (opens new window) to introduce your design and provide the link to your module Github repository. We will evaluate your design and review your code, if the module is well-designed and needed, we will add it to EasyAbp org.

# Improve Existing Modules

If you want to improve an existing module, please create a PR in the module Github repository, which we will review and merge if it is needed.

Last Updated: 8/26/2022, 9:14:33 AM