Browse Source

Merge branch 'dev' into alper/stream-dispose

pull/10146/head
maliming 5 years ago
parent
commit
b6b6fd2614
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 16
      .github/workflows/auto-pr.yml
  2. 22
      .github/workflows/build-and-test.yml
  3. 2
      .gitignore
  4. 16
      Directory.Build.props
  5. 1
      README.md
  6. 44
      abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json
  7. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json
  8. 5
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  9. 3
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  10. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
  11. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
  12. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json
  13. 2
      abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json
  14. 4
      build/common.ps1
  15. 2
      build/test-all.ps1
  16. 4
      codecov.yml
  17. 2
      common.props
  18. 2
      configureawait.props
  19. 2
      docs/cs/Entity-Framework-Core-PostgreSQL.md
  20. 2
      docs/cs/Getting-Started-AspNetCore-Application.md
  21. 2
      docs/cs/Getting-Started-Console-Application.md
  22. 2
      docs/cs/Index.md
  23. 2
      docs/en/API/Application-Configuration.md
  24. 2
      docs/en/API/Swagger-Integration.md
  25. 2
      docs/en/Audit-Logging.md
  26. 11
      docs/en/Background-Jobs-Hangfire.md
  27. 99
      docs/en/Background-Workers-Hangfire.md
  28. 11
      docs/en/Background-Workers.md
  29. 2
      docs/en/Best-Practices/Application-Services.md
  30. 2
      docs/en/Best-Practices/Data-Transfer-Objects.md
  31. 2
      docs/en/Best-Practices/Domain-Services.md
  32. 2
      docs/en/Best-Practices/Entity-Framework-Core-Integration.md
  33. 2
      docs/en/Best-Practices/Index.md
  34. 2
      docs/en/Best-Practices/Module-Architecture.md
  35. 2
      docs/en/Best-Practices/MongoDB-Integration.md
  36. 308
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/POST.md
  37. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/abp-book-cover.png
  38. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/csharp-proxies.png
  39. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/email-settings.png
  40. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/enable-email-tenant.png
  41. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/hangfire-dashboard.png
  42. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/js-proxies.png
  43. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/tenant-features.png
  44. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/use-preview-visual-studio.png
  45. BIN
      docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/user-active.png
  46. 2
      docs/en/CLI.md
  47. BIN
      docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/1.png
  48. BIN
      docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/2.png
  49. 88
      docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/POST.md
  50. 2
      docs/en/Configuration.md
  51. 2
      docs/en/Dependency-Injection.md
  52. 133
      docs/en/Distributed-Event-Bus-Azure-Integration.md
  53. 54
      docs/en/Distributed-Event-Bus.md
  54. 2
      docs/en/Domain-Services.md
  55. 2
      docs/en/Emailing.md
  56. 2
      docs/en/Entity-Framework-Core-Migrations.md
  57. 2
      docs/en/Entity-Framework-Core-MySQL.md
  58. 2
      docs/en/Entity-Framework-Core-Oracle-Devart.md
  59. 2
      docs/en/Entity-Framework-Core-Oracle-Official.md
  60. 2
      docs/en/Entity-Framework-Core-Oracle.md
  61. 2
      docs/en/Entity-Framework-Core-Other-DBMS.md
  62. 2
      docs/en/Entity-Framework-Core-PostgreSQL.md
  63. 2
      docs/en/Entity-Framework-Core-SQLite.md
  64. 2
      docs/en/Getting-Started-AspNetCore-Application.md
  65. 2
      docs/en/Getting-Started-React-Native.md
  66. 2
      docs/en/Getting-Started-With-Startup-Templates.md
  67. 2
      docs/en/Index.md
  68. 2
      docs/en/Integration-Tests.md
  69. 2
      docs/en/Json-Serialization.md
  70. 50
      docs/en/Local-Event-Bus.md
  71. 2
      docs/en/MailKit.md
  72. 101
      docs/en/Migration-Guides/Abp-5_0-Angular.md
  73. 51
      docs/en/Migration-Guides/Abp-5_0.md
  74. 10
      docs/en/Migration-Guides/Index.md
  75. 2
      docs/en/Module-Development-Basics.md
  76. 3
      docs/en/Module-Entity-Extensions.md
  77. 5
      docs/en/Modules/Cms-Kit/Index.md
  78. 2
      docs/en/Modules/Setting-Management.md
  79. 2
      docs/en/Object-Extensions.md
  80. 2
      docs/en/Options.md
  81. 2
      docs/en/RabbitMq.md
  82. 2
      docs/en/Road-Map.md
  83. 2
      docs/en/SMS-Sending.md
  84. 2
      docs/en/Settings.md
  85. 54
      docs/en/SignalR-Integration.md
  86. 2
      docs/en/Specifications.md
  87. 2
      docs/en/Startup-Templates/Application.md
  88. 2
      docs/en/Startup-Templates/Index.md
  89. 2
      docs/en/Startup-Templates/Module.md
  90. 6
      docs/en/Testing.md
  91. 2
      docs/en/Timing.md
  92. 249
      docs/en/UI/Angular/Chart-Component.md
  93. 4
      docs/en/UI/Angular/Config-State-Service.md
  94. 12
      docs/en/UI/Angular/Content-Strategy.md
  95. 10
      docs/en/UI/Angular/Extensions-Overall.md
  96. 46
      docs/en/UI/Angular/Permission-Management.md
  97. BIN
      docs/en/UI/Angular/images/bar-chart.png
  98. BIN
      docs/en/UI/Angular/images/doughnut-chart.png
  99. BIN
      docs/en/UI/Angular/images/pie-chart.png
  100. BIN
      docs/en/UI/Angular/images/radar-chart.gif

16
.github/workflows/auto-pr.yml

@ -1,10 +1,10 @@
name: Merge branch dev with rel-4.4
name: Merge branch dev with rel-5.0
on:
push:
branches:
- rel-4.4
- rel-5.0
jobs:
merge-dev-with-rel-4-4:
merge-dev-with-rel-5-0:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -12,13 +12,13 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
git fetch origin rel-4.4:rel-4.4
git reset --hard rel-4.4
git fetch origin rel-5.0:rel-5.0
git reset --hard rel-5.0
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
branch: auto-merge/rel-4-4/${{github.run_number}}
title: Merge branch dev with rel-4.4
body: This PR generated automatically to merge dev with rel-4.4. Please review the changed files before merging to prevent any errors that may occur.
branch: auto-merge/rel-5-0/${{github.run_number}}
title: Merge branch dev with rel-5.0
body: This PR generated automatically to merge dev with rel-5.0. Please review the changed files before merging to prevent any errors that may occur.
reviewers: ${{github.actor}}
token: ${{ github.token }}

22
.github/workflows/build-and-test.yml

@ -1,5 +1,22 @@
name: "build and test"
on:
push:
branches:
- dev
paths:
- 'framework/**/*.cs'
- 'framework/**/*.cshtml'
- 'framework/**/*.csproj'
- 'framework/**/*.razor'
- 'modules/**/*.cs'
- 'modules/**/*.cshtml'
- 'modules/**/*.csproj'
- 'modules/**/*.razor'
- 'templates/**/*.cs'
- 'templates/**/*.cshtml'
- 'templates/**/*.csproj'
- 'templates/**/*.razor'
pull_request:
paths:
- 'framework/**/*.cs'
@ -21,7 +38,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-dotnet@master
with:
dotnet-version: 6.0.100-rc.1.21458.32
dotnet-version: 6.0.100-rc.2.21505.57
- name: Build All
run: .\build-all.ps1
@ -32,3 +49,6 @@ jobs:
run: .\test-all.ps1
working-directory: .\build
shell: powershell
- name: Codecov
uses: codecov/codecov-action@v2

2
.gitignore

@ -314,7 +314,7 @@ abp-build-config.json
tempkey.jwk
# ABP Analyzing files
*.abppkg.analyze.json
# [Disabled for now] *.abppkg.analyze.json
# appsettings.secrets.json
appsettings.secrets.json

16
Directory.Build.props

@ -2,10 +2,10 @@
<PropertyGroup>
<!-- All Microsoft packages -->
<MicrosoftPackageVersion>6.0.0-rc.*</MicrosoftPackageVersion>
<MicrosoftPackageVersion>6.0.0-rc.2.*</MicrosoftPackageVersion>
<!-- Microsoft.NET.Test.Sdk https://www.nuget.org/packages/Microsoft.NET.Test.Sdk -->
<MicrosoftNETTestSdkPackageVersion>16.9.1</MicrosoftNETTestSdkPackageVersion>
<MicrosoftNETTestSdkPackageVersion>16.11.0</MicrosoftNETTestSdkPackageVersion>
<!-- NSubstitute https://www.nuget.org/packages/NSubstitute -->
<NSubstitutePackageVersion>4.2.2</NSubstitutePackageVersion>
@ -23,7 +23,17 @@
<xUnitRunnerVisualstudioPackageVersion>2.4.3</xUnitRunnerVisualstudioPackageVersion>
<!-- Mongo2Go https://www.nuget.org/packages/Mongo2Go -->
<Mongo2GoPackageVersion>3.1.1</Mongo2GoPackageVersion>
<Mongo2GoPackageVersion>3.1.3</Mongo2GoPackageVersion>
<IsTestProject Condition="$(MSBuildProjectFullPath.Contains('test')) and ($(MSBuildProjectName.EndsWith('.Tests')) or $(MSBuildProjectName.EndsWith('.TestBase')))">true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Condition="'$(IsTestProject)' == 'true'" Include="coverlet.collector" Version="3.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

1
README.md

@ -1,6 +1,7 @@
# ABP Framework
![build and test](https://img.shields.io/github/workflow/status/abpframework/abp/build%20and%20test/dev?style=flat-square)
[![codecov](https://codecov.io/gh/abpframework/abp/branch/dev/graph/badge.svg?token=jUKLCxa6HF)](https://codecov.io/gh/abpframework/abp)
[![NuGet](https://img.shields.io/nuget/v/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![NuGet (with prereleases)](https://img.shields.io/nuget/vpre/Volo.Abp.Core.svg?style=flat-square)](https://www.nuget.org/packages/Volo.Abp.Core)
[![MyGet (nightly builds)](https://img.shields.io/myget/abp-nightly/vpre/Volo.Abp.svg?style=flat-square)](https://docs.abp.io/en/abp/latest/Nightly-Builds)

44
abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json

@ -310,6 +310,48 @@
"DeleteInvoice" : "Delete Invoice",
"SuccessfullyDeleted": "Successfully deleted!",
"PaymentStateSetTo" : "Payment state set to {0}",
"ChangeState": "Change State"
"ChangeState": "Change State",
"Permission:TrialLicense" : "Trial License",
"Menu:TrialLicenses": "Trial Licenses",
"TrialLicenses": "Trial Licenses",
"UserNameFilter": "Username",
"TrialLicenseStatusFilter": "Status",
"TrialLicenseStartDateFilter": "Start date",
"TrialLicenseEndDateFilter": "End date",
"FirsName": "First name",
"LastName": "Last name",
"Status": "Status",
"StartDate": "Start date",
"EndDate": "End date",
"CompanyName": "Company name",
"PurchasedDate": "Purchased date",
"OrganizationDetail": "Organization Detail",
"SendActivationMail": "Send Activation Mail",
"ActivationMailSentSuccessfully": "Activation mail sent successfully!",
"TrialLicenseStatus": "Trial license status",
"TrialLicenseDetail": "Trial License Detail",
"AcceptsMarketingCommunications": "Marketing Communications",
"PurposeOfUsage": "Purpose of usage",
"CountryName": "Country name",
"CompanySize": "Company size",
"DetailTrialLicense": "Details",
"Requested": "Requested",
"Activated": "Activated",
"PurchasedToNormalLicense": "Purchased",
"Expired": "Expired",
"TrialLicenseDeletionWarningMessage": "Are you sure you want to delete the trial license? Trial license, organization, support accounts will be deleted!",
"LicenseCategoryFilter": "License category",
"Volo.AbpIo.Commercial:030000": "You already used your trial period.",
"Volo.AbpIo.Commercial:030001": "This organization name already exists.",
"Volo.AbpIo.Commercial:030002": "Once activated, trial license cannot be set to requested!",
"Volo.AbpIo.Commercial:030003": "There is no such status!",
"Volo.AbpIo.Commercial:030004": "Status could not be changed due to an unexpected error!",
"Volo.AbpIo.Commercial:030005": "Start and end date can be updated when the trial license is in the -activated- status!",
"Volo.AbpIo.Commercial:030006": "End date must always be greater than start date!",
"Volo.AbpIo.Commercial:030007": "This trial license has already been activated once!",
"Volo.AbpIo.Commercial:030008": "Purchase date can be set only when status is Purchased!",
"Volo.AbpIo.Commercial:030009": "User not found!",
"Volo.AbpIo.Commercial:030010": "To purchase the trial license, first you need to activate your trial license!",
"Volo.AbpIo.Commercial:030011": "You cannot delete a trial license when it is purchased!"
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json

@ -101,6 +101,7 @@
"WeWillSendYouADownloadLink": "We've sent the file to {0}.",
"InvalidFormInputs": "Please, type the valid information specified on the form.",
"DDDBookEmailBody": "Thank you. <br /> To download your book, <a href=\"{0}\">click here</a>.",
"FreeDDDEBook": "Free DDD E-Book"
"FreeDDDEBook": "Free DDD E-Book",
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>."
}
}

5
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -230,7 +230,7 @@
"HowCanIRefundVatExplanation2": "Log in into your <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\">2Checkout</a> account",
"HowCanIRefundVatExplanation3": "Find the appropriate order and press \"Refund Belated VAT\" (enter your VAT ID)",
"HowCanIGetMyInvoice": "How can I get my invoice?",
"HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: PayU and 2Checkout. If you purchase your license through 2Checkout gateway, it sends the PDF invoice to your email address, see <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\">2Checkout invoicing.</a> If you purchase through the PayU gateway or via bank wire transfer, we will prepare and send your invoice. You can request your invoice from the <a href=\"{0}\">organization management page.</a>",
"HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: Iyzico and 2Checkout. If you purchase your license through the 2Checkout gateway, it sends the PDF invoice to your email address, see <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\">2Checkout invoicing.</a> If you purchase through the Iyzico gateway, with custom purchase link or via bank wire transfer, we will prepare and send your invoice. You can request or download your invoice from the <a href=\"{0}\">organization management page</a>. Before contacting us for the invoice, check your organization management page!",
"Forum": "Forum",
"SupportExplanation": "ABP Commercial licenses provides a premium forum support by a team consists of the ABP Framework experts.",
"PrivateTicket": "Private Ticket",
@ -388,6 +388,7 @@
"PurchaseTrialLicenseMessage": "Your license expiration date is {0}. <br> If you want to continue using the projects you created during your free trial period, you need to change the license keys in your <code>appsettings.secrets.json</code> files. Here is your license key:",
"TrialLicenseExpireMessage": "You are using the trial license and your trial license will expire on {0}.",
"TryForFree": "Try For Free",
"TrialLicenseExpiredInfo": "Your trial license period has expired!"
"TrialLicenseExpiredInfo": "Your trial license period has expired!",
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>."
}
}

3
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json

@ -98,6 +98,7 @@
"WeWillSendYouADownloadLink": "{0} adresine email gönderilmiştir.",
"InvalidFormInputs": "Lütfen formda belirtilen geçerli bilgileri yazınız.",
"DDDBookEmailBody": "Teşekkürler. <br /> Kitabı indirmek için, <a href=\"{0}\">buraya tıklayınız</a>.",
"FreeDDDEBook": "Ücretsiz DDD E-Kitap"
"FreeDDDEBook": "Ücretsiz DDD E-Kitap",
"CommercialNewsletterConfirmationMessage": "<a href=\"https://commercial.abp.io/TermsConditions\">Şartlar, Koşullar</a> ve <a href=\"https://commercial.abp.io/Privacy\">Gizlilik politikasını</a> kabul ediyorum."
}
}

2
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json

@ -230,7 +230,7 @@
"HowCanIRefundVatExplanation2": "登录到你的<a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\">2Checkout</a>账户",
"HowCanIRefundVatExplanation3": "找到适当的订单,然后按\"退还已延期的增值税\"(输入你的增值税ID",
"HowCanIGetMyInvoice": "我如何获得发票?",
"HowCanIGetMyInvoiceExplanation": "有两个用于购买许可的支付网关:PayU和2Checkout. 如果你通过2Checkout网关购买许可,则它将PDF发票发送到你的电子邮件地址,请参阅<a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work>2Checkout发票.</a>如果你是通过PayU网关或通过银行电汇购买的,我们将准备并发送你的发票. 你可以从<a href=\"{0}\">组织管理页面</a>索取发票.",
"HowCanIGetMyInvoiceExplanation": "有两个用于购买许可的支付网关:Iyzico和2Checkout. 如果你通过2Checkout网关购买许可,则它将PDF发票发送到你的电子邮件地址,请参阅<a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work>2Checkout发票.</a>如果你是通过Iyzico网关或通过银行电汇购买的,我们将准备并发送你的发票. 你可以从<a href=\"{0}\">组织管理页面</a>索取发票.",
"Forum": "论坛",
"SupportExplanation": "ABP商业版许可包含由ABP框架专家组成的团队提供的高级论坛支持.",
"PrivateTicket": "私有票",

4
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json

@ -228,7 +228,7 @@
"HowCanIRefundVatExplanation2": "登錄到你的<a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\">2Checkout</a>賬戶",
"HowCanIRefundVatExplanation3": "找到適當的訂單,然後按\"退還已延期的增值稅\"(輸入你的增值稅ID",
"HowCanIGetMyInvoice": "我如何獲得發票?",
"HowCanIGetMyInvoiceExplanation": "有兩個用於購買許可的支付網關:PayU和2Checkout. 如果你通過2Checkout網關購買許可,則它將PDF發票發送到你的電子郵件地址,請參閱<a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work>2Checkout發票.</a>如果你是通過PayU網關或通過銀行電匯購買的,我們將準備並發送你的發票. 你可以從<a href=\"{0}\">組織管理頁面</a>索取發票.",
"HowCanIGetMyInvoiceExplanation": "有兩個用於購買許可的支付網關:Iyzico和2Checkout. 如果你通過2Checkout網關購買許可,則它將PDF發票發送到你的電子郵件地址,請參閱<a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work>2Checkout發票.</a>如果你是通過Iyzico網關或通過銀行電匯購買的,我們將準備並發送你的發票. 你可以從<a href=\"{0}\">組織管理頁面</a>索取發票.",
"Forum": "論壇",
"SupportExplanation": "ABP商業版許可包含由ABP框架專家組成的團隊提供的高級論壇支持.",
"PrivateTicket": "私有票",
@ -319,4 +319,4 @@
"MongoDB": "MongoDB"
}
}
}

2
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/en.json

@ -1,4 +1,4 @@
{
{
"culture": "en",
"texts": {
"Permission:CommunityArticle": "Community Article",

2
abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/ro-RO.json

@ -1,4 +1,4 @@
{
{
"culture": "ro-RO",
"texts": {
"Permission:CommunityArticle": "Articol comunitar",

4
build/common.ps1

@ -7,6 +7,7 @@ $rootFolder = (Get-Item -Path "./" -Verbose).FullName
# List of solutions used only in development mode
$solutionPaths = @(
"../framework",
"../studio",
"../modules/basic-theme",
"../modules/users",
"../modules/permission-management",
@ -19,7 +20,8 @@ $solutionPaths = @(
"../modules/background-jobs",
"../modules/account",
"../modules/cms-kit",
"../modules/blob-storing-database"
"../modules/blob-storing-database",
"../studio"
)
if ($full -eq "-f")

2
build/test-all.ps1

@ -7,7 +7,7 @@ $full = $args[0]
foreach ($solutionPath in $solutionPaths) {
$solutionAbsPath = (Join-Path $rootFolder $solutionPath)
Set-Location $solutionAbsPath
dotnet test --no-build --no-restore
dotnet test --no-build --no-restore --collect:"XPlat Code Coverage"
if (-Not $?) {
Write-Host ("Test failed for the solution: " + $solutionPath)
Set-Location $rootFolder

4
codecov.yml

@ -0,0 +1,4 @@
codecov:
branch: dev
require_ci_to_pass: yes
allow_coverage_offsets: true

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>5.0.0</Version>
<Version>5.0.0-beta.2</Version>
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl>

2
configureawait.props

@ -1,7 +1,7 @@
<Project>
<ItemGroup>
<PackageReference Include="ConfigureAwait.Fody" Version="3.3.1" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.5.0">
<PackageReference Include="Fody" Version="6.5.3">
<PrivateAssets>All</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

2
docs/cs/Entity-Framework-Core-PostgreSQL.md

@ -1,4 +1,4 @@
# Přepnutí na EF Core PostgreSQL providera
# Přepnutí na EF Core PostgreSQL providera
Tento dokument vysvětluje, jak přepnout na poskytovatele databáze **PostgreSQL** pro **[spouštěcí šablonu aplikace](Startup-Templates/Application.md)**, která je dodávána s předem nakonfigurovaným SQL poskytovatelem.

2
docs/cs/Getting-Started-AspNetCore-Application.md

@ -1,4 +1,4 @@
# Začínáme s ASP.NET Core MVC aplikací
# Začínáme s ASP.NET Core MVC aplikací
Tento tutoriál vysvětluje jak začít s ABP z ničeho s minimem závislostí. Obvykle chcete začít se **[startovací šablonou](https://abp.io/Templates)**.

2
docs/cs/Getting-Started-Console-Application.md

@ -1,4 +1,4 @@
# Začínáme s konzolovou aplikací
# Začínáme s konzolovou aplikací
Tento tutoriál vysvětluje jak začít s ABP z ničeho s minimem závislostí. Obvykle chcete začít se **[startovací šablonou](https://abp.io/Templates)**.

2
docs/cs/Index.md

@ -1,4 +1,4 @@
# ABP dokumentace
# ABP dokumentace
ABP je **open source aplikační framework** se zaměřením na vývoj webových aplikací založených na ASP.NET Core, zároveň ho však lze využít i k vývoji jiných typů aplikací.

2
docs/en/API/Application-Configuration.md

@ -1,4 +1,4 @@
# Application Configuration Endpoint
# Application Configuration Endpoint
ABP Framework provides a pre-built and standard endpoint that contains some useful information about the application/service. Here, the list of some fundamental information at this endpoint:

2
docs/en/API/Swagger-Integration.md

@ -1,4 +1,4 @@
# Swagger Integration
# Swagger Integration
[Swagger (OpenAPI)](https://swagger.io/) is a language-agnostic specification for describing REST APIs. It allows both computers and humans to understand the capabilities of a REST API without direct access to the source code. Its main goals are to:

2
docs/en/Audit-Logging.md

@ -1,4 +1,4 @@
# Audit Logging
# Audit Logging
[Wikipedia](https://en.wikipedia.org/wiki/Audit_trail): "*An audit trail (also called **audit log**) is a security-relevant chronological record, set of records, and/or destination and source of records that provide documentary evidence of the sequence of activities that have affected at any time a specific operation, procedure, or event*".

11
docs/en/Background-Jobs-Hangfire.md

@ -95,12 +95,21 @@ app.UseHangfireDashboard("/hangfire", new DashboardOptions
});
```
* `AbpHangfireAuthorizationFilter` is an implementation of an authorization filter.
#### AbpHangfireAuthorizationFilter
`AbpHangfireAuthorizationFilter` class has the following fields:
* **`enableTenant` (`bool`, default: `false`):** Enables/disables accessing the Hangfire dashboard on tenant users.
* **`requiredPermissionName` (`string`, default: `null`):** Hangfire dashboard is accessible only if the current user has the specified permission. In this case, if we specify a permission name, we don't need to set `enableTenant` `true` because the permission system already does it.
If you want to require an additional permission, you can pass it into the constructor as below:
```csharp
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter("MyHangFireDashboardPermissionName") }
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter(requiredPermissionName: "MyHangFireDashboardPermissionName") }
});
```

99
docs/en/Background-Workers-Hangfire.md

@ -0,0 +1,99 @@
# Hangfire Background Worker Manager
[Hangfire](https://https://www.hangfire.io/) is an advanced background jobs and worker manager. You can integrate Hangfire with the ABP Framework to use it instead of the [default background worker manager](Background-Workers.md).
The major advantage is that you can use the same server farm to manage your Background Jobs and Workers, as well as leverage the advanced scheduling that is available from Hangfire for [Recurring Jobs](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html?highlight=recurring), aka Background Workers.
## Installation
It is suggested to use the [ABP CLI](CLI.md) to install this package.
### Using the ABP CLI
Open a command line window in the folder of the project (.csproj file) and type the following command:
````bash
abp add-package Volo.Abp.BackgroundWorkers.Hangfire
````
### Manual Installation
If you want to manually install;
1. Add the [Volo.Abp.BackgroundWorkers.Hangfire](https://www.nuget.org/packages/Volo.Abp.BackgroundWorkers.Hangfire) NuGet package to your project:
````
Install-Package Volo.Abp.BackgroundWorkers.Hangfire
````
2. Add the `AbpBackgroundWorkersHangfireModule` to the dependency list of your module:
````csharp
[DependsOn(
//...other dependencies
typeof(AbpBackgroundWorkersHangfireModule) //Add the new module dependency
)]
public class YourModule : AbpModule
{
}
````
> Hangfire background worker integration provides an adapter `HangfirePeriodicBackgroundWorkerAdapter` to automatically load any `PeriodicBackgroundWorkerBase` and `AsyncPeriodicBackgroundWorkerBase` derived classes as `IHangfireBackgroundWorker` instances. This allows you to still to easily switch over to use Hangfire as the background manager even you have existing background workers that are based on the [default background workers implementation](Background-Workers.md).
## Create a Background Worker
`HangfireBackgroundWorkerBase` is an easy way to create a background worker.
```` csharp
public class MyLogWorker : HangfireBackgroundWorkerBase
{
public MyLogWorker()
{
RecurringJobId = nameof(MyLogWorker);
CronExpression = Cron.Daily();
}
public override Task DoWorkAsync()
{
Logger.LogInformation("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}
````
* **RecurringJobId** Is an optional parameter, see [Hangfire document](https://docs.hangfire.io/en/latest/background-methods/performing-recurrent-tasks.html)
* **CronExpression** Is a CRON expression, see [CRON expression](https://en.wikipedia.org/wiki/Cron#CRON_expression)
> You can directly implement the `IHangfireBackgroundWorker`, but `HangfireBackgroundWorkerBase` provides some useful properties like Logger.
## Register BackgroundWorkerManager
After creating a background worker class, you should add it to the `IBackgroundWorkerManager`. The most common place is the `OnApplicationInitialization` method of your module class:
```` csharp
[DependsOn(typeof(AbpBackgroundWorkersModule))]
public class MyModule : AbpModule
{
public override void OnApplicationInitialization(
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<MyLogWorker>();
}
}
````
`context.AddBackgroundWorker(...)` is a shortcut extension method for the expression below:
```` csharp
context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.Add(
context
.ServiceProvider
.GetRequiredService<MyLogWorker>()
);
````
So, it resolves the given background worker and adds to the `IBackgroundWorkerManager`.
While we generally add workers in OnApplicationInitialization, there are no restrictions on that. You can inject IBackgroundWorkerManager anywhere and add workers at runtime. Background worker manager will stop and release all the registered workers when your application is being shut down.

11
docs/en/Background-Workers.md

@ -131,10 +131,15 @@ If that's a problem for your workers, you have two options;
* Disable the background worker system using the `AbpBackgroundWorkerOptions` described above, for all the application instances, except one of them.
* Disable the background worker system for all the application instances and create another special application that runs on a single server and execute the workers.
## Quartz Integration
## Integrations
ABP Framework's background worker system is good to implement periodic tasks. However, you may want to use an advanced task scheduler like [Quartz](https://www.quartz-scheduler.net/). See the community contributed [quartz integration](Background-Workers-Quartz.md) for the background workers.
Background worker system is extensible and you can change the default background worker manager with your own implementation or on of the pre-built integrations.
See pre-built worker manager alternatives:
* [Quartz Background Worker Manager](Background-Workers-Quartz.md)
* [Hangfire Background Worker Manager](Background-Workers-Hangfire.md)
## See Also
* [Quartz Integration for the background workers](Background-Workers-Quartz.md)
* [Background Jobs](Background-Jobs.md)

2
docs/en/Best-Practices/Application-Services.md

@ -1,4 +1,4 @@
## Application Services Best Practices & Conventions
## Application Services Best Practices & Conventions
* **Do** create an application service for each **aggregate root**.

2
docs/en/Best-Practices/Data-Transfer-Objects.md

@ -1,4 +1,4 @@
## Data Transfer Objects Best Practices & Conventions
## Data Transfer Objects Best Practices & Conventions
* **Do** define DTOs in the **application contracts** package.
* **Do** inherit from the pre-built **base DTO classes** where possible and necessary (like `EntityDto<TKey>`, `CreationAuditedEntityDto<TKey>`, `AuditedEntityDto<TKey>`, `FullAuditedEntityDto<TKey>` and so on).

2
docs/en/Best-Practices/Domain-Services.md

@ -1,4 +1,4 @@
## Domain Services Best Practices & Conventions
## Domain Services Best Practices & Conventions
> **This document is not ready yet. Please see the [Domain Services](../Domain-Services.md) document.**

2
docs/en/Best-Practices/Entity-Framework-Core-Integration.md

@ -1,4 +1,4 @@
## Entity Framework Core Integration Best Practices
## Entity Framework Core Integration Best Practices
> See [Entity Framework Core Integration document](../Entity-Framework-Core.md) for the basics of the EF Core integration.

2
docs/en/Best-Practices/Index.md

@ -1,4 +1,4 @@
## Module Development Best Practices & Conventions
## Module Development Best Practices & Conventions
### Introduction

2
docs/en/Best-Practices/Module-Architecture.md

@ -1,4 +1,4 @@
## Module Architecture Best Practices & Conventions
## Module Architecture Best Practices & Conventions
### Solution Structure

2
docs/en/Best-Practices/MongoDB-Integration.md

@ -1,4 +1,4 @@
## MongoDB Integration
## MongoDB Integration
* Do define a separated `MongoDbContext` interface and class for each module.

308
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/POST.md

@ -0,0 +1,308 @@
# ABP Platform 5.0 Beta 1 Has Been Released
Today, we are excited to release the [ABP Framework](https://abp.io/) and the [ABP Commercial](https://commercial.abp.io/) version **5.0 Beta**. This blog post introduces the new features and important changes in this new version.
> **The planned release date for the [5.0.0 Release Candidate](https://github.com/abpframework/abp/milestone/51) version is November, 2021**.
Please try the beta 1 version and provide feedback for a more stable ABP version 5.0! Thank you all.
## Get Started with the 5.0 Beta 1
follow the steps below to try the version 5.0.0 beta 1 today;
1) **Upgrade** the ABP CLI to the version `5.0.0-beta.1` using a command line terminal:
````bash
dotnet tool update Volo.Abp.Cli -g --version 5.0.0-beta.1
````
**or install** if you haven't installed before:
````bash
dotnet tool install Volo.Abp.Cli -g --version 5.0.0-beta.1
````
2) Create a **new application** with the `--preview` option:
````bash
abp new BookStore --preview
````
See the [ABP CLI documentation](https://docs.abp.io/en/abp/latest/CLI) for all the available options.
> You can also use the *Direct Download* tab on the [Get Started](https://abp.io/get-started) page by selecting the **Preview checkbox**.
### Visual Studio Upgrade
As .NET 6 is a preview version you need to make changes on the Visual Studio 2019.
If you want to run a .NET 6 project on Visual Studio 2019, you need to install the latest .NET SDK 6 from https://dotnet.microsoft.com/download/dotnet/6.0
and also enable the `Use Previews of the .NET SDK` option from Visual Studio 2019 options. See the screenshot:
![Enable Using Previews of the .NET SDK ](use-preview-visual-studio.png)
Alternatively you can download the latest Visual Studio 2022 preview to run/create the .NET 6 projects. We have tested the ABP solution with the Visual Studio 2022 `17.0.0 Preview 4.1`. Check out https://visualstudio.microsoft.com/vs/preview/ for more information.
### Migration Notes & Breaking Changes
This is a major version and there are some breaking changes and upgrade steps. Here, a list of important breaking changes in this version:
* Upgraded to .NET 6.0-rc.1, so you need to move your solution to .NET 6.0 if you want to use the ABP 5.0.
* `IRepository` doesn't inherit from `IQueryable` anymore. It was already made obsolete in 4.2.
* Removed NGXS and states from the Angular UI.
* Removed gulp dependency from the MVC / Razor Pages UI in favor of `abp install-libs` command of ABP CLI.
Please see the [migration document](https://docs.abp.io/en/abp/5.0/Migration-Guides/Abp-5_0) for all the details. You can also see all [the closed issues and pull request](https://github.com/abpframework/abp/releases/tag/5.0.0-beta.1) on GitHub.
## What's new with Beta 1?
In this section, I will introduce some major features released with beta 1.
### Static (Generated) Client Proxies for C# and JavaScript
Dynamic C# ([see](https://docs.abp.io/en/abp/latest/API/Dynamic-CSharp-API-Clients)) and JavaScript ([see](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Dynamic-JavaScript-Proxies)) client proxy system is one of the most loved features of the ABP Framework. It generates the proxy code on runtime and makes client-to-server calls a breeze. With ABP 5.0, we are providing an alternative approach: You can generate the client proxy code on development-time.
Development-time client proxy generation has a performance advantage since it doesn't need to obtain the HTTP API definition on runtime. It also makes it easier to consume a (micro)service behind an API Gateway. With dynamic proxies, we should return a combined HTTP API definition from the API Gateway and need to add HTTP API layers of the microservices to the gateway. Static proxies removes this requirement. One disadvantage is that you should re-generate the client proxy code whenever you change your API endpoint definition. Yes, software development always has tradeoffs :)
Working with static client proxy generation is simple with the ABP CLI. You first need to run the server application, open a command-line terminal, locate to the root folder of your client application, then run the `generate-proxy` command of the ABP CLI.
#### Creating C# client proxies
C# client proxies are useful to consume APIs from Blazor WebAssembly applications. It is also useful for microservice to microservice HTTP API calls. Notice that the client application need to have a reference to the application service contracts (typically, the `.Application.Contracts` project in your solution) in order to consume the services.
**Example usage:**
````bash
abp generate-proxy -t csharp -u https://localhost:44305
````
`-t` indicates the client type, C# here. `-u` is the URL of the server application. It creates the proxies for the application (the app module) by default. You can specify the module name as `-m <module-name>` if you are building a modular system. The following figure shows the generated files:
![csharp-proxies](csharp-proxies.png)
Once the proxies are generated, you can inject and use the application service interfaces of these proxies, like `IProductAppService` in this example. Usage is same of the [dynamic C# client proxies](https://docs.abp.io/en/abp/latest/API/Dynamic-CSharp-API-Clients).
#### Creating JavaScript client proxies
JavaScript proxies are useful to consume APIs from MVC / Razor Pages UI. It works on JQuery AJAX API, just like the [dynamic JavaScript proxies](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Dynamic-JavaScript-Proxies).
**Example usage:**
````bash
abp generate-proxy -t js -u https://localhost:44305
````
The following figure shows the generated file:
![js-proxies](js-proxies.png)
Then you can consume the server-side APIs from your JavaScript code just like the [dynamic JavaScript proxies](https://docs.abp.io/en/abp/latest/UI/AspNetCore/Dynamic-JavaScript-Proxies).
#### Creating Angular client proxies
Angular developers knows that the generate-proxy command was already available in ABP's previous versions to create client-side proxy services in the Angular UI. The same functionality continues to be available and already [documented here](https://docs.abp.io/en/abp/latest/UI/Angular/Service-Proxies).
**Example usage:**
````bash
abp generate-proxy -t ng -u https://localhost:44305
````
### Transactional Outbox & Inbox for the Distributed Event Bus
This was one of the most awaited features by distributed software developers.
The [transactional outbox pattern](https://microservices.io/patterns/data/transactional-outbox.html) is used to publishing distributed events within the same transaction that manipulates the application database. Distributed events are saved into the database inside the same transaction with your data changes, then sent to the message broker (like RabbitMQ or Kafka) by a separate background worker with a re-try system. In this way, it ensures the consistency between your database state and the published events.
The transactional inbox pattern, on the other hand, saves incoming events into database first, then executes the event handler in a transactional manner and removes the event from the inbox queue in the same transaction. It also ensures that the event is only executed one time by keeping the processed messages for a while and discarding the duplicate events received from the message broker.
Enabling the inbox and outbox patterns requires a few manual steps for your application. We've created a simple [console application example](https://github.com/abpframework/abp/tree/dev/test/DistEvents), but I will also explain all the steps here.
#### Pre-requirements
First of all, you need to have EF Core or MongoDB installed into your solution. It should be already installed if you'd created a solution from the ABP startup template.
#### Install the packages
Install the new [Volo.Abp.EventBus.Boxes](https://www.nuget.org/packages/Volo.Abp.EventBus.Boxes) NuGet package to your database layer (to `EntityFrameworkCore` or `MongoDB` project) or to the host application. Open a command-line terminal at the root directory of your database (or host) project and execute the following command:
````csharp
abp add-package Volo.Abp.EventBus.Boxes
````
This will install the package and setup the ABP module dependency. This package depends on [DistributedLock.Core](https://www.nuget.org/packages/DistributedLock.Core) library which provides a distributed locking system for concurrency control in a distributed environment. There are [many distributed lock providers](https://github.com/madelson/DistributedLock#implementations), including Redis, SqlServer and ZooKeeper. You can use the one you like. Here, I will show the Redis provider.
Add [DistributedLock.Redis](https://www.nuget.org/packages/DistributedLock.Redis) NuGet package to your project, then add the following code into the ConfigureService method of your ABP module class:
````csharp
context.Services.AddSingleton<IDistributedLockProvider>(sp =>
{
var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
});
````
We are getting the Redis configuration from the `appsettings.json` file, so add the following lines to your `appsettings.json` file:
````json
"Redis": {
"Configuration": "127.0.0.1"
}
````
You can change the IP or customize the configuration based on your environment.
#### Configure the DbContext
Open your `DbContext` class, implement the `IHasEventInbox` and the `IHasEventOutbox` interfaces. You should end up by adding two `DbSet` properties into your `DbContext` class:
````csharp
public DbSet<IncomingEventRecord> IncomingEvents { get; set; }
public DbSet<OutgoingEventRecord> OutgoingEvents { get; set; }
````
Add the following lines inside the `OnModelCreating` method of your `DbContext` class:
````csharp
builder.ConfigureEventInbox();
builder.ConfigureEventOutbox();
````
It is similar for MongoDB; implement the `IHasEventInbox` and the `IHasEventOutbox` interfaces. There is no `Configure...` method for MongoDB.
Now, we've added inbox/outbox related tables to our database schema. Now, for EF Core, use the standard `Add-Migration` and `Update-Database` commands to apply changes into your database (you can skip this step for MongoDB). If you want to use the command-line terminal, run the following commands in the root directory of the database integration project:
````bash
dotnet ef migrations add "Added_Event_Boxes"
dotnet ef database update
````
#### Configure the distributed event bus options
As the last step, write the following configuration code inside the `ConfigureServices` method of your module class:
````csharp
Configure<AbpDistributedEventBusOptions>(options =>
{
options.Outboxes.Configure(config =>
{
config.UseDbContext<YourDbContext>();
});
options.Inboxes.Configure(config =>
{
config.UseDbContext<YourDbContext>();
});
});
````
Replace `YourDbContext` with your `DbContext` class.
That's all. You can continue to publishing and consuming events just as before. See the [distributed event bus documentation](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus) if you don't know how to use it.
### Publishing events in transaction
The previous feature (outbox & inbox) solves the transactional event publishing problem for distributed systems. This feature, publishing events in transaction, solves the problem of executing event handlers in the same transaction that the events are published in for non-distributed applications. With 5.0, all events (local or distributed) are handled in the same transaction. If any handler fails, the transaction is rolled back. If you don't want that, you should use try/catch and ignore the exception inside your event handler.
Remember that if you don't install a real distributed event provider (like [RabbitMQ](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus-RabbitMQ-Integration) or [Kafka](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus-Kafka-Integration)), the [distributed events](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus) are actually executed in-process, just like the [local events](https://docs.abp.io/en/abp/latest/Local-Event-Bus). So, with this development, all the events become transactional, even if your system is distributed or not.
No action needed to take. It will just work by default. There is a [deprecation note](https://github.com/abpframework/abp/issues/9897) related to this change (some pre-defined events [will be removed](https://github.com/abpframework/abp/issues/9908) in the next major version since they are not needed anymore)
### Inactivating a user
The [Identity module](https://docs.abp.io/en/abp/latest/Modules/Identity) has a new feature to make a user active or inactive. Inactive users can not login to the system. In this way, you can disable a user account without deleting it. An *Active* checkbox is added to the user create/edit dialog to control it on the UI:
![user-active](user-active.png)
EF Core developers should add a new database migration since this brings a new field to the `AbpUsers` table.
### Overriding email settings per tenant
If you're building a multi-tenant application, it is now possible to override email sending settings per tenant. To make this possible, you should first enable that [feature](https://docs.abp.io/en/abp/latest/Features) to the tenant you want, by clicking the *Actions -> Features* for the tenant.
![tenant-features](tenant-features.png)
Enable the feature using the checkbox as shown in the following modal:
![enable-email-tenant](enable-email-tenant.png)
Then the tenant admin can open the email settings page under the Administration -> Settings menu (on development environment, logout, switch to the tenant and re-login with the tenant admin):
![email-settings](email-settings.png)
### Hangfire dashboard permission
ABP allows to use Hangfire as the background job manager when you install the integration package [as documented](https://docs.abp.io/en/abp/5.0/Background-Jobs-Hangfire). Hangfire's dashboard is used to monitor and control the background job queues. Here, a screenshot from the dashboard:
![hangfire-dashboard](hangfire-dashboard.png)
Hangfire's dashboard is not authorized by default, so any user can navigate to the `/hangfire` URL and see/control the jobs. With the ABP version 5.0, we've added a built-in authorization implementation for the Hangfire dashboard. Instead of `app.UseHangfireDashboard();`, you can use the following middleware configuration:
````csharp
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] { new AbpHangfireAuthorizationFilter() }
});
````
In this way, only the authenticated users can see the dashboard. However, we suggest to set a permission name, so only the users with that permission can see the dashboard:
````csharp
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
AsyncAuthorization = new[] {
new AbpHangfireAuthorizationFilter("MyPermissionName")
}
});
````
You can define the permission (`MyPermissionName` in this example) using the standard [permission system](https://docs.abp.io/en/abp/5.0/Authorization#permission-system).
### Introducing AbpControllerBase
ABP provides an `AbpController` class that you can inherit your MVC controllers from. It provides some pre-injected services to simplify your controllers. With v5.0, we are adding a second base controller class, `AbpControllerBase`, which is more proper to create API controllers (without view features). It is suggested to inherit from the `AbpControllerBase` class to create API controllers, instead of the `AbpController` class.
**Example:**
````csharp
[Route("api/products")]
public class ProductController : AbpControllerBase
{
// TODO: ...
}
````
## Ongoing Works & Next Release
We'd published important features and changes with this beta 1 release. However, there are still some major works in development. The most important work is the **Bootstrap 5 upgrade**. ABP 5.0 will work on Bootstrap 5, which is an important change for existing applications. We suggest to prepare for this change from now.
The next release will be 5.0.0-beta.2. It will include the Bootstrap 5 upgrade. We don't plan make another big work for the version 5.0. After the beta.2, we will work on tests, feedbacks and documentation to prepare a stable final release.
## Community News
### ABP was on ASP.NET Community Startup!
It was great for us to be invited to Microsoft's [ASP.NET Community Weekly Standup](https://dotnet.microsoft.com/live/community-standup) show, at September 28. There was a very high attention and that made us very happy. Thanks to the ABP Community and all the watchers :) If you've missed the talk, [you can watch it here](https://www.youtube.com/watch?v=vMWM-_ihjwM).
### Upcoming ABP Book!
I am currently authoring the first official book for the ABP Framework and it is on [pre-sale on Amazon](https://www.amazon.com/Mastering-ABP-Framework-maintainable-implementing-dp-1801079242/dp/1801079242) now.
![abp-book-cover](abp-book-cover.png)
This books is a complete guide to start working with the ABP Framework, explore the ABP features and concepts. It also contains chapters for DDD, modular application development and multi-tenancy to learn and practically work with the ABP architecture to build maintainable software solutions and create SaaS applications. The book will be based on ABP 5.0 and published in the beginning of 2022. You can [pre-order now](https://www.amazon.com/Mastering-ABP-Framework-maintainable-implementing-dp-1801079242/dp/1801079242)!
### New ABP Community posts
Here, the latest posts added to the [ABP community](https://community.abp.io/):
* [Deploy ABP Framework .NET Core tiered application to docker swarm](https://community.abp.io/articles/deploy-abp-framework-dotnet-core-tiered-app-to-docker-swarm-kcrjbjec)
* [How to override localization strings of depending modules](https://community.abp.io/articles/how-to-override-localization-strings-of-depending-modules-ba1oy03l)
* [Centralized logging for .NET Core ABP microservices application using Seq](https://community.abp.io/articles/centralized-logging-for-.net-core-abp-microservices-app-using-seq-g1xe7e7y)
* [Extend Tenant management and add custom host to your ABP application](https://community.abp.io/articles/extend-tenant-management-and-add-custom-host-to-your-abp-app-lwmi9lr5)
Thanks to the ABP Community for all the contents they have published. You can also post your ABP and .NET related (text or video) contents to the ABP Community.
## Conclusion
The ABP version 5.0 is coming with important changes (like .NET 6 and Bootstrap 5) and features. In this blog post, I summarized the news about that new version. Please try it and provide feedback by opening issues on [the GitHub repository](https://github.com/abpframework/abp). Thank you all!

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/abp-book-cover.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/csharp-proxies.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/email-settings.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/enable-email-tenant.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/hangfire-dashboard.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/js-proxies.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/tenant-features.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/use-preview-visual-studio.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/en/Blog-Posts/2021-10-05 v5_0_Beta1/user-active.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

2
docs/en/CLI.md

@ -1,4 +1,4 @@
# ABP CLI
# ABP CLI
ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions.

BIN
docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

88
docs/en/Community-Articles/2021-09-25-How-to-Override-Localization-Strings-Of-Depending-Modules/POST.md

@ -0,0 +1,88 @@
# How to override localization strings of depending modules
## Source Code
You can find the source of the example solution used in this article [here](https://github.com/abpframework/abp-samples/tree/master/DocumentationSamples/ExtendLocalizationResource).
## Getting Started
This example is based on the following document
https://docs.abp.io/en/abp/latest/Localization#extending-existing-resource
We will change the default `DisplayName:Abp.Timing.Timezone` and `Description:Abp.Timing.Timezone` of [`AbpTimingResource`](https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/AbpTimingResource.cs) and add localized text in [Russian language(`ru`)](https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/en.json).
I created the `AbpTiming` folder in the `Localization` directory of the `ExtendLocalizationResource.Domain.Shared` project.
Create `en.json` and `ru.json` in its directory.
`en.json`
```json
{
"culture": "en",
"texts": {
"DisplayName:Abp.Timing.Timezone": "My Time zone",
"Description:Abp.Timing.Timezone": "My Application time zone"
}
}
```
`ru.json`
```json
{
"culture": "ru",
"texts": {
"DisplayName:Abp.Timing.Timezone": "Часовой пояс",
"Description:Abp.Timing.Timezone": "Часовой пояс приложения"
}
}
```
![](1.png)
We have below content in `ExtendLocalizationResource.Domain.Shared.csproj` file, See [Virtual-File-System](https://docs.abp.io/en/abp/latest/Virtual-File-System#working-with-the-embedded-files) understand how it works.
```xml
<ItemGroup>
<EmbeddedResource Include="Localization\ExtendLocalizationResource\*.json" />
<Content Remove="Localization\ExtendLocalizationResource\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="5.0.*" />
</ItemGroup>
```
Change the code of the `ConfigureServices` method in `ExtendLocalizationResourceDomainSharedModule`.
```cs
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<ExtendLocalizationResourceResource>("en")
.AddBaseTypes(typeof(AbpValidationResource))
.AddVirtualJson("/Localization/ExtendLocalizationResource");
//add following code
options.Resources
.Get<AbpTimingResource>()
.AddVirtualJson("/Localization/AbpTiming");
options.DefaultResourceType = typeof(ExtendLocalizationResourceResource);
});
```
Execute `ExtendLocalizationResource.DbMigrator` to migrate the database and run `ExtendLocalizationResource.Web`.
We have changed the English localization text and added Russian localization.
### Index page
```cs
<p>@AbpTimingResource["DisplayName:Abp.Timing.Timezone"]</p>
@using(CultureHelper.Use("ru"))
{
<p>@AbpTimingResource["DisplayName:Abp.Timing.Timezone"]</p>
}
```
![](2.png)

2
docs/en/Configuration.md

@ -1,3 +1,3 @@
# Configuration
# Configuration
ASP.NET Core has an flexible and extensible key-value based configuration system. In fact, the configuration system is a part of Microsoft.Extensions libraries and it is independent from ASP.NET Core. That means it can be used in any type of application. See [Microsoft's documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/) to learn the configuration infrastructure. ABP framework is 100% compatible with the configuration system.

2
docs/en/Dependency-Injection.md

@ -1,4 +1,4 @@
# Dependency Injection
# Dependency Injection
ABP's Dependency Injection system is developed based on Microsoft's [dependency injection extension](https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96) library (Microsoft.Extensions.DependencyInjection nuget package). So, it's documentation is valid in ABP too.

133
docs/en/Distributed-Event-Bus-Azure-Integration.md

@ -0,0 +1,133 @@
# Distributed Event Bus Azure Integration
> This document explains **how to configure the [Azure Service Bus](https://azure.microsoft.com/en-us/services/service-bus/)** as the distributed event bus provider. See the [distributed event bus document](Distributed-Event-Bus.md) to learn how to use the distributed event bus system
## Installation
Use the ABP CLI to add [Volo.Abp.EventBus.Azure](https://www.nuget.org/packages/Volo.Abp.EventBus.Azure) NuGet package to your project:
* Install the [ABP CLI](https://docs.abp.io/en/abp/latest/CLI) if you haven't installed before.
* Open a command line (terminal) in the directory of the `.csproj` file you want to add the `Volo.Abp.EventBus.Azure` package.
* Run `abp add-package Volo.Abp.EventBus.Azure` command.
If you want to do it manually, install the [Volo.Abp.EventBus.Azure](https://www.nuget.org/packages/Volo.Abp.EventBus.Azure) NuGet package to your project and add `[DependsOn(typeof(AbpEventBusAzureModule))]` to the [ABP module](Module-Development-Basics.md) class inside your project.
## Configuration
You can configure using the standard [configuration system](Configuration.md), like using the `appsettings.json` file, or using the [options](Options.md) classes.
### `appsettings.json` file configuration
This is the simplest way to configure the Azure Service Bus settings. It is also very strong since you can use any other configuration source (like environment variables) that is [supported by the AspNet Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/).
**Example: The minimal configuration to connect to Azure Service Bus Namespace with default configurations**
````json
{
"Azure": {
"ServiceBus": {
"Connections": {
"Default": {
"ConnectionString": "Endpoint=sb://sb-my-app.servicebus.windows.net/;SharedAccessKeyName={{Policy Name}};SharedAccessKey={};EntityPath=marketing-consent"
}
}
},
"EventBus": {
"ConnectionName": "Default",
"SubscriberName": "MySubscriberName",
"TopicName": "MyTopicName"
}
}
}
````
* `MySubscriberName` is the name of this subscription, which is used as the **Subscriber** on the Azure Service Bus.
* `MyTopicName` is the **topic name**.
See [the Azure Service Bus document](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-queues-topics-subscriptions) to understand these options better.
#### Connections
If you need to connect to another Azure Service Bus Namespace the Default, you need to configure the connection properties.
**Example: Declare two connections and use one of them for the event bus**
````json
{
"Azure": {
"ServiceBus": {
"Connections": {
"Default": {
"ConnectionString": "Endpoint=sb://sb-my-app.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey={{SharedAccessKey}}"
},
"SecondConnection": {
"ConnectionString": "Endpoint=sb://sb-my-app.servicebus.windows.net/;SharedAccessKeyName={{Policy Name}};SharedAccessKey={{SharedAccessKey}}"
}
}
},
"EventBus": {
"ConnectionName": "SecondConnection",
"SubscriberName": "MySubscriberName",
"TopicName": "MyTopicName"
}
}
}
````
This allows you to use multiple Azure Service Bus namespaces in your application, but select one of them for the event bus.
You can use any of the [ServiceBusAdministrationClientOptions](https://docs.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.administration.servicebusadministrationclientoptions?view=azure-dotnet), [ServiceBusClientOptions](https://docs.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusclientoptions?view=azure-dotnet), [ServiceBusProcessorOptions](https://docs.microsoft.com/en-us/dotnet/api/azure.messaging.servicebus.servicebusprocessoroptions?view=azure-dotnet) properties for the connection.
**Example: Specify the Admin, Client and Processor options**
````json
{
"Azure": {
"ServiceBus": {
"Connections": {
"Default": {
"ConnectionString": "Endpoint=sb://sb-my-app.servicebus.windows.net/;SharedAccessKeyName={{Policy Name}};SharedAccessKey={};EntityPath=marketing-consent",
"Admin": {
"Retry": {
"MaxRetries": 3
}
},
"Client": {
"RetryOptions": {
"MaxRetries": 1
}
},
"Processor": {
"AutoCompleteMessages": true,
"ReceiveMode": "ReceiveAndDelete"
}
}
}
},
"EventBus": {
"ConnectionName": "Default",
"SubscriberName": "MySubscriberName",
"TopicName": "MyTopicName"
}
}
}
````
### The Options Classes
`AbpAzureServiceBusOptions` and `AbpAzureEventBusOptions` classes can be used to configure the connection strings and event bus options for Azure Service Bus.
You can configure this options inside the `ConfigureServices` of your [module](Module-Development-Basics.md).
**Example: Configure the connection**
````csharp
Configure<AbpAzureServiceBusOptions>(options =>
{
options.Connections.Default.ConnectionString = "Endpoint=sb://sb-my-app.servicebus.windows.net/;SharedAccessKeyName={{Policy Name}};SharedAccessKey={}";
options.Connections.Default.Admin.Retry.MaxRetries = 3;
options.Connections.Default.Client.RetryOptions.MaxRetries = 1;
});
````
Using these options classes can be combined with the `appsettings.json` way. Configuring an option property in the code overrides the value in the configuration file.

54
docs/en/Distributed-Event-Bus.md

@ -7,6 +7,7 @@ Distributed Event bus system allows to **publish** and **subscribe** to events t
Distributed event bus system provides an **abstraction** that can be implemented by any vendor/provider. There are four providers implemented out of the box:
* `LocalDistributedEventBus` is the default implementation that implements the distributed event bus to work as in-process. Yes! The **default implementation works just like the [local event bus](Local-Event-Bus.md)**, if you don't configure a real distributed provider.
* `AzureDistributedEventBus` implements the distributed event bus with the [Azure Service Bus](https://azure.microsoft.com/en-us/services/service-bus/). See the [Azure Service Bus integration document](Distributed-Event-Bus-Azure-Integration.md) to learn how to configure it.
* `RabbitMqDistributedEventBus` implements the distributed event bus with the [RabbitMQ](https://www.rabbitmq.com/). See the [RabbitMQ integration document](Distributed-Event-Bus-RabbitMQ-Integration.md) to learn how to configure it.
* `KafkaDistributedEventBus` implements the distributed event bus with the [Kafka](https://kafka.apache.org/). See the [Kafka integration document](Distributed-Event-Bus-Kafka-Integration.md) to learn how to configure it.
* `RebusDistributedEventBus` implements the distributed event bus with the [Rebus](http://mookid.dk/category/rebus/). See the [Rebus integration document](Distributed-Event-Bus-Rebus-Integration.md) to learn how to configure it.
@ -301,55 +302,4 @@ namespace AbpDemo
}
````
This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options.
## Exception Handling
ABP provides exception handling and retries when an exception occurs, it will move to the dead letter queue after the retry fails.
Enable exception handling:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.EnabledErrorHandle = true;
options.UseRetryStrategy();
});
}
```
* `EnabledErrorHandle` is used to enable exception handing.
* `UseRetryStrategy` is used to enable retry.
When an exception occurs, it will retry every three seconds up to the maximum number of retries(default is 3) and move to dead letter queue, you can change the number of retries, retry interval and dead letter queue name:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.DeadLetterName = "dead_queue";
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### Error Handle Selector
By default all event types will be exception handling, you can use `ErrorHandleSelector` of `AbpEventBusOptions` to change it:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` actually a list of type predicate. You can write a lambda expression to define your filter.
### Customize Exception Handling
ABP defines the `IEventErrorHandler` interface and implemented by the provider, you can replace it via [dependency injection](Dependency-Injection.md)
This example uses the `AutoMap` attribute of the AutoMapper to configure the mapping. You could create a profile class instead. Please refer to the AutoMapper document for more options.

2
docs/en/Domain-Services.md

@ -1,4 +1,4 @@
# Domain Services
# Domain Services
## Introduction

2
docs/en/Emailing.md

@ -1,4 +1,4 @@
# Email Sending
# Email Sending
ABP Framework provides various services, settings and integrations for sending emails;

2
docs/en/Entity-Framework-Core-Migrations.md

@ -1,4 +1,4 @@
# EF Core Database Migrations
# EF Core Database Migrations
This document begins by **introducing the default structure** provided by [the application startup template](Startup-Templates/Application.md) and **discusses various scenarios** you may want to implement for your own application.

2
docs/en/Entity-Framework-Core-MySQL.md

@ -1,4 +1,4 @@
# Switch to EF Core MySQL Provider
# Switch to EF Core MySQL Provider
This document explains how to switch to the **MySQL** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Entity-Framework-Core-Oracle-Devart.md

@ -1,4 +1,4 @@
# Switch to EF Core Oracle Devart Provider
# Switch to EF Core Oracle Devart Provider
This document explains how to switch to the **Oracle** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Entity-Framework-Core-Oracle-Official.md

@ -1,4 +1,4 @@
# Switch to EF Core Oracle Provider
# Switch to EF Core Oracle Provider
This document explains how to switch to the **Oracle** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Entity-Framework-Core-Oracle.md

@ -1,4 +1,4 @@
# Switch to EF Core Oracle Provider
# Switch to EF Core Oracle Provider
This document explains how to switch to the **Oracle** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Entity-Framework-Core-Other-DBMS.md

@ -1,4 +1,4 @@
# Switch to Another DBMS for Entity Framework Core
# Switch to Another DBMS for Entity Framework Core
**[The application startup template](Startup-Templates/Application.md)** comes with **SQL Server provider pre-configured** for the Entity Framework Core. However, EF Core supports [many other DBMSs](https://docs.microsoft.com/en-us/ef/core/providers/) and you can use any of them within your ABP based applications.

2
docs/en/Entity-Framework-Core-PostgreSQL.md

@ -1,4 +1,4 @@
# Switch to EF Core PostgreSQL Provider
# Switch to EF Core PostgreSQL Provider
This document explains how to switch to the **PostgreSQL** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Entity-Framework-Core-SQLite.md

@ -1,4 +1,4 @@
# Switch to EF Core SQLite Provider
# Switch to EF Core SQLite Provider
This document explains how to switch to the **SQLite** database provider for **[the application startup template](Startup-Templates/Application.md)** which comes with SQL Server provider pre-configured.

2
docs/en/Getting-Started-AspNetCore-Application.md

@ -1,4 +1,4 @@
# Getting Started ABP With AspNet Core MVC Web Application
# Getting Started ABP With AspNet Core MVC Web Application
This tutorial explains how to start ABP from scratch with minimal dependencies. You generally want to start with the **[startup template](Getting-Started-AspNetCore-MVC-Template.md)**.

2
docs/en/Getting-Started-React-Native.md

@ -1,4 +1,4 @@
# Getting Started with the React Native
# Getting Started with the React Native
````json
//[doc-params]

2
docs/en/Getting-Started-With-Startup-Templates.md

@ -1,4 +1,4 @@
# Getting Started with the Startup Templates
# Getting Started with the Startup Templates
See the following tutorials to learn how to get started with the ABP Framework using the pre-built application startup templates:

2
docs/en/Index.md

@ -1,4 +1,4 @@
# ABP Documentation
# ABP Documentation
ABP Framework is a complete **infrastructure** based on the **ASP.NET Core** to create **modern web applications** and **APIs** by following the software development **best practices** and the **latest technologies**.

2
docs/en/Integration-Tests.md

@ -1 +1 @@
This document has been [moved to here](Testing.md).
This document has been [moved to here](Testing.md).

2
docs/en/Json-Serialization.md

@ -1,3 +1,3 @@
# JSON
# JSON
TODO

50
docs/en/Local-Event-Bus.md

@ -143,7 +143,7 @@ namespace AbpDemo
{
public async Task HandleEventAsync(StockCountChangedEvent eventData)
{
//TODO: your code that does somthing on the event
//TODO: your code that does something on the event
}
}
}
@ -158,52 +158,6 @@ If you perform **database operations** and use the [repositories](Repositories.m
> The handler class must be registered to the dependency injection (DI). The sample above uses the `ITransientDependency` to accomplish it. See the [DI document](Dependency-Injection.md) for more options.
## Exception Handling
ABP provides exception handling and retries when an exception occurs.
Enable exception handling:
```csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy();
});
}
```
When an exception occurs, it will retry every three seconds up to the maximum number of retries(default is 3) and throw the original exception, you can change the number of retries and the retry interval:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.UseRetryStrategy(retryStrategyOptions =>
{
retryStrategyOptions.IntervalMillisecond = 0;
retryStrategyOptions.MaxRetryAttempts = 1;
});
});
```
### Error Handle Selector
By default all event types will be exception handling, you can use `ErrorHandleSelector` of `AbpEventBusOptions` to change it:
```csharp
PreConfigure<AbpEventBusOptions>(options =>
{
options.ErrorHandleSelector = type => type == typeof(MyExceptionHandleEventData);
});
```
`options.ErrorHandleSelector` actually a list of type predicate. You can write a lambda expression to define your filter.
### Customize Exception Handling
ABP defines the `IEventErrorHandler` interface and implemented by `LocalEventErrorHandler`, you can replace it via [dependency injection](Dependency-Injection.md)
### Transaction & Exception Behavior
When an event published, subscribed event handlers are immediately executed. So;
@ -272,4 +226,4 @@ The event types are;
Pre-build events are published when you save changes to the database;
* For EF Core, they are published on `DbContext.SaveChanges`.
* For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).
* For MongoDB, they are published when you call repository's `InsertAsync`, `UpdateAsync` or `DeleteAsync` methods (since MongoDB has not a change tracking system).

2
docs/en/MailKit.md

@ -1,4 +1,4 @@
# MailKit Integration
# MailKit Integration
[MailKit](http://www.mimekit.net/) is a cross-platform, popular open source mail client library for .net. ABP Framework provides an integration package to use the MailKit as the [email sender](Emailing.md).

101
docs/en/Migration-Guides/Abp-5_0-Angular.md

@ -0,0 +1,101 @@
# Angular UI v4.x to v5.0 Migration Guide
## Breaking Changes
### Overall
See the overall list of breaking changes:
- Bootstrap 5 implementation [#10067](https://github.com/abpframework/abp/issues/10067)
- Remove NGXS dependency & states [#9952](https://github.com/abpframework/abp/issues/9952)
- Install @angular/localize package to startup templates [#10099](https://github.com/abpframework/abp/issues/10099)
- Create new secondary entrypoints and move the related proxies to there [#10060](https://github.com/abpframework/abp/issues/10060)
- Move SettingTabsService to @abp/ng.setting-management/config package from @abp/ng.core [#10061](https://github.com/abpframework/abp/issues/10061)
- Make the @abp/ng.account dependent on @abp/ng.identity [#10059](https://github.com/abpframework/abp/issues/10059)
- Set default abp-modal size medium [#10118](https://github.com/abpframework/abp/issues/10118)
- Update all dependency versions to the latest [#9806](https://github.com/abpframework/abp/issues/9806)
- Chart.js big include with CommonJS warning [#7472](https://github.com/abpframework/abp/issues/7472)
### Angular v12
The new ABP Angular UI is based on Angular v12. We started to compile Angular UI packages with the Ivy compilation. Therefore, **new packages only work with Angular v12**. If you are still on the older version of Angular v12, you have to update to Angular v12. The update is usually very easy. See [Angular Update Guide](https://update.angular.io/?l=2&v=11.0-12.0) for further information.
### Bootstrap 5
TODO
### NGXS has been removed
We aim to make the ABP Framework free of any state-management solutions. ABP developers should be able to use the ABP Framework with any library/framework of their choice. So, we decided to remove NGXS from ABP packages.
If you'd like to use NGXS after upgrading to v5.0, you have to install the NGXS to your project. The package can be installed with the following command:
```bash
npm install @ngxs/store
# or
yarn add @ngxs/store
```
NGXS states and actions, some namespaces have been removed. See [this issue](https://github.com/abpframework/abp/issues/9952) for the details.
If you don't want to use the NGXS, you should remove all NGXS related imports, injections, etc., from your project.
### @angular/localize package
[`@angular/localize`](https://angular.io/api/localize) dependency has been removed from `@abp/ng.core` package. The package must be installed in your app. Run the following command to install:
```bash
npm install @angular/localize
# or
yarn add @angular/localize
```
> ABP Angular UI packages are not dependent on the `@angular/localize` package. However, some packages (like `@ng-bootstrap/ng-bootstrap`) depend on the package. Thus, this package needs to be installed in your project.
### Proxy endpoints
New endpoints named proxy have been created, related proxies have moved.
For example; before v5.0, `IdentityUserService` could be imported from `@abp/ng.identity`. As of v5.0, the service can be imported from `@abp/ng.identity/proxy`. See an example:
```ts
import { IdentityUserService } from '@abp/ng.identity/proxy';
@Component({})
export class YourComponent {
constructor(private identityUserService: IdentityUserService) {}
}
```
Following proxies have been affected:
- `@abp/ng.account` to `@abp/ng.account.core/proxy`
- `@abp/ng.feature-management` to `@abp/ng.feature-management/proxy`
- `@abp/ng.identity` to `@abp/ng.identity/proxy`
- `@abp/ng.permission-management` to `@abp/ng.permission-management/proxy`
- `@abp/ng.tenant-management` to `@abp/ng.tenant-management/proxy`
- **ProfileService** is deleted from `@abp/ng.core`. Instead, you can import it from `@abp/ng.identity/proxy`
### SettingTabsService
**SettingTabsService** has moved from `@abp/ng.core` to `@abp/ng.setting-management/config`.
### ChartComponent
[`ChartComponent`](../UI/Angular/Chart-Component.md) has moved from `@abp/ng.theme.shared` to `@abp/ng.components/chart.js`. To use the component, you need to import the `ChartModule` to your module as follows:
```ts
import { ChartModule } from '@abp/ng.components/chart.js';
@NgModule({
imports: [
ChartModule,
// ...
],
// ...
})
export class YourFeatureModule {}
```

51
docs/en/Migration-Guides/Abp-5_0.md

@ -0,0 +1,51 @@
# ABP Framework v4.x to v5.0 Migration Guide
## IdentityUser
`IsActive <bool>` property is added to the `IdentityUser`. This flag will be checked during the authentication of the users. See the related [PR](https://github.com/abpframework/abp/pull/10185).
**After the migration, set this property to `true` for the existing users: `UPDATE AbpUsers SET IsActive=1`**
For EFCore you can set `defaultValue` to `true` in the migration class:
(This will add the column with `true` value for the existing records.)
```cs
public partial class AddIsActiveToIdentityUser : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsActive",
table: "AbpUsers",
type: "bit",
nullable: false,
defaultValue: true); // Default is false.
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsActive",
table: "AbpUsers");
}
}
```
For document base databases like MongoDB, you need to manually update the `IsActive` field for the existing user records.
## MongoDB
ABP Framework will serialize the datetime based on [AbpClockOptions](https://docs.abp.io/en/abp/latest/Timing#clock-options) starting from ABP v5.0. It was saving `DateTime` values as UTC in MongoDB. Check out [MongoDB Datetime Serialization Options](https://mongodb.github.io/mongo-csharp-driver/2.13/reference/bson/mapping/#datetime-serialization-options).
To revert back this feature, set `UseAbpClockHandleDateTime = false` in `AbpMongoDbOptions`:
```cs
services.Configure<AbpMongoDbOptions>(x => x.UseAbpClockHandleDateTime = false);
```
## IApiScopeRepository
`GetByNameAsync` method renamed as `FindByNameAsync`.
## Angular UI
See the [Angular UI 5.0 Migration Guide](Abp-5_0-Angular.md).

10
docs/en/Migration-Guides/Index.md

@ -1,7 +1,7 @@
# ABP Framework Migration Guides
* [4.2 to 4.3](Abp-4_3.md)
* [4.x to 4.2](Abp-4_2.md)
* [3.3.x to 4.0](Abp-4_0.md)
* [2.9.x to 3.0](../UI/Angular/Migration-Guide-v3.md)
- [4.x to 5.0](Abp-5_0.md)
- [4.2 to 4.3](Abp-4_3.md)
- [4.x to 4.2](Abp-4_2.md)
- [3.3.x to 4.0](Abp-4_0.md)
- [2.9.x to 3.0](../UI/Angular/Migration-Guide-v3.md)

2
docs/en/Module-Development-Basics.md

@ -1,4 +1,4 @@
# Modularity
# Modularity
## Introduction

3
docs/en/Module-Entity-Extensions.md

@ -491,3 +491,6 @@ Here, a few things you can do:
* You can override a domain or application service to perform custom logics with your new property.
* You can low level control how to add/render a field in the data table on the UI.
## See Also
* [Angular UI Extensions](UI/Angular/Extensions-Overall.md)

5
docs/en/Modules/Cms-Kit/Index.md

@ -20,11 +20,16 @@ All features are individually usable. If you disable a feature, it completely di
## How to Install
> This module is depends on [BlobStoring](../../Blob-Storing.md) module, please install `BlobStoring` module first and add a provider. For more information, check the [documentation](../../Blob-Storing.md).
[ABP CLI](../../CLI.md) allows installing a module to a solution using the `add-module` command. You can install the CMS Kit module in a command-line terminal with the following command:
```bash
abp add-module Volo.CmsKit
```
> By default, Cms-Kit is disabled by `GlobalFeature`. Because of that the initial migration will be empty. So you can skip the migration by adding `--skip-db-migrations` to command when installing if you are using Entity Framework Core. After enabling Cms-Kit global feture, please add new migration.
After the installation process, open the `GlobalFeatureConfigurator` class in the `Domain.Shared` project of your solution and place the following code into the `Configure` method to enable all the features in the CMS Kit module.
```csharp

2
docs/en/Modules/Setting-Management.md

@ -278,7 +278,7 @@ Open the `app.component.ts` and modify the file as shown below:
```js
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { SettingTabsService } from '@abp/ng.setting-management/config'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)

2
docs/en/Object-Extensions.md

@ -1,4 +1,4 @@
# Object Extensions
# Object Extensions
ABP Framework provides an **object extension system** to allow you to **add extra properties** to an existing object **without modifying** the related class. This allows to extend functionalities implemented by a depended [application module](Modules/Index.md), especially when you want to [extend entities](Customizing-Application-Modules-Extending-Entities.md) and [DTOs](Customizing-Application-Modules-Overriding-Services.md) defined by the module.

2
docs/en/Options.md

@ -1,4 +1,4 @@
# Options
# Options
Microsoft has introduced [the options pattern](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options) that is used to configure a group of settings used by the framework services. This pattern is implemented by the [Microsoft.Extensions.Options](https://www.nuget.org/packages/Microsoft.Extensions.Options) NuGet package, so it is usable by any type of applications in addition to ASP.NET Core based applications.

2
docs/en/RabbitMq.md

@ -1,3 +1,3 @@
# RabbitMQ
# RabbitMQ
TODO!

2
docs/en/Road-Map.md

@ -1,4 +1,4 @@
# ABP Framework Road Map
# ABP Framework Road Map
This document provides a road map, release schedule and planned features for the ABP Framework.

2
docs/en/SMS-Sending.md

@ -1,4 +1,4 @@
# SMS Sending
# SMS Sending
The ABP Framework provides an abstraction to sending SMS. Having such an abstraction has some benefits;

2
docs/en/Settings.md

@ -1,4 +1,4 @@
# Settings
# Settings
[Configuration system](Configuration.md) is a good way to configure the application on startup. In addition to the configurations, ABP provides another way to set and get some application settings.

54
docs/en/SignalR-Integration.md

@ -52,15 +52,15 @@ Client side installation depends on your UI framework / client type.
Run the following command in the root folder of your web project:
````bash
```bash
yarn add @abp/signalr
````
```
> This requires to [install yarn](https://yarnpkg.com/) if you haven't install before.
This will add the `@abp/signalr` to the dependencies in the `package.json` of your project:
````json
```json
{
...
"dependencies": {
@ -68,25 +68,25 @@ This will add the `@abp/signalr` to the dependencies in the `package.json` of yo
"@abp/signalr": "~2.7.0"
}
}
````
```
Run the following [ABP CLI](CLI.md) command in the root folder of your web project:
````bash
```bash
abp install-libs
````
```
This will copy the SignalR JavaScript files into your project:
![signal-js-file](images/signal-js-file.png)
Finally, add the following code to your page/view to include the `signalr.js` file
Finally, add the following code to your page/view to include the `signalr.js` file
````xml
```xml
@section scripts {
<abp-script type="typeof(SignalRBrowserScriptContributor)" />
}
````
```
It requires to add `@using Volo.Abp.AspNetCore.Mvc.UI.Packages.SignalR` to your page/view.
@ -108,27 +108,27 @@ ABP automatically registers all the hubs to the [dependency injection](Dependenc
Example:
````csharp
```csharp
public class MessagingHub : Hub
{
//...
}
````
```
The hub route will be `/signalr-hubs/messaging` for the `MessagingHub`:
* Adding a standard `/signalr-hubs/` prefix
* Continue with the **camel case** hub name, without the `Hub` suffix.
- Adding a standard `/signalr-hubs/` prefix
- Continue with the **kebab-case** hub name, without the `Hub` suffix.
If you want to specify the route, you can use the `HubRoute` attribute:
````csharp
```csharp
[HubRoute("/my-messaging-hub")]
public class MessagingHub : Hub
{
//...
}
````
```
### AbpHub Base Classes
@ -136,7 +136,7 @@ Instead of the standard `Hub` and `Hub<T>` classes, you can inherit from the `Ab
Example:
````csharp
```csharp
public class MessagingHub : AbpHub
{
public async Task SendMessage(string targetUserName, string message)
@ -145,7 +145,7 @@ public class MessagingHub : AbpHub
var txt = L["MyText"]; //Localization
}
}
````
```
> While you could inject the same properties into your hub constructor, this way simplifies your hub class.
@ -153,9 +153,9 @@ public class MessagingHub : AbpHub
ABP automatically registers all the hubs to the [dependency injection](Dependency-Injection.md) as a **transient service**. If you want to **disable auto dependency injection** registration for your hub class, just add a `DisableConventionalRegistration` attribute. You can still register your hub class to dependency injection in the `ConfigureServices` method of your module if you like:
````csharp
```csharp
context.Services.AddTransient<MessagingHub>();
````
```
When **you or ABP** register the class to the dependency injection, it is automatically mapped to the endpoint route configuration just as described in the previous sections. You can use `DisableAutoHubMap` attribute if you want to manually map your hub class.
@ -163,7 +163,7 @@ For manual mapping, you have two options:
1. Use the `AbpSignalROptions` to add your map configuration (in the `ConfigureServices` method of your [module](Module-Development-Basics.md)), so ABP still performs the endpoint mapping for your hub:
````csharp
```csharp
Configure<AbpSignalROptions>(options =>
{
options.Hubs.Add(
@ -178,13 +178,13 @@ Configure<AbpSignalROptions>(options =>
)
);
});
````
```
This is a good way to provide additional SignalR options.
If you don't want to disable auto hub map, but still want to perform additional SignalR configuration, use the `options.Hubs.AddOrUpdate(...)` method:
````csharp
```csharp
Configure<AbpSignalROptions>(options =>
{
options.Hubs.AddOrUpdate(
@ -200,13 +200,13 @@ Configure<AbpSignalROptions>(options =>
}
);
});
````
```
This is the way you can modify the options of a hub class defined in a depended module (where you don't have the source code access).
2. Change `app.UseConfiguredEndpoints` in the `OnApplicationInitialization` method of your [module](Module-Development-Basics.md) as shown below (added a lambda method as the parameter).
````csharp
```csharp
app.UseConfiguredEndpoints(endpoints =>
{
endpoints.MapHub<MessagingHub>("/my-messaging-hub", options =>
@ -214,7 +214,7 @@ app.UseConfiguredEndpoints(endpoints =>
options.LongPolling.PollTimeout = TimeSpan.FromSeconds(30);
});
});
````
```
### UserIdProvider
@ -234,5 +234,5 @@ Refer to the Microsoft's documentation to [host and scale](https://docs.microsof
## See Also
* [Microsoft SignalR documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction)
* [Real-Time Messaging In A Distributed Architecture Using ABP, SingalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ)
- [Microsoft SignalR documentation](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction)
- [Real-Time Messaging In A Distributed Architecture Using ABP, SingalR & RabbitMQ](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ)

2
docs/en/Specifications.md

@ -1,4 +1,4 @@
# Specifications
# Specifications
Specification Pattern is used to define **named, reusable, combinable and testable filters** for entities and other business objects.

2
docs/en/Startup-Templates/Application.md

@ -1,4 +1,4 @@
# Application Startup Template
# Application Startup Template
## Introduction

2
docs/en/Startup-Templates/Index.md

@ -1,4 +1,4 @@
# Startup Templates
# Startup Templates
While you can start with an empty project and add needed packages manually, startup templates make easy and comfortable to start a new solution with the ABP framework. Click the name from the list below to see the documentation of the related startup template:

2
docs/en/Startup-Templates/Module.md

@ -1,4 +1,4 @@
# Module Startup Template
# Module Startup Template
This template can be used to create a **reusable [application module](../Modules/Index.md)** based on the [module development best practices & conventions](../Best-Practices/Index.md). It is also suitable for creating **microservices** (with or without UI).

6
docs/en/Testing.md

@ -1,4 +1,4 @@
# Automated Testing
# Automated Testing
## Introduction
@ -647,7 +647,7 @@ namespace MyProject.Issues
}
````
It's that simple. This test method tests everything, including the application service, EF Core mapping, object to object mapping and the repository implementation. In this way, you can fully test the Application Later and the Domain Layer of your solution.
It's that simple. This test method tests everything, including the application service, EF Core mapping, object to object mapping and the repository implementation. In this way, you can fully test the Application Layer and the Domain Layer of your solution.
## UI Tests
@ -670,4 +670,4 @@ See the following documents to learn Non Visual UI Testing;
Visual Tests are used to interact with the application UI just like a real user does. It fully tests the application, including the visual appearance of the pages and components.
Visual UI Testing is out of the scope for the ABP Framework. There are a lot of tooling in the industry (like [Selenium](https://www.selenium.dev/)) that you can use to test your application's UI.
Visual UI Testing is out of the scope for the ABP Framework. There are a lot of tooling in the industry (like [Selenium](https://www.selenium.dev/)) that you can use to test your application's UI.

2
docs/en/Timing.md

@ -1,4 +1,4 @@
# Timing
# Timing
Working with times & [time zones](https://en.wikipedia.org/wiki/Time_zone) is always tricky, especially if you need to build a **global system** that is used by users in **different time zones**.

249
docs/en/UI/Angular/Chart-Component.md

@ -0,0 +1,249 @@
# Chart Component
ABP Chart component exposed by `@abp/ng.components/chart.js` is based on [`charts.js`](https://www.chartjs.org/) v3+. You don't need to install the `chart.js` package. Since the `@abp/ng.components` is dependent on the `chart.js`, the package is already installed in your project.
> Chart component loads `chart.js` script lazy. So it does not increase the bundle size.
## How to Use
First of all, need to import the `ChartModule` to your feature module as follows:
```ts
// your-feature.module.ts
import { ChartModule } from '@abp/ng.components/chart.js';
import { ChartDemoComponent } from './chart-demo.component';
@NgModule({
imports: [
ChartModule,
// ...
],
declarations: [ChartDemoComponent],
// ...
})
export class YourFeatureModule {}
```
Then, `abp-chart` component can be used. See an example:
```ts
// chart-demo.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-chart-demo',
template: ` <abp-chart type="pie" [data]="data"></abp-chart> `,
})
export class ChartDemoComponent {
data = {
labels: ['Data 1', 'Data 2', 'Data 3'],
datasets: [
{
label: 'Dataset 1',
data: [40, 15, 45],
backgroundColor: ['#ff7675', '#fdcb6e', '#0984e3'],
},
],
};
}
```
> **Important Note**: Changing the chart data without creating a new data instance does not trigger change detection. In order to chart to redraw itself, a new data object needs to be created.
See the result:
![pie-chart](./images/pie-chart.png)
## Examples
### Doughnut
```ts
import { Component } from '@angular/core';
@Component({
selector: 'app-chart-demo',
template: `
<abp-chart
type="doughnut"
[data]="data"
[options]="options"
width="400px"
height="400px"
></abp-chart>
`,
})
export class ChartDemoComponent {
data = {
labels: ['Data 1', 'Data 2', 'Data 3'],
datasets: [
{
label: 'Dataset 1',
data: [40, 15, 45],
backgroundColor: ['#a0e6c3', '#f0ea4c', '#5b9dc3'],
},
],
};
options = {
plugins: {
title: {
display: true,
text: 'Doughnut Chart',
fontSize: 16,
},
legend: {
position: 'bottom',
},
},
};
}
```
Result:
![Doughnut Chart](./images/doughnut-chart.png)
### Bar
```ts
import { Component } from '@angular/core';
@Component({
selector: 'app-chart-demo',
template: `
<abp-chart
type="bar"
[data]="data"
width="400px"
height="400px"
></abp-chart>
`,
})
export class ChartDemoComponent {
data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'First dataset',
backgroundColor: '#42A5F5',
data: [65, 59, 80, 81, 56, 55, 40],
},
{
label: 'Second dataset',
backgroundColor: '#FFA726',
data: [28, 48, 40, 19, 86, 27, 90],
},
],
};
}
```
Result:
![Bar Chart](./images/bar-chart.png)
### Radar
```ts
import { Component } from '@angular/core';
@Component({
selector: 'app-chart-demo',
template: `
<abp-chart
type="radar"
[data]="data"
width="400px"
height="400px"
></abp-chart>
<button class="btn btn-primary-outline mt-4" (click)="addDataset()">
Add dataset
</button>
`,
})
export class ChartDemoComponent {
data = {
labels: [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
],
datasets: [
{
label: 'Dataset 1',
backgroundColor: 'rgba(179,181,198,0.2)',
borderColor: 'rgba(179,181,198,1)',
data: [65, 59, 90, 81, 56, 55, 40, 35, 82, 51, 62, 95],
},
{
label: 'Dataset 2',
backgroundColor: 'rgba(255,99,132,0.2)',
borderColor: 'rgba(255,99,132,1)',
data: [28, 48, 40, 58, 96, 27, 100, 44, 85, 77, 71, 39],
},
],
};
addDataset() {
this.data = {
...this.data,
datasets: [
...this.data.datasets,
{
label: 'Dataset 3',
backgroundColor: 'rgba(54,162,235,0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
data: [90, 95, 98, 91, 99, 96, 89, 95, 98, 93, 92, 90],
},
],
};
}
}
```
Result:
![Bar Chart](./images/radar-chart.gif)
See the [`chart.js` samples](https://www.chartjs.org/docs/latest/samples) for more examples.
## API
### `abp-chart`
#### Properties
| Name | Description | Type | Default |
| --------------- | ---------------------------------------------------------------- | ----------------------- | ------- |
| `[type]` | Type of the chart. | `string` | null |
| `[data]` | Chart data to display | `any` | null |
| `[options]` | Chart options to customize | `any` | null |
| `[plugins]` | Chart plugins to customize behaviour | `any` | null |
| `[width]` | Witdh of the chart | `string` | null |
| `[height]` | Height of the chart | `string` | null |
| `[responsive]` | Whether the chart is responsive | `boolean` | true |
| `(dataSelect)` | A callback that executes when an element on the chart is clicked | `EventEmitter<any>` | - |
| `(initialized)` | A callback that executes when the chart is initialized | `EventEmitter<boolean>` | - |
#### Methods
| Name | Description | Parameters |
| ---------------- | ------------------------------------------------------------------- | ---------- |
| `refresh` | Redraws the chart | - |
| `reinit` | Destroys the chart then creates it again | - |
| `getBase64Image` | Returns a base 64 encoded string of the chart in it's current state | - |
| `generateLegend` | Returns an HTML string of a legend for the chart | - |
| `getCanvas` | Returns the canvas HTML element | - |

4
docs/en/UI/Angular/Config-State-Service.md

@ -81,7 +81,7 @@ You can use the `getFeature` or `getFeature$` method of `ConfigStateService` to
```js
// this.config is instance of ConfigStateService
const enableLdapLogin = this.configStateService.getFeature("Account.EnableLdapLogin");
const enableLdapLogin = this.config.getFeature("Account.EnableLdapLogin");
// or
this.config.getFeature$("Account.EnableLdapLogin").subscribe(enableLdapLogin => {
@ -98,7 +98,7 @@ You can use the `getSetting` or `getSetting$` method of `ConfigStateService` to
```js
// this.config is instance of ConfigStateService
const twoFactorBehaviour = this.configStateService.getSetting("Abp.Identity.TwoFactor.Behaviour");
const twoFactorBehaviour = this.config.getSetting("Abp.Identity.TwoFactor.Behaviour");
// or
this.config.getSetting$("Abp.Identity.TwoFactor.Behaviour").subscribe(twoFactorBehaviour => {

12
docs/en/UI/Angular/Content-Strategy.md

@ -11,13 +11,15 @@
constructor(
public content: string,
protected domStrategy?: DomStrategy,
protected contentSecurityStrategy?: ContentSecurityStrategy
protected contentSecurityStrategy?: ContentSecurityStrategy,
protected options?: ElementOptions = {},
)
```
- `content` is set to `<script>` and `<style>` elements as `textContent` property.
- `domStrategy` is the `DomStrategy` that will be used when inserting the created element. (_default: AppendToHead_)
- `contentSecurityStrategy` is the `ContentSecurityStrategy` that will be used on the created element before inserting it. (_default: None_)
- `options` can be used to pass any option to the element that will be created. e.g: `{ id: "some-id" }` (_default: empty object_)
Please refer to [DomStrategy](./Dom-Strategy.md) and [ContentSecurityStrategy](./Content-Security-Strategy.md) documentation for their usage.
@ -57,7 +59,7 @@ Predefined content strategies are accessible via `CONTENT_STRATEGY` constant.
### AppendScriptToBody
```js
CONTENT_STRATEGY.AppendScriptToBody(content: string)
CONTENT_STRATEGY.AppendScriptToBody(content: string, options?: ElementOptions<HTMLScriptElement>)
```
Creates a `<script>` element with the given content and places it at the **end** of `<body>` tag in the document.
@ -66,7 +68,7 @@ Creates a `<script>` element with the given content and places it at the **end**
### AppendScriptToHead
```js
CONTENT_STRATEGY.AppendScriptToHead(content: string)
CONTENT_STRATEGY.AppendScriptToHead(content: string, options?: ElementOptions<HTMLScriptElement>)
```
Creates a `<script>` element with the given content and places it at the **end** of `<head>` tag in the document.
@ -75,7 +77,7 @@ Creates a `<script>` element with the given content and places it at the **end**
### AppendStyleToHead
```js
CONTENT_STRATEGY.AppendStyleToHead(content: string)
CONTENT_STRATEGY.AppendStyleToHead(content: string, options?: ElementOptions<HTMLStyleElement>)
```
Creates a `<style>` element with the given content and places it at the **end** of `<head>` tag in the document.
@ -84,7 +86,7 @@ Creates a `<style>` element with the given content and places it at the **end**
### PrependStyleToHead
```js
CONTENT_STRATEGY.PrependStyleToHead(content: string)
CONTENT_STRATEGY.PrependStyleToHead(content: string, options?: ElementOptions<HTMLStyleElement>)
```
Creates a `<style>` element with the given content and places it at the **beginning** of `<head>` tag in the document.

10
docs/en/UI/Angular/Extensions-Overall.md

@ -0,0 +1,10 @@
## Angular UI Extensions
Angular UI extensions system allows you to add a new action to the actions menu, a new column to the data table, a new action to the toolbar of a page, and add a new field to the create and/or edit forms.
See the documents below for the details:
* [Entity Action Extensions](Entity-Action-Extensions.md)
* [Data Table Column (or Entity Prop) Extensions](Data-Table-Column-Extensions.md)
* [Page Toolbar Extension](Page-Toolbar-Extensions.md)
* [Dynamic Form (or Form Prop) Extensions](Dynamic-Form-Extensions.md)

46
docs/en/UI/Angular/Permission-Management.md

@ -4,8 +4,6 @@ A permission is a simple policy that is granted or prohibited for a particular u
You can get permission of authenticated user using `getGrantedPolicy` or `getGrantedPolicy$` method of `PermissionService`.
> ConfigState's getGrantedPolicy selector and ConfigStateService's getGrantedPolicy method deprecated. Use permission service's `getGrantedPolicy$` or `getGrantedPolicy`methods instead
You can get permission as boolean value:
```js
@ -77,4 +75,46 @@ const routes: Routes = [
];
```
Granted Policies are stored in the `auth` property of `ConfigState`.
## Customization
In some cases, a custom permission management may be needed. All you need to do is to replace the service with your own. Here is how to achieve this:
- First, create a service of your own. Let's call it `CustomPermissionService` and extend `PermissionService` from `@abp/ng.core` as follows:
```js
import { ConfigStateService, PermissionService } from '@abp/ng.core';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class CustomPermissionService extends PermissionService {
constructor(configStateService: ConfigStateService) {
super(configStateService);
}
// This is an example to show how to override the methods
getGrantedPolicy$(key: string) {
return super.getGrantedPolicy$(key);
}
}
```
- Then, in `app.module.ts`, provide this service as follows:
```js
@NgModule({
// ...
providers: [
// ...
{
provide: PermissionService,
useExisting: CustomPermissionService,
},
],
// ...
})
export class AppModule {}
```
That's it. Now, when a directive/guard asks for `PermissionService` from angular, it will inject your service.

BIN
docs/en/UI/Angular/images/bar-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/en/UI/Angular/images/doughnut-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/en/UI/Angular/images/pie-chart.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
docs/en/UI/Angular/images/radar-chart.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save