Skip to content

Commit

Permalink
Initial checkin
Browse files Browse the repository at this point in the history
  • Loading branch information
dolunay committed Dec 6, 2024
0 parents commit fe8fabd
Show file tree
Hide file tree
Showing 6 changed files with 510 additions and 0 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: publish to easyabp.io
on:
push:
branches:
- master
- main
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
fetch-depth: 0

- name: Find and Replace
uses: jacobtomlinson/gha-find-replace@master
with:
find: \]\((/docs/)
replace: "](/guide/${{ github.event.repository.name }}/"
include: docs/**.md

- name: Pull repo and change files
id: change
run: |
ls
git clone https://github.com/Syrna/easyabp.github.io
cd easyabp.github.io
rm -rf docs/guide/${{ github.event.repository.name }}
rm -rf docs/.vuepress/public/guide/${{ github.event.repository.name }}
mkdir -p docs/guide
mkdir -p docs/.vuepress/public/guide
cp -rf ../docs/ docs/guide/${{ github.event.repository.name }}
cp -rf ../docs/ docs/.vuepress/public/guide/${{ github.event.repository.name }}
git add --all
echo "##[set-output name=diff;]$(git diff --staged)"
- name: Commit files
if: steps.change.outputs.diff
run: |
ls
cd easyabp.github.io
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git commit -m "Update the docs of ${{ github.event.repository.name }}" -a
- name: Push changes
if: steps.change.outputs.diff
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.EASYABP_IO_ACCESS_TOKEN }}
repository: Syrna/easyabp.github.io
directory: easyabp.github.io
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/docs/README.md
71 changes: 71 additions & 0 deletions docs/Getting-Start-to-Develop-Modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Getting Start to Develop Modules
This article will show you how to develop ABP modules that follow the [Module Development Specification](/docs/Module-Development-Specification.md) document.

## Step 1: Generate a new ABP module

Use ABP CLI to generate a new ABP module solution with the name prefix `Syrna.`, see: https://docs.abp.io/en/abp/latest/CLI#new.

## Step 2: Complete the project structure

1. For each project (except the Web project), create folders according to namespace and move all the original files and folders in, for example: `Syrna/(Abp)/MyModuleName/`.

2. Search `<RootNamespace>Syrna.MyModuleName</RootNamespace>` in **src** folder and replace with `<RootNamespace />`.

3. Move all the files in `Syrna.MyModuleName.Domain.Shared/Syrna/MyModuleName/Localization/MyModuleName/` to `Syrna.MyModuleName.Domain.Shared/Syrna/MyModuleName/Localization/`.

4. Open **MyModuleNameDomainSharedModule.cs**:
* Change `.AddVirtualJson("/Localization/MyModuleName");` to `.AddVirtualJson("/Syrna/MyModuleName/Localization");`.
* Change `options.MapCodeNamespace("MyModuleName", typeof(MyModuleNameResource));` to ``options.MapCodeNamespace("Syrna.MyModuleName", typeof(MyModuleNameResource));``.

5. Open **Syrna.MyModuleName.Domain.Shared.csproj**:
* Change `<EmbeddedResource Include="Localization\MyModuleName\*.json" />` to `<EmbeddedResource Include="Syrna\MyModuleName\Localization\*.json" />`.
* Change `<Content Remove="Localization\MyModuleName\*.json" />` to `<Content Remove="Syrna\MyModuleName\Localization\*.json" />`.
* Delete other unused `<EmbeddedResource ... />` configurations.

## Step 3: Adjust code of pages

Tip: Skip this step if you do not need Web project.

1. **Pages** folder should have only **MyModuleName** subfolder, other folders and files should be in the **MyModuleName** folder.

2. Open all the **index.js** for entity management pages:
* Change `abp.localization.getResource('MyProjectName');` to `abp.localization.getResource('SyrnaMyProjectName');`

<details>
<summary>Detail checks</summary>

1. Open all the **index.js** for entity management pages:
* Ensure the param value in `new abp.ModalManager()` is correct.
* Ensure the param value in `abp.auth.isGranted()`is correct.

2. Open all the **index.cshtml** for entity management pages:
* Ensure the src value in `<abp-script ... />` and `<abp-style ... />` is correct.

3. Open **MyModuleNameMenuContributor.cs**:
* Ensure the url of each menu item is correct.

</details>

## Step 4: Change and use name constants

1. Open `MyModuleNamePermissions.cs` and change **GroupName** to `Syrna.MyModuleName`.

2. Open `MyModuleNameSettings.cs` and change **GroupName** to `Syrna.MyModuleName`.

3. Open `MyModuleNameMenus.cs` and change **Prefix** to a public property with the value `Syrna.MyModuleName`.

4. Open `MyModuleNameDbProperties.cs` and change **DbTablePrefix** and **ConnectionStringName** to `SyrnaMyModuleName`.

5. Open `MyModuleNameRemoteServiceConsts.cs`, change **RemoteServiceName** to `SyrnaMyModuleName` and change **ModuleName** to `syrnaMyModuleName`.

6. Open `MyModuleNameResource.cs` and replace `[LocalizationResourceName("MyModuleName")]` with `[LocalizationResourceName("SyrnaMyModuleName")]`.

7. Open `MyModuleNameController.cs` and add **[Area(MyModuleNameServiceConsts.ModuleName)]** attribute.

## Step 5: Other adjustments

1. Modify the **common.props** file according to: https://github.com/Syrna/PrivateMessaging/blob/master/common.props.

2. Unified ABP version number.
1. Put ABP version number into the **Directory.Build.props** file (see [demo](https://github.com/Syrna/PrivateMessaging/blob/master/Directory.Build.props)).
2. Replace `<PackageReference Include="Volo.Abp.xxx" Version="x.x.x" />` to `<PackageReference Include="Volo.Abp.xxx" Version="$(AbpVersion)" />` in all the .csproj files of the solution.
11 changes: 11 additions & 0 deletions docs/How-To.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# "How To" Guides
Todo.

## Add NuGet Packages
Todo.

## Add Module Dependencies
Todo.

## Develop an Syrna Module
See [Getting Start to Develop Modules](/docs/Getting-Start-to-Develop-Modules.md) and [Module Development Specification](/docs/Module-Development-Specification.md#contribute-to-easyabp).
155 changes: 155 additions & 0 deletions docs/Module-Development-Specification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Module Development Specification

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

## Basic Knowledges

Please read through the ABP official document: [Module Development](https://docs.abp.io/en/abp/latest/Module-Development-Basics).

## Standardization

We have some standards based on the official document: [Module Development Best Practices & Conventions](https://docs.abp.io/en/abp/latest/Best-Practices/Index).

### Abstraction

Try to design an abstract module and provide more implementations.
* Good practice: `Syrna.Abp.Sms`, `Syrna.Abp.Sms.Aws`, `Syrna.Abp.Sms.Azure`.
* Bad practice: `Syrna.Abp.AzureSms`.

### Module Naming

Example of module solution name:
* Application module: `Syrna.TodoManagement`.
* Framework module: `Syrna.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

Todo.

### Solution Structure

Read the document [Getting Start to Develop Modules](https://github.com/Syrna/SyrnaGuide/blob/master/docs/Getting-Start-to-Develop-Modules.md) 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.

### Menu Items

Refer to the [MenuContributor demo](https://github.com/Syrna/GiftCardManagement/blob/master/src/Syrna.GiftCardManagement.Web/GiftCardManagementMenuContributor.cs).

* The name of menu item should have a `CompanyName+ModuleName` prefix, for example: `SyrnaGiftCardManagementGiftCard` is the `GiftCard` using the `SyrnaGiftCardManagement` 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.

```c#
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.

* See ABP document: [Creating a New Entity with Its Own Database Table/Collection](https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities#creating-a-new-entity-with-its-own-database-table-collection).
* Use `IDistributedEventHandler` instead of `ILocalEventHandler` to synchronize user data.

### 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](https://github.com/Syrna/PrivateMessaging/blob/master/common.props) and the [FodyWeavers.xml](https://github.com/Syrna/PrivateMessaging/blob/master/src/Syrna.PrivateMessaging.Domain/FodyWeavers.xml) 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](https://github.com/Syrna/AbpHelper.GUI/blob/master/doc/AbpHelper-CLI/Generate-Controller-Code/Usage.md) to generate controllers manually.

### Change and Use Name Constants

* Open `MyModuleNamePermissions.cs` and change **GroupName** to `Syrna.MyModuleName`.
* Open `MyModuleNameSettings.cs` and change **GroupName** to `Syrna.MyModuleName`.
* Open `MyModuleNameRemoteServiceConsts.cs` and change **RemoteServiceName** to `SyrnaMyModuleName`.
* Open `MyModuleNameRemoteServiceConsts.cs` and change **ModuleName** to `syrnaMyModuleName`.
* Open `MyModuleNameResource.cs` and replace `[LocalizationResourceName("MyModuleName")]` with `[LocalizationResourceName("SyrnaMyModuleName")]`.
* Open `MyModuleNameController.cs` and add **[Area(MyModuleNameServiceConsts.ModuleName)]** attribute.

### Depend on Other Modules

Todo.

### Testing

Todo.

### common.props

Follow the steps below:
1. Copy the [common.props](https://github.com/Syrna/FileManagement/blob/master/common.props) demo to your module.
1. Edit `Version`, `Description`, `PackageTags` and `PackageLicenseExpression`. (Don't follow the ABP framework's version.)

### README.md

Refer to the [README.md](https://github.com/Syrna/FileManagement/blob/master/README.md) demo. You can customize the structure, but in fact similar formats are more readable.

### Packaging and Publishing

Refer to the [GitHub Action demo](https://github.com/Syrna/FileManagement/tree/master/.github/workflows/publish.yml), 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

* Syrna 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](https://github.com/Syrna/FileManagement/blob/master/docs/README.md#road-map) 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 Syrna

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

### Publish New Modules

If you want to contribute a new module to Syrna, please create an issue [here](https://github.com/Syrna/SyrnaGuide/issues) 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 Syrna 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.
Loading

0 comments on commit fe8fabd

Please sign in to comment.