Browse Source

Merge branch 'dev' into maliming/IdentityServer-v4

pull/4578/head
maliming 6 years ago
parent
commit
e6fafdf08a
  1. 2
      common.props
  2. 72
      docs/en/Getting-Started-React-Native.md
  3. 145
      docs/en/Getting-Started.md
  4. 2
      docs/en/How-To/Azure-Active-Directory-Authentication-MVC.md
  5. 2
      docs/en/How-To/Customize-Login-Page-MVC.md
  6. 2
      docs/en/How-To/Customize-SignIn-Manager.md
  7. 2
      docs/en/Samples/Index.md
  8. 1
      docs/en/Tutorials/Part-1.md
  9. 51
      docs/en/UI/Angular/Custom-Setting-Page.md
  10. 21
      docs/en/UI/Angular/Localization.md
  11. 104
      docs/en/UI/Angular/Migration-Guide-v3.md
  12. 8
      docs/en/UI/Angular/Permission-Management.md
  13. 6
      docs/en/UI/Angular/Service-Proxies.md
  14. BIN
      docs/en/UI/Angular/images/custom-settings.png
  15. BIN
      docs/en/UI/Angular/images/generated-files-via-generate-proxy.png
  16. 9
      docs/en/docs-nav.json
  17. 177
      docs/zh-Hans/Blog-Posts/2020-07-01 v3_0_Release/Post.md
  18. BIN
      docs/zh-Hans/Blog-Posts/2020-07-01 v3_0_Release/file-management-ui.png
  19. 2
      docs/zh-Hans/How-To/Azure-Active-Directory-Authentication-MVC.md
  20. 2
      docs/zh-Hans/How-To/Customize-Login-Page-MVC.md
  21. 2
      docs/zh-Hans/How-To/Customize-SignIn-Manager.md
  22. 2
      docs/zh-Hans/Samples/Index.md
  23. 5
      docs/zh-Hans/Tutorials/Part-1.md
  24. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml
  25. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml
  26. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml
  27. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHooks.cs
  28. 19
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs
  29. 20
      framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs
  30. 5
      framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs
  31. 38
      framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs
  32. 7
      framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs
  33. 76
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs
  34. 10
      framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs
  35. 7
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs
  36. 2
      npm/lerna.json
  37. 2
      npm/ng-packs/apps/dev-app/src/app/app.module.ts
  38. 2
      npm/ng-packs/lerna.version.json
  39. 4
      npm/ng-packs/packages/account/package.json
  40. 2
      npm/ng-packs/packages/core/package.json
  41. 8
      npm/ng-packs/packages/core/src/lib/core.module.ts
  42. 6
      npm/ng-packs/packages/core/src/lib/services/auth.service.ts
  43. 31
      npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts
  44. 10
      npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts
  45. 4
      npm/ng-packs/packages/feature-management/package.json
  46. 6
      npm/ng-packs/packages/identity/package.json
  47. 4
      npm/ng-packs/packages/permission-management/package.json
  48. 4
      npm/ng-packs/packages/setting-management/package.json
  49. 6
      npm/ng-packs/packages/tenant-management/package.json
  50. 4
      npm/ng-packs/packages/theme-basic/package.json
  51. 4
      npm/ng-packs/packages/theme-shared/package.json
  52. 4
      npm/packs/anchor-js/package.json
  53. 4
      npm/packs/aspnetcore.mvc.ui.theme.basic/package.json
  54. 30
      npm/packs/aspnetcore.mvc.ui.theme.shared/package.json
  55. 2
      npm/packs/aspnetcore.mvc.ui/package.json
  56. 10
      npm/packs/blogging/package.json
  57. 2
      npm/packs/bootstrap-datepicker/package.json
  58. 4
      npm/packs/bootstrap/package.json
  59. 2
      npm/packs/chart.js/package.json
  60. 4
      npm/packs/clipboard/package.json
  61. 4
      npm/packs/codemirror/package.json
  62. 2
      npm/packs/core/package.json
  63. 4
      npm/packs/datatables.net-bs4/package.json
  64. 4
      npm/packs/datatables.net/package.json
  65. 12
      npm/packs/docs/package.json
  66. 2
      npm/packs/flag-icon-css/package.json
  67. 4
      npm/packs/font-awesome/package.json
  68. 4
      npm/packs/highlight.js/package.json
  69. 4
      npm/packs/jquery-form/package.json
  70. 4
      npm/packs/jquery-validation-unobtrusive/package.json
  71. 4
      npm/packs/jquery-validation/package.json
  72. 4
      npm/packs/jquery/package.json
  73. 4
      npm/packs/jstree/package.json
  74. 4
      npm/packs/lodash/package.json
  75. 2
      npm/packs/luxon/package.json
  76. 4
      npm/packs/malihu-custom-scrollbar-plugin/package.json
  77. 4
      npm/packs/markdown-it/package.json
  78. 4
      npm/packs/owl.carousel/package.json
  79. 4
      npm/packs/popper.js/package.json
  80. 6
      npm/packs/prismjs/package.json
  81. 4
      npm/packs/select2/package.json
  82. 4
      npm/packs/signalr/package.json
  83. 4
      npm/packs/sweetalert/package.json
  84. 4
      npm/packs/timeago/package.json
  85. 4
      npm/packs/toastr/package.json
  86. 10
      npm/packs/tui-editor/package.json
  87. 4
      npm/packs/uppy/package.json
  88. 2
      npm/packs/utils/package.json
  89. 6
      npm/packs/virtual-file-explorer/package.json
  90. 3
      nupkg/common.ps1
  91. 13
      samples/MicroserviceDemo/DeployToKubernetes.sh
  92. 208
      samples/MicroserviceDemo/MicroserviceDemo.sln
  93. 4
      samples/MicroserviceDemo/README.md
  94. 2
      samples/MicroserviceDemo/_run/01_AuthServer.ps1
  95. 2
      samples/MicroserviceDemo/_run/02_IdentityService.ps1
  96. 2
      samples/MicroserviceDemo/_run/03_BloggingService.ps1
  97. 2
      samples/MicroserviceDemo/_run/04_ProductService.ps1
  98. 2
      samples/MicroserviceDemo/_run/05_InternalGateway.ps1
  99. 2
      samples/MicroserviceDemo/_run/06_BackendAdminAppGateway.ps1
  100. 2
      samples/MicroserviceDemo/_run/07_PublicWebSiteGateway.ps1

2
common.props

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

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

@ -0,0 +1,72 @@
# Getting Started with the React Native
ABP platform provide basic [React Native](https://reactnative.dev/) startup template to develop mobile applications **integrated to your ABP based backends**.
When you **create a new application** as described in the [getting started document](Getting-Started.md), the solution includes the React Native application in the `react-native` folder as default.
## Configure Your Local IP Address
A React Native application running on an Android emulator or a physical phone **can not connect to the backend** on `localhost`. To fix this problem, it is necessary to run the backend application on your **local IP address**.
{{ if Tiered == "No"}}
![React Native host project local IP entry](images/rn-host-local-ip.png)
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `SelfUrl` and `Authority` properties with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ else if Tiered == "Yes" }}
![React Native tiered project local IP entry](images/rn-tiered-local-ip.png)
* Open the `appsettings.json` in the `.IdentityServer` folder. Replace the `localhost` address on the `SelfUrl` property with your local IP address.
* Open the `launchSettings.json` in the `.IdentityServer/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `Authority` property with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ end }}
## Run the Server Application
Run the backend application as described in the [getting started document](Getting-Started.md).
> React Native application does not trust the auto-generated .NET HTTPS certificate. You should use **HTTP** during the development.
Go to the `react-native` folder, open a command line terminal, type the `yarn` command (we suggest to the [yarn](https://yarnpkg.com/) package manager while `npm install` will also work):
```bash
yarn
```
* Open the `Environment.js` in the `react-native` folder and replace the `localhost` address on the `apiUrl` and `issuer` properties with your local IP address as shown below:
![react native environment local IP](images/rn-environment-local-ip.png)
{{ if Tiered == "Yes" }}
> Make sure that `issuer` matches the running address of the `.IdentityServer` project, `apiUrl` matches the running address of the `.HttpApi.Host` or `.Web` project.
{{else}}
> Make sure that `issuer` and `apiUrl` matches the running address of the `.HttpApi.Host` or `.Web` project.
{{ end }}
Once all node modules are loaded, execute `yarn start` (or `npm start`) command:
```bash
yarn start
```
Wait Expo CLI to start. Expo CLI opens the management interface on the `http://localhost:19002/` address.
![expo-interface](images/rn-expo-interface.png)
In the above management interface, you can start the application with an Android emulator, an iOS simulator or a physical phone by the scan the QR code with the [Expo Client](https://expo.io/tools#client).
> See the [Android Studio Emulator](https://docs.expo.io/workflow/android-simulator/), [iOS Simulator](https://docs.expo.io/workflow/ios-simulator/) documents on expo.io.
![React Native login screen on iPhone 11](images/rn-login-iphone.png)
Enter **admin** as the username and **1q2w3E*** as the password to login to the application.
The application is up and running. You can continue to develop your application based on this startup template.

145
docs/en/Getting-Started.md

@ -1,4 +1,4 @@
# Getting started
# Getting Started
````json
//[doc-params]
@ -9,36 +9,36 @@
}
````
This tutorial explains how to create a new {{if UI == "MVC"}} ASP.NET Core MVC web {{else if UI == "NG"}} Angular {{end}} application using the startup template, configure and run it.
This tutorial explains how to create a new {{if UI == "MVC"}} ASP.NET Core MVC (Razor Pages) web {{else if UI == "NG"}} Angular {{end}} application using the startup template.
## Setup your development environment
## Setup Your Development Environment
First things first! Let's setup your development environment before creating the first project.
### Pre-requirements
### Pre-Requirements
The following tools should be installed on your development machine:
* [Visual Studio 2019 (v16.4+)](https://visualstudio.microsoft.com/vs/) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
* [.NET Core 3.0+](https://www.microsoft.com/net/download/dotnet-core/)
* [Visual Studio 2019 (v16.4+)](https://visualstudio.microsoft.com/vs/) for Windows / [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).*
* [.NET Core 3.1+](https://www.microsoft.com/net/download/dotnet-core/)
* [Node v12+](https://nodejs.org)
* [Yarn v1.19+](https://classic.yarnpkg.com/)
{{ if Tiered == "Yes" }}
* [Redis](https://redis.io/): The applications use Redis as as [distributed cache](../Caching.md). So, you need to have Redis installed & running.
* [Redis](https://redis.io/) (the startup solution uses the Redis as the [distributed cache](Caching.md)).
{{ end }}
> You can use another editor instead of Visual Studio as long as it supports .NET Core and ASP.NET Core.
> *You can use another editor instead of Visual Studio as long as it supports .NET Core and ASP.NET Core.
### Install the ABP CLI
[ABP CLI](./CLI.md) is a command line interface that is used to authenticate and automate some tasks for ABP based applications.
[ABP CLI](./CLI.md) is a command line interface that is used to automate some common tasks for ABP based applications.
> ABP CLI is a free & open source tool for [the ABP framework](https://abp.io/).
> ABP CLI is a free & open source tool for the ABP framework.
First, you need to install the ABP CLI using the following command:
@ -52,27 +52,25 @@ If you've already installed, you can update it using the following command:
dotnet tool update -g Volo.Abp.Cli
````
## Create a new project
## Create a New Project
> This document assumes that you prefer to use **{{ UI_Value }}** as the UI framework and **{{ DB_Value }}** as the database provider. For other options, please change the preference on top of this document.
### Using the ABP CLI to create a new project
### Using the ABP CLI to Create a New Project
Use the `new` command of the ABP CLI to create a new project:
````shell
abp new Acme.BookStore -t app{{if UI == "NG"}} -u angular {{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes" && UI != "NG"}} --tiered {{else if Tiered == "Yes" && UI == "NG"}}--separate-identity-server{{end}}
abp new Acme.BookStore{{if UI == "NG"}} -u angular {{end}}{{if DB == "Mongo"}} -d mongodb{{end}}{{if Tiered == "Yes" && UI != "NG"}} --tiered {{else if Tiered == "Yes" && UI == "NG"}}--separate-identity-server{{end}}
````
* `-t` argument specifies the [startup template](Startup-Templates/Application.md) name. `app` is the startup template that contains the essential [ABP Modules](Modules/Index.md) pre-installed and configured for you.
{{ if UI == "NG" }}
* `-u` argument specifies the UI framework, `angular` in this case.
{{ if Tiered == "Yes" }}
* `--separate-identity-server` argument is used to separate the identity server application from the API host application. If not specified, you will have a single endpoint.
* `--separate-identity-server` argument is used to separate the identity server application from the API host application. If not specified, you will have a single endpoint on the server.
{{ end }}
@ -92,11 +90,13 @@ abp new Acme.BookStore -t app{{if UI == "NG"}} -u angular {{end}}{{if DB == "Mon
> You can use different level of namespaces; e.g. BookStore, Acme.BookStore or Acme.Retail.BookStore.
#### ABP CLI commands & options
#### ABP CLI Commands & Options
[ABP CLI document](./CLI.md) covers all of the available commands and options for the ABP CLI. This document uses the [application startup template](Startup-Templates/Application.md) to create a new web application. See the [ABP Startup Templates](Startup-Templates/Index.md) document for other templates.
[ABP CLI document](./CLI.md) covers all of the available commands and options for the ABP CLI. See the [ABP Startup Templates](Startup-Templates/Index.md) document for other templates.
> Alternatively, you can select the "Direct Download" tab from the [ABP Framework web site](https://abp.io/get-started) to create a new solution.
## The solution structure
## The Solution Structure
{{ if UI == "MVC" }}
@ -135,7 +135,7 @@ Open the `.sln` (Visual Studio solution) file under the `aspnet-core` folder:
>
> Your solution may have slightly different structure based on your **UI**, **database** and other preferences.
The solution has a layered structure (based on [Domain Driven Design](./Domain-Driven-Design.md)) and also contains unit & integration test projects.
The solution has a layered structure (based on the [Domain Driven Design](Domain-Driven-Design.md)) and also contains unit & integration test projects.
{{ if DB == "EF" }}
@ -149,9 +149,9 @@ Integration tests projects are properly configured to work with in-memory **Mong
> See the [application template document](Startup-Templates/Application.md) to understand the solution structure in details.
## Create the database
## Create the Database
### Database connection string
### Connection String
Check the **connection string** in the `appsettings.json` file under the {{if UI == "MVC"}}{{if Tiered == "Yes"}}`.IdentityServer` and `.HttpApi.Host` projects{{else}}`.Web` project{{end}}{{else if UI == "NG" }}`.HttpApi.Host` project{{end}}:
@ -163,13 +163,13 @@ Check the **connection string** in the `appsettings.json` file under the {{if UI
}
````
The solution is configured to use **Entity Framework Core** with **MS SQL Server**. EF Core supports [various](https://docs.microsoft.com/en-us/ef/core/providers/) database providers, so you can use any supported DBMS. See [the Entity Framework integration document](https://docs.abp.io/en/abp/latest/Entity-Framework-Core) to learn how to switch to another DBMS.
The solution is configured to use **Entity Framework Core** with **MS SQL Server**. EF Core supports [various](https://docs.microsoft.com/en-us/ef/core/providers/) database providers, so you can use any supported DBMS. See [the Entity Framework integration document](https://docs.abp.io/en/abp/latest/Entity-Framework-Core) to learn how to [switch to another DBMS](Entity-Framework-Core-Other-DBMS.md).
### Apply the migrations
### Apply the Migrations
The solution uses the [Entity Framework Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli). So, you need to apply migrations to create the database. There are two ways of applying the database migrations.
#### Apply migrations using the DbMigrator
#### Apply Migrations Using the DbMigrator
The solution comes with a `.DbMigrator` console application which applies migrations and also seed the initial data. It is useful on development as well as on production environment.
@ -183,9 +183,9 @@ Right click to the `.DbMigrator` project and select **Set as StartUp Project**
![db-migrator-output](images/db-migrator-output.png)
> Initial seed data creates the `admin` user in the database which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database.
> Initial [seed data](Data-Seeding.md) creates the `admin` user in the database which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database.
#### Using EF Core Update-Database command
#### Using EF Core Update-Database Command
Ef Core has `Update-Database` command which creates database if necessary and applies pending migrations.
@ -207,7 +207,9 @@ Open the **Package Manager Console**, select `.EntityFrameworkCore.DbMigrations`
This will create a new database based on the configured connection string.
> Using the `.Migrator` tool is the suggested way, because it also seeds the initial data to be able to properly run the web application.
> **Using the `.DbMigrator` tool is the suggested way**, because it also seeds the initial data to be able to properly run the web application.
>
> If you just use the `Update-Database` command, you will have an empty database, so you can not login to the application since there is no initial admin user in the database. You can use the `Update-Database` command in development time when you don't need to seed the database. However, using the `.DbMigrator` application is easier and you can always use it to migrate the schema and seed the database.
{{ else if DB == "Mongo" }}
@ -219,7 +221,7 @@ This will create a new database based on the configured connection string.
The solution is configured to use **MongoDB** in your local computer, so you need to have a MongoDB server instance up and running or change the connection string to another MongoDB server.
### Seed initial data
### Seed Initial Data
The solution comes with a `.DbMigrator` console application which seeds the initial data. It is useful on development as well as on production environment.
@ -233,11 +235,11 @@ Right click to the `.DbMigrator` project and select **Set as StartUp Project**
![db-migrator-output](images/db-migrator-output.png)
> Initial seed data creates the `admin` user in the database which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database.
> Initial [seed data](Data-Seeding.md) creates the `admin` user in the database which is then used to login to the application. So, you need to use `.DbMigrator` at least once for a new database.
{{ end }}
## Run the application
## Run the Application
{{ if UI == "MVC" }}
@ -331,83 +333,18 @@ open your web browser and navigate to [localhost:4200](http://localhost:4200/)
{{ end }}
Enter **admin** as the username and **1q2w3E*** as the password to login to the application:
![bookstore-home](images/bookstore-home.png)
The application is up and running. You can start developing your application based on this startup template.
#### Mobile Development
ABP platform provide [React Native](https://reactnative.dev/) template to develop mobile applications.
>The solution includes the React Native application in the `react-native` folder as default. If you don't plan to develop a mobile application with React Native, you can ignore this step and delete the `react-native` folder.
The React Native application running on an Android emulator or a physical phone cannot connect to the backend on `localhost`. To fix this problem, it is necessary to run backend on the local IP.
{{ if Tiered == "No"}}
![React Native host project local IP entry](images/rn-host-local-ip.png)
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `SelfUrl` and `Authority` properties with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ else if Tiered == "Yes" }}
![React Native tiered project local IP entry](images/rn-tiered-local-ip.png)
* Open the `appsettings.json` in the `.IdentityServer` folder. Replace the `localhost` address on the `SelfUrl` property with your local IP address.
* Open the `launchSettings.json` in the `.IdentityServer/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
* Open the `appsettings.json` in the `.HttpApi.Host` folder. Replace the `localhost` address on the `Authority` property with your local IP address.
* Open the `launchSettings.json` in the `.HttpApi.Host/Properties` folder. Replace the `localhost` address on the `applicationUrl` properties with your local IP address.
{{ end }}
Run the backend as described in the [**Running the HTTP API Host (server-side)**](#running-the-http-api-host-server-side) section.
> React Native application does not trust the auto-generated .NET HTTPS certificate, you should use the HTTP during development.
Go to the `react-native` folder, open a command line terminal, type the `yarn` command (we suggest to the [yarn](https://yarnpkg.com/) package manager while `npm install` will also work in most cases):
```bash
yarn
```
* Open the `Environment.js` in the `react-native` folder and replace the `localhost` address on the `apiUrl` and `issuer` properties with your local IP address as shown below:
![react native environment local IP](images/rn-environment-local-ip.png)
{{ if Tiered == "Yes" }}
> Make sure that `issuer` matches the running address of the `.IdentityServer` project, `apiUrl` matches the running address of the `.HttpApi.Host` project.
{{else}}
> Make sure that `issuer` and `apiUrl` matches the running address of the `.HttpApi.Host` project.
{{ end }}
Once all node modules are loaded, execute `yarn start` (or `npm start`) command:
```bash
yarn start
```
Wait Expo CLI to start. Expo CLI opens the management interface on the `http://localhost:19002/` address.
![expo-interface](images/rn-expo-interface.png)
In the above management interface, you can start the application with an Android emulator, an iOS simulator or a physical phone by the scan the QR code with the [Expo Client](https://expo.io/tools#client).
Enter **admin** as the username and **1q2w3E*** as the password to login to the application. The application is up and running. You can start developing your application based on this startup template.
> See the [Android Studio Emulator](https://docs.expo.io/workflow/android-simulator/), [iOS Simulator](https://docs.expo.io/workflow/ios-simulator/) documents on expo.io.
## Mobile Development
![React Native login screen on iPhone 11](images/rn-login-iphone.png)
When you create a new application, the solution includes `react-native` folder by default. This is a basic [React Native](https://reactnative.dev/) startup template to develop mobile applications integrated to your ABP based backends.
Enter **admin** as the username and **1q2w3E*** as the password to login to the application.
If you don't plan to develop a mobile application with React Native, you can safely delete the `react-native` folder.
The application is up and running. You can continue to develop your application based on this startup template.
> You can specifying the `--mobile none` option to the ABP CLI to not create the `react-native` folder in the beginning.
> The [application startup template](Startup-Templates/Application.md) includes the TenantManagement and Identity modules.
See the "[Getting Started with the React Native](Getting-Started-React-Native.md)" document to learn how to configure and run the React Native application.
## What's next?
## See Also
[Application development tutorial](Tutorials/Part-1.md)
* [Web Application Development Tutorial](Tutorials/Part-1.md)

2
docs/en/How-To/Azure-Active-Directory-Authentication-MVC.md

@ -136,7 +136,7 @@ And that's it, integration is completed. Keep on mind that you can connect any o
## The Source Code
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization).
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization).
# FAQ

2
docs/en/How-To/Customize-Login-Page-MVC.md

@ -105,7 +105,7 @@ Just changed the `@model` to `Acme.BookStore.Web.Pages.Account.CustomLoginModel`
## The Source Code
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization).
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization).
## See Also

2
docs/en/How-To/Customize-SignIn-Manager.md

@ -93,7 +93,7 @@ PreConfigure<IdentityBuilder>(identityBuilder =>
## The Source Code
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization).
You can find the source code of the completed example [here](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization).
## See Also

2
docs/en/Samples/Index.md

@ -51,7 +51,7 @@ While there is no Razor Pages & MongoDB combination, you can check both document
* **Stored Procedure Demo**: Demonstrates how to use stored procedures, database views and functions with best practices.
* [Source code](https://github.com/abpframework/abp-samples/tree/master/StoredProcedureDemo)
* **Authentication Customization**: A solution to show how to customize the authentication for ASP.NET Core MVC / Razor Pages applications.
* [Source code](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization)
* [Source code](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization)
* Related "[How To](../How-To/Index.md)" documents:
* [Azure Active Directory Authentication](../How-To/Azure-Active-Directory-Authentication-MVC.md)
* [Customize the Login Page](../How-To/Customize-Login-Page-MVC.md)

1
docs/en/Tutorials/Part-1.md

@ -718,6 +718,7 @@ Create `index.js` JavaScript file under the `Pages/Books/` folder:
````js
$(function () {
var l = abp.localization.getResource('BookStore');
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList),
columnDefs: [

51
docs/en/UI/Angular/Custom-Setting-Page.md

@ -1,39 +1,34 @@
# Custom Setting Page
There are several settings tabs from different modules. You can add custom settings page to your project in 3 steps.
There are several settings tabs from different modules. You can add a custom setting page to your project.
1. Create a Component
1. Create a component with the following command:
```js
import { Select } from '@ngxs/store';
import { Component } from '@angular/core';
@Component({
selector: 'app-your-custom-settings',
template: `
custom-settings works!
`,
})
export class YourCustomSettingsComponent {
// Your component logic
}
```bash
yarn ng generate component my-settings
```
2. Add the `YourCustomSettingsComponent` to `declarations` and the `entryComponents` arrays in the `AppModule`.
3. Open the `app.component.ts` and add the below content to the `ngOnInit`
2. Open the `app.component.ts` and modify the file as shown below:
```js
import { addSettingTab } from '@abp/ng.theme.shared';
// ...
ngOnInit() {
addSettingTab({
component: YourCustomSettingsComponent,
name: 'Type here the setting tab title (you can type a localization key, e.g: AbpAccount::Login',
order: 4,
requiredPolicy: 'type here a policy key'
});
import { Component } from '@angular/core';
import { SettingTabsService } from '@abp/ng.core'; // imported SettingTabsService
import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent
@Component(/* component metadata */)
export class AppComponent {
constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent
{
// added below
settingTabs.add([
{
name: 'MySettings',
order: 1,
requiredPolicy: 'policy key here',
component: MySettingsComponent,
},
]);
}
}
```

21
docs/en/UI/Angular/Localization.md

@ -146,16 +146,6 @@ Find [styles configuration in angular.json](https://angular.io/guide/workspace-c
"build": {
"options": {
"styles": [
{
"input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css",
"inject": false,
"bundleName": "bootstrap-rtl.min"
},
{
"input": "node_modules/bootstrap/dist/css/bootstrap.min.css",
"inject": true,
"bundleName": "bootstrap-ltr.min"
},
{
"input": "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
"inject": true,
@ -166,6 +156,16 @@ Find [styles configuration in angular.json](https://angular.io/guide/workspace-c
"inject": true,
"bundleName": "fontawesome-v4-shims.min"
},
{
"input": "node_modules/@abp/ng.theme.shared/styles/bootstrap-rtl.min.css",
"inject": false,
"bundleName": "bootstrap-rtl.min"
},
{
"input": "node_modules/bootstrap/dist/css/bootstrap.min.css",
"inject": true,
"bundleName": "bootstrap-ltr.min"
},
"apps/dev-app/src/styles.scss"
],
}
@ -174,6 +174,7 @@ Find [styles configuration in angular.json](https://angular.io/guide/workspace-c
}
}
}
```
#### Step 2. Clear Lazy Loaded Fontawesome in AppComponent

104
docs/en/UI/Angular/Migration-Guide-v3.md

@ -237,9 +237,10 @@ Until v3, we had been using a custom component, `abp-table`, as the default tabl
As of ABP v3, we have switched to a battle-tested, well-executed data grid: [ngx-datatable](https://github.com/swimlane/ngx-datatable). All ABP modules will come with ngx-datatable already implemented in them. `ThemeSharedModule` already exports `NgxDatatableModule`. So, if you install the package by running `yarn add @swimlane/ngx-datatable` in your terminal, it will be available for use in all modules of your app.
For proper styling, you need to add the following in the styles section of your angular.json file:
For proper styling, you need to add the following in the styles section of your angular.json file (above all others):
```json
"styles": [
{
"input": "node_modules/@swimlane/ngx-datatable/index.css",
"inject": true,
@ -254,7 +255,9 @@ For proper styling, you need to add the following in the styles section of your
"input": "node_modules/@swimlane/ngx-datatable/themes/material.css",
"inject": true,
"bundleName": "ngx-datatable-material"
}
},
// other styles
]
```
Since `abp-table` is not dropped yet, modules previously built by ABP v2.x will not suddenly lose all their tables. Yet, they will look and feel different from built-in ABP v3 modules. Therefore, you will probably want to convert the tables in those modules to ngx-datatable. In order to decrease the amount of work required to convert an abp-table into ngx-datatable, we have modified the [ListService](./List-Service.md) to work well with ngx-datatable and [introduced](https://volosoft.com/blog/attribute-directives-to-avoid-repetition-in-angular-templates) two new directives: `NgxDatatableListDirective` and `NgxDatatableDefaultDirective`.
@ -355,6 +358,103 @@ Once you bind the injected `ListService` instance through `NgxDatatableListDirec
**Important Note:** The `abp-table` is not removed, but is deprecated and will be removed in the future. Please consider switching to ngx-datatable.
### Extensions System [COMMERCIAL]
The extensions system is open sourced now and is publicly available from `@abp/ng.theme.shared/extensions` package instead of `@volo/abp.commercial.ng.ui`. Also, according to the new structure of config packages, the configuration is given through `forLazy` static methods as described above.
#### What to Do When Migrating?
If you have never used the extensions system before, you do not have to do anything. If you have, then please check the documentation again to see what changed. Extension system itself works the same as before. The only changes are the package you import from and the static method and the module you pass your contributors to.
### Lepton Theme Logos [COMMERCIAL]
In ABP v2.x, Lepton had one light and one dark logo per color theme. We have realized we could make it work with only one light and one dark logo. So, we have changed how Lepton looks up logo images and now you just need to have a `logo-light.png` and a `logo-dark.png` in your project.
#### What to Do When Migrating?
If you have switched template logo PNGs before, the change is simple:
- Go to `/assets/images/logo` folder.
- Rename `theme1.png` as `logo-light.png` and `theme1-reverse.png` as `logo-dark.png`.
- Delete all other `theme*.png` files.
If you have replaced the logo component(s), the change is a little bit different, but still simple. The `LayoutStateService` has a two new members: `primaryLogoColor` and `secondaryLogoColor`. They have an observable stream of `'light'` and `'dark'` strings as value. You can consume their value in your custom logo component templates with the `async` pipe. Here is a complete example which covers both primary and secondary (account) layout logos.
```js
import { AddReplaceableComponent } from '@abp/ng.core';
import { CommonModule } from '@angular/common';
import { APP_INITIALIZER, Component, Injector, NgModule } from '@angular/core';
import { Store } from '@ngxs/store';
import { eAccountComponents } from '@volo/abp.ng.account';
import {
AccountLayoutComponent,
eThemeLeptonComponents,
LayoutStateService,
} from '@volo/abp.ng.theme.lepton';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
template: `
<div class="account-brand p-4 text-center mb-1" *ngIf="isAccount; else link">
<ng-template [ngTemplateOutlet]="link"></ng-template>
</div>
<ng-template #link>
<a [style.background-image]="logoUrl | async" class="navbar-brand" routerLink="/"></a>
</ng-template>
`,
})
export class LogoComponent {
isAccount: boolean;
logoColor: Observable<'dark' | 'light'>;
get logoUrl() {
return this.logoColor.pipe(map(color => `url(/assets/images/logo/logo-${color}.png)`));
}
constructor(injector: Injector) {
const layout = injector.get(LayoutStateService);
this.isAccount = Boolean(injector.get(AccountLayoutComponent, false));
this.logoColor = this.isAccount ? layout.secondaryLogoColor : layout.primaryLogoColor;
}
}
@NgModule({
imports: [CommonModule],
declarations: [LogoComponent],
exports: [LogoComponent],
})
export class LogoModule {}
export const APP_LOGO_PROVIDER = [
{ provide: APP_INITIALIZER, useFactory: switchLogos, multi: true, deps: [Store] },
];
export function switchLogos(store: Store) {
return () => {
store.dispatch(
new AddReplaceableComponent({
component: LogoComponent,
key: eThemeLeptonComponents.Logo,
}),
);
store.dispatch(
new AddReplaceableComponent({
component: LogoComponent,
key: eAccountComponents.Logo,
}),
);
};
}
```
Just add `APP_LOGO_PROVIDER` to the providers of your root module (usually `AppModule`) and you will have a custom logo component adjusting to the theme colors.
### Deprecated Interfaces
Some interfaces have long been marked as deprecated and now they are removed.

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

@ -55,7 +55,9 @@ The directive can also be used as an attribute directive but we recommend to you
You can use `PermissionGuard` if you want to control authenticated user's permission to access to the route during navigation.
Add `requiredPolicy` to the `routes` property in your routing module.
* Import the PermissionGuard from @abp/ng.core.
* Add `canActivate: [PermissionGuard]` to your route object.
* Add `requiredPolicy` to the `data` property of your route in your routing module.
```js
import { PermissionGuard } from '@abp/ng.core';
@ -66,9 +68,7 @@ const routes: Routes = [
component: YourComponent,
canActivate: [PermissionGuard],
data: {
routes: {
requiredPolicy: 'AbpIdentity.Roles.Create',
},
requiredPolicy: 'YourProjectName.YourComponent', // policy key for your component
},
},
];

6
docs/en/UI/Angular/Service-Proxies.md

@ -32,7 +32,7 @@ A variable named `apiName` (available as of v2.4) is defined in each service. `a
The `providedIn` property of the services is defined as `'root'`. Therefore no need to add a service as a provider to a module. You can use a service by injecting it into a constructor as shown below:
```js
import { AbpApplicationConfigurationService } from '../app/shared/services';
import { AbpApplicationConfigurationService } from '../abp/applicationconfiguration/services';
//...
export class HomeComponent{
@ -48,14 +48,14 @@ The Angular compiler removes the services that have not been injected anywhere f
### Models
The generated models match the DTOs in the back-end. Each model is generated as a class under the `src/app/*/shared/models` folder.
The generated models match the DTOs in the back-end. Each model is generated as a class under the `src/app/*/models` folder.
There are a few [base classes](https://github.com/abpframework/abp/blob/dev/npm/ng-packs/packages/core/src/lib/models/dtos.ts) in the `@abp/ng.core` package. Some models extend these classes.
A class instance can be created as shown below:
```js
import { IdentityRoleCreateDto } from '../identity/shared/models';
import { IdentityRoleCreateDto } from '../identity/role/models'
//...
const instance = new IdentityRoleCreateDto({name: 'Role 1', isDefault: false, isPublic: true})
```

BIN
docs/en/UI/Angular/images/custom-settings.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 106 KiB

BIN
docs/en/UI/Angular/images/generated-files-via-generate-proxy.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

After

Width:  |  Height:  |  Size: 63 KiB

9
docs/en/docs-nav.json

@ -432,6 +432,15 @@
}
]
},
{
"text": "React Native",
"items": [
{
"text": "Getting Started",
"path": "Getting-Started-React-Native.md"
}
]
},
{
"text": "Common",
"items": [

177
docs/zh-Hans/Blog-Posts/2020-07-01 v3_0_Release/Post.md

@ -0,0 +1,177 @@
# ABP框架 v3.0 已发布
我们很高兴地宣布,**ABP框架**和**ABP商业版**3.0版已经发布.与常规的2周发布一个版本不同的是, 这个版本用了4周的时间.关闭了**119个[issue](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3A3.0)**,合并了**89个[pull request](https://github.com/abpframework/abp/pulls?q=is%3Aopen+is%3Apr+milestone%3A3.0)** 和主框架[仓库](https://github.com/abpframework/abp)中的**798次提交**.
由于这是一个**主要版本**,它也包括了一些**重大更改**.不要害怕,这些变化都容易对应,并且下面会详细解释.
> 详细更改日志请查看[GitHub的发布说明](https://github.com/abpframework/abp/releases/tag/3.0.0).
## ABP框架3.0有哪些新增内容?
这篇文章将只包括重要功能/更改.你可在[GitHub的发布说明](https://github.com/abpframework/abp/releases/tag/3.0.0)上看到所有的更改.
### Angular 10!
Angular 10刚刚[发布](https://blog.angular.io/version-10-of-angular-now-available-78960babd41),我们就立即迁移了[启动模板](https://docs.abp.io/en/abp/latest/Startup-Templates/Application)到Angular 10!所以,当你以Angular UI[创建一个新的解决方案](https://abp.io/get-started)时, 你将获得新Angular的优点.
我们为想要迁移到Angular 10的老版本项目准备了一份[迁移指南](https://github.com/abpframework/abp/blob/dev/docs/en/UI/Angular/Migration-Guide-v3.md).
### Oracle集成包
之前我们为使用Devart库, 基于EF Core for Oracle的应用程序创建了[一个集成包](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.Oracle.Devart), 因为官方的Oracle EF Core包还未支持EF Core 3.1. 现在它以[beta发布](https://www.nuget.org/packages/Oracle.EntityFrameworkCore/3.19.0-beta1).虽然是beta版,但我们已经创建了它的[集成包](https://www.nuget.org/packages/Volo.Abp.EntityFrameworkCore.Oracle),这样你就可以在你的应用程序中使用它.
更多细节请查看[文档](https://docs.abp.io/en/abp/latest/Entity-Framework-Core-Oracle).
### Azure BLOB存储提供器
在上一个版本中我们创建了一个[Blob存储系统](https://docs.abp.io/en/abp/latest/Blob-Storing), 包含一个文件系统和数据库存储提供器. 本次发布我们引入了Azure BLOB存储提供器.请查看[文档](https://docs.abp.io/en/abp/latest/Blob-Storing-Azure).
### 分布式缓存批量操作和新的Redis缓存包
ASP.NET Core的[标准IDistributeCache](https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed)接口不包含**批量操作**,如使用单独方法/服务器调用设置多个项目. ABP框架引入了新的方法可用于在ABP的`IDistributedCache<T>`接口中进行批量操作:
* GetManyAsync / GetMany
* SetManyAsync / SetMany
然后,我们需要为Redis缓存实现这些新方法并且[必须创建](https://github.com/abpframework/abp/issues/4483)一个Redis集成包用于扩展微软的实现.
这些方法也被ABP框架所使用, 用来缓存某个用户/角色/租户的设置,功能和权限,并且带来了**显著的性能提升**.
更多细节请查看[缓存文档](https://docs.abp.io/en/abp/latest/Caching).
### 为虚拟文件系统支持嵌入文件清单
虚拟文件系统现在支持在项目中使用`GenerateEmbeddedFilesManifest`来添加编译程序集中嵌入资源的**真实的文件/目录结构**.所以,你现在可以访问文件,而没有任何文件名的限制(以前,目录名称中的一些特殊字符,比如`.`在某些情况会有问题)
查看[文档](https://docs.abp.io/en/abp/latest/Virtual-File-System)学习如何利用新系统的优点.
### 新示例
基于社区的需求,我们准备了两个新的示例应用程序:
* [StoredProcedureDemo](https://github.com/abpframework/abp-samples/tree/master/StoredProcedureDemo)演示了如何在自定义仓储库中调用存储过程,视图和函数.
* [OrganizationUnitSample](https://github.com/abpframework/abp-samples/tree/master/OrganizationUnitSample)演示了如何为你的实体使用[Identity模块](https://docs.abp.io/en/abp/latest/Modules/Identity)的组织单元系统.
### DynamicStringLength 和 DynamicMaxLength 属性
当类被用作模型或[DTO](https://docs.abp.io/en/abp/latest/Data-Transfer-Objects)时, 标准的`StringLength`和`MaxLength`数据注解属性用来验证类中的属性是很有用的. 但是, 就像任何其它的属性一样, 长度的值应该是一个**编译时**已知的字面值(常量).
**示例: 使用`StringLength`**
````csharp
public class CreateBookDto
{
public const int MaxNameLength = 128; //常量!
[StringLength(MaxNameLength)]
public string Name { get; set; }
}
````
ABP框架现在有`DynamicStringLength` 和 `DynamicMaxLength`属性允许在**运行时**确定长度.
**示例: 使用`DynamicStringLength`**
````csharp
public class CreateBookDto
{
public static int MaxNameLength { get; set; } = 128;
[DynamicStringLength(typeof(CreateBookDto), nameof(MaxNameLength))]
public string Name { get; set; }
}
````
`DynamicStringLength`通过类的**类型**和这个类的一个静态属性的**名字**来读取最大长度(也有一个最小长度的选项, 就像`StringLength`).
这样就允许你从配置中读取最大值并且在应用程序启动时设置(一般在[模块](https://docs.abp.io/en/abp/latest/Module-Development-Basics)的`PreConfigureServices`方法)
````csharp
CreateBookDto.MaxNameLength = 200;
````
[预建应用程序模块](https://docs.abp.io/en/abp/latest/Modules/Index)使用了这个功能,所以你现在可以覆盖这些模块中定义的属性的最大长度了.
### 自动分布式事件
ABP可以为所有的实体在创建,更新和删除时**自动发布分布式事件**. 这很有用因为在分布式系统中你通常会对这些基础事件感兴趣.
这个功能在v3.0中**已成熟并[文档化了](https://docs.abp.io/en/abp/latest/Distributed-Event-Bus#pre-defined-events)**. 你可以轻松地配置一部分或全部要发布事件的实体.
### IAsyncQueryableExecuter
使用LINQ扩展方法,当你在查询时需要调用`ToListAsync()`,`FirstOrDefaultAsync()`... 不幸的是,这些方法并不是**标准的**LINQ扩展方法.它们定义在[Microsoft.EntityFrameworkCore](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore)包中(或在[MongoDB.Driver](https://www.nuget.org/packages/MongoDB.Driver/),如果你使用MongoDB的话).
所以,如果你想使用异步扩展方法, 你需要依赖这个包.这样做破坏了分层,并且使你的应用程序或领域层依赖于EF Core / MongoDB的包.
`IAsyncQueryableExecuter`是ABP框架定义的服务, 用来**不依赖特定提供器地执行异步查询**(EF Core / MongoDB包).
查看[文档](https://docs.abp.io/en/abp/latest/Repositories#iqueryable-async-operations)来获取细节和了解我们的建议.
### API 文档
现在我们为每次发布ABP框架和模块都公开[API文档](https://docs.abp.io/api-docs/abp/3.0/api/index.html).所以,你可以更容易地查看ABP框架的类.点击[文档](https://docs.abp.io/en/abp/latest/)导航菜单中的**API文档**的链接.
### 包列表
我们[创建了一个页面](http://abp.io/packages)列出所有ABP相关的官方NuGet和NPM包.
### 其他
* 为Identity Server实现了前端通道的服务端客户[登出](https://identityserver4.readthedocs.io/en/latest/topics/signout.html)
* `abp.currentUser`(Angular UI中的`CurrentUser`服务)现在有一个包含当前用户的角色名的`roles`数组.
* 升级所有的Nu​​Get和NPM软件包的依赖.
* 引入了`ReadOnlyAppService`基类(只包含get操作), 做为`CrudAppService`基类(其中有get,create,update和delete操作)的补充.
其他更新请查看[GitHub发行说明](https://github.com/abpframework/abp/releases/tag/3.0.0).
## ABP商业版3.0有哪些新增内容?
除了所有ABP框架的功能以外,ABP商业版同样在本次发布中有一些额外的功能.本节介绍3.0版本中[ABP商业版](https://commercial.abp.io/)的亮点.
### 新的文件管理模块
我们创建了一个用于在应用程序中存储和管理文件的新模块.这个新模块基于[BLOB存储系统](https://docs.abp.io/en/abp/latest/Blob-Storing),因此它可以使用不同的存储提供器来存储文件内容.
**示例截图**
![file-management-ui](file-management-ui.png)
您可以上传,下载和以分层文件夹结构组织文件.它也兼容多租户,你可以为租户限制总文件大小.在未来的版本中,我们将致力于“共享”系统, 用于以一个更可控的方式在用户之间或通过公开链接与你的客户共享文件.
> 文件管理模块是目前仅适用于MVC / Razor Pages UI.我们正工作于Angular UI,它会在未来的版本中发布.
## 重大更改
由于这是一个主要版本,我们重新设计了一些API,并引入了一些"容易解决"的重大更改.
### ABP框架
* 更改了一些预建应用程序模块的**常量**为静态属性, 这样你就可在你的代码中对它们修改. 如果你在属性中使用了这些常量,那么请使用上面介绍的`DynamicStringLength`.
* 更改`ConcurrencyStamp`最大长度为40. 你需要在更新ABP框架后**添加一个数据库迁移**并且更新数据库.
* NPM软件包的依赖关系使用`~`代替`^`,为了更加稳定.
### ABP商业版
* 更改了应用程序标识的文件名.此前,它为每个主题使用了单独的标识文件,如`theme1.png`,`theme1-reverse.png`,`theme2.png`,`theme2-reverse.png`(...`6`).现在,我们只有两个标识文件:`logo-light.png`和`logo-dark.png`.所以,重命名MVC UI的`wwwroot/images/logo/`和Angular UI的`/src/assets/images/logo/`下的标识.
* 我们也增加了ABP商业版的[API文档](https://docs.abp.io/api-docs/commercial/3.0/api/index.html).
> **此外,Angular UI请查看[迁移指南](https://github.com/abpframework/abp/blob/dev/docs/en/UI/Angular/Migration-Guide-v3.md)**.
## 已知问题
* 3.0.0版本有一个分层架构的问题.查看[这个issue](https://github.com/abpframework/abp/pull/4564)为你的应用程序解决它,直到我们发布V3.0.1.
## 关于未来的版本
我们将继续在每两个星期发布一个新的小功能版本.所以,下一个预计发布日期是**2020年7月16日**的**3.1**版本.
在接下来的几个版本中,我们将专注于**Blazor UI**,如[路线图](https://docs.abp.io/en/abp/latest/Road-Map)中承诺的.我们将继续改进文档,创建示例,添加其他新功能和改善.关注[ABP框架Twitter账号](https://twitter.com/abpframework)获取最新消息...
## 彩蛋: 文章!
除了开发我们的产品,我们的团队一直在不断书写各种主题的文章/教程.你可能感兴趣的最新文章:
* [Angular 10有哪些新增内容?](https://volosoft.com/blog/what-is-new-in-angular-10)
* [在分布式架构中使用ABP, SignalR和RabbitMQ构建实时消息系统](https://volosoft.com/blog/RealTime-Messaging-Distributed-Architecture-Abp-SingalR-RabbitMQ)
* [如何在Angular模板中使用Attribute Directives来避免重复](https://volosoft.com/blog/attribute-directives-to-avoid-repetition-in-angular-templates)

BIN
docs/zh-Hans/Blog-Posts/2020-07-01 v3_0_Release/file-management-ui.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

2
docs/zh-Hans/How-To/Azure-Active-Directory-Authentication-MVC.md

@ -136,7 +136,7 @@ private void ConfigureAuthentication(ServiceConfigurationContext context, IConfi
## 本文的源代码
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization)找到已完成的示例源码.
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization)找到已完成的示例源码.
# FAQ

2
docs/zh-Hans/How-To/Customize-Login-Page-MVC.md

@ -105,7 +105,7 @@ public class CustomLoginModel : LoginModel
## 本文的源代码
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization)找到已完成的示例源码.
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization)找到已完成的示例源码.
## 另请参阅

2
docs/zh-Hans/How-To/Customize-SignIn-Manager.md

@ -93,7 +93,7 @@ PreConfigure<IdentityBuilder>(identityBuilder =>
## 本文的源代码
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization)找到已完成的示例源码.
你可以在[这里](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization)找到已完成的示例源码.
## 另请参阅

2
docs/zh-Hans/Samples/Index.md

@ -49,7 +49,7 @@
* [源码](https://github.com/abpframework/abp-samples/tree/master/TextTemplateDemo)
* [文本模板文档](../Text-Templating.md)
* **自定义认证**: 如何为ASP.NET Core MVC / Razor Pages应用程序自定义身份验证的解决方案.
* [源码](https://github.com/abpframework/abp-samples/tree/master/aspnet-core/Authentication-Customization)
* [源码](https://github.com/abpframework/abp-samples/tree/master/Authentication-Customization)
* 相关 "[How To](../How-To/Index.md)" 文档:
* [Azure Active Directory 认证](../How-To/Azure-Active-Directory-Authentication-MVC.md)
* [自定义登录页面](../How-To/Customize-Login-Page-MVC.md)

5
docs/zh-Hans/Tutorials/Part-1.md

@ -675,7 +675,7 @@ namespace Acme.BookStore.Web.Menus
<h2>@L["Book"]</h2>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BookTable">
<abp-table striped-rows="true" id="BooksTable">
<thead>
<tr>
<th>@L["Name"]</th>
@ -704,7 +704,8 @@ namespace Acme.BookStore.Web.Menus
````js
$(function () {
var dataTable = $('#BookTable').DataTable(abp.libs.datatables.normalizeConfiguration({
var l = abp.localization.getResource('BookStore');
var dataTable = $('#BooksTable').DataTable(abp.libs.datatables.normalizeConfiguration({
ajax: abp.libs.datatables.createAjax(acme.bookStore.book.getList),
columnDefs: [
{ data: "name" },

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml

@ -86,7 +86,9 @@
</div>
}
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Account)
@RenderBody()
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Account)
</abp-column>
</abp-row>
</div>
@ -102,4 +104,4 @@
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Account)
</body>
</html>
</html>

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml

@ -64,7 +64,9 @@
@RenderSection("content_toolbar", false)
</div>
</div>
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Application)
@RenderBody()
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Application)
</div>
<abp-script-bundle name="@BasicThemeBundles.Scripts.Global" />
@ -78,4 +80,4 @@
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Application)
</body>
</html>
</html>

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml

@ -59,7 +59,9 @@
<div class="@containerClass">
@(await Component.InvokeAsync<PageAlertsViewComponent>())
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.First, StandardLayouts.Empty)
@RenderBody()
@await Component.InvokeLayoutHookAsync(LayoutHooks.PageContent.Last, StandardLayouts.Empty)
</div>
<abp-script-bundle name="@BasicThemeBundles.Scripts.Global" />
@ -73,4 +75,4 @@
@await Component.InvokeLayoutHookAsync(LayoutHooks.Body.Last, StandardLayouts.Empty)
</body>
</html>
</html>

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Components/LayoutHook/LayoutHooks.cs

@ -13,5 +13,11 @@
public const string First = "Body.First";
public const string Last = "Body.Last";
}
public static class PageContent
{
public const string First = "PageContent.First";
public const string Last = "PageContent.Last";
}
}
}

19
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateProxyCommand.cs

@ -11,8 +11,10 @@ using Volo.Abp.Cli.ProjectBuilding;
using Volo.Abp.Cli.ProjectBuilding.Building;
using Volo.Abp.DependencyInjection;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using Volo.Abp.Localization;
using Volo.Abp.Reflection;
namespace Volo.Abp.Cli.Commands
@ -801,13 +803,16 @@ namespace Volo.Abp.Cli.Commands
return value;
}
return Regex.Replace(
value,
"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])",
"-$1",
RegexOptions.Compiled)
.Trim()
.ToLower();
using (CultureHelper.Use(CultureInfo.InvariantCulture))
{
return Regex.Replace(
value,
"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z])",
"-$1",
RegexOptions.Compiled)
.Trim()
.ToLower();
}
}
}

20
framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NpmPackagesUpdater.cs

@ -70,11 +70,18 @@ namespace Volo.Abp.Cli.ProjectModification
if (includePreviews)
{
await CreateNpmrcFileAsync(Path.GetDirectoryName(file.Key));
RunNpmInstall(fileDirectory);
}
else if (switchToStable)
{
await DeleteNpmrcFileAsync(Path.GetDirectoryName(file.Key));
}
if (await NpmrcFileExistAsync(fileDirectory))
{
RunNpmInstall(fileDirectory);
}
else
{
RunYarn(fileDirectory);
}
@ -93,15 +100,20 @@ namespace Volo.Abp.Cli.ProjectModification
await Task.CompletedTask;
}
private static async Task<bool> NpmrcFileExistAsync(string directoryName)
{
return File.Exists(Path.Combine(directoryName, ".npmrc"));
}
private async Task CreateNpmrcFileAsync(string directoryName)
{
var fileName = Path.Combine(directoryName, ".npmrc");
var abpRegistry = "@abp:registry=https://www.myget.org/F/abp-nightly/npm";
var voloRegistry = await GetVoloRegistryAsync();
if (File.Exists(fileName))
if (await NpmrcFileExistAsync(directoryName))
{
var fileContent = File.ReadAllText(fileName);
if (!fileContent.Contains(abpRegistry))
@ -237,7 +249,7 @@ namespace Volo.Abp.Cli.ProjectModification
_fileVersionStorage[package.Name] = newVersionWithPrefix;
return $"~{newVersionWithPrefix}";
return newVersionWithPrefix;
}
protected virtual List<JProperty> GetAbpPackagesFromPackageJson(JObject fileObject)

5
framework/src/Volo.Abp.EntityFrameworkCore/Volo/Abp/EntityFrameworkCore/AbpDbContext.cs

@ -491,6 +491,11 @@ namespace Volo.Abp.EntityFrameworkCore
return;
}
if (!typeof(IEntity).IsAssignableFrom(typeof(TEntity)))
{
return;
}
modelBuilder.Entity<TEntity>().ConfigureByConvention();
ConfigureGlobalFilters<TEntity>(modelBuilder, mutableEntityType);

38
framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs

@ -19,7 +19,8 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
{
public class MongoDbRepository<TMongoDbContext, TEntity>
: RepositoryBase<TEntity>,
IMongoDbRepository<TEntity>
IMongoDbRepository<TEntity>,
IMongoQueryable<TEntity>
where TMongoDbContext : IAbpMongoDbContext
where TEntity : class, IEntity
{
@ -167,7 +168,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
}
public override async Task<TEntity> FindAsync(
Expression<Func<TEntity, bool>> predicate,
Expression<Func<TEntity, bool>> predicate,
bool includeDetails = true,
CancellationToken cancellationToken = default)
{
@ -322,6 +323,35 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
{
throw new AbpDbConcurrencyException("Database operation expected to affect 1 row but actually affected 0 row. Data may have been modified or deleted since entities were loaded. This exception has been thrown on optimistic concurrency check.");
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <returns></returns>
public QueryableExecutionModel GetExecutionModel()
{
return GetMongoQueryable().GetExecutionModel();
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public IAsyncCursor<TEntity> ToCursor(CancellationToken cancellationToken = new CancellationToken())
{
return GetMongoQueryable().ToCursor(cancellationToken);
}
/// <summary>
/// IMongoQueryable<TEntity>
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public Task<IAsyncCursor<TEntity>> ToCursorAsync(CancellationToken cancellationToken = new CancellationToken())
{
return GetMongoQueryable().ToCursorAsync(cancellationToken);
}
}
public class MongoDbRepository<TMongoDbContext, TEntity, TKey>
@ -331,7 +361,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
where TEntity : class, IEntity<TKey>
{
public IMongoDbRepositoryFilterer<TEntity, TKey> RepositoryFilterer { get; set; }
public MongoDbRepository(IMongoDbContextProvider<TMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
@ -376,4 +406,4 @@ namespace Volo.Abp.Domain.Repositories.MongoDB
return RepositoryFilterer.CreateEntityFilter(entity, withConcurrencyStamp, concurrencyStamp);
}
}
}
}

7
framework/src/Volo.Abp.MongoDB/Volo/Abp/MongoDB/MongoDbAsyncQueryableProvider.cs

@ -8,6 +8,7 @@ using Volo.Abp.DependencyInjection;
using Volo.Abp.Linq;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.DynamicProxy;
namespace Volo.Abp.MongoDB
{
@ -15,12 +16,12 @@ namespace Volo.Abp.MongoDB
{
public bool CanExecute<T>(IQueryable<T> queryable)
{
return queryable.Provider.GetType().Namespace?.StartsWith("MongoDB") ?? false;
return ProxyHelper.UnProxy(queryable) is IMongoQueryable<T>;
}
protected IMongoQueryable<T> GetMongoQueryable<T>(IQueryable<T> queryable)
protected virtual IMongoQueryable<T> GetMongoQueryable<T>(IQueryable<T> queryable)
{
return (IMongoQueryable<T>) queryable;
return ProxyHelper.UnProxy(queryable).As<IMongoQueryable<T>>();
}
public Task<bool> ContainsAsync<T>(IQueryable<T> queryable, T item, CancellationToken cancellationToken = default)

76
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/MongoDbAsyncQueryableProvider_Tests.cs

@ -0,0 +1,76 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.TestApp.Domain;
using Volo.Abp.TestApp.Testing;
using Volo.Abp.Uow;
using Xunit;
namespace Volo.Abp.MongoDB.Repositories
{
[Collection(MongoTestCollection.Name)]
public class MongoDbAsyncQueryableProvider_Tests : TestAppTestBase<AbpMongoDbTestModule>
{
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IRepository<Person, Guid> _personRepository;
private readonly MongoDbAsyncQueryableProvider _mongoDbAsyncQueryableProvider;
public MongoDbAsyncQueryableProvider_Tests()
{
_unitOfWorkManager = GetRequiredService<IUnitOfWorkManager>();
_personRepository = GetRequiredService<IRepository<Person, Guid>>();
_mongoDbAsyncQueryableProvider = GetRequiredService<MongoDbAsyncQueryableProvider>();
}
[Fact]
public void CanExecute()
{
_mongoDbAsyncQueryableProvider.CanExecute(_personRepository).ShouldBeTrue();
_mongoDbAsyncQueryableProvider.CanExecute(_personRepository.WithDetails()).ShouldBeTrue();
}
[Fact]
public async Task FirstOrDefaultAsync()
{
using (var uow = _unitOfWorkManager.Begin())
{
(await _mongoDbAsyncQueryableProvider.FirstOrDefaultAsync(_personRepository.Where(p => p.Name == "Douglas"))).ShouldNotBeNull();
await uow.CompleteAsync();
}
}
[Fact]
public async Task AnyAsync()
{
using (var uow = _unitOfWorkManager.Begin())
{
(await _mongoDbAsyncQueryableProvider.AnyAsync(_personRepository, p => p.Name == "Douglas")).ShouldBeTrue();
await uow.CompleteAsync();
}
}
[Fact]
public async Task CountAsync()
{
using (var uow = _unitOfWorkManager.Begin())
{
(await _mongoDbAsyncQueryableProvider.CountAsync(_personRepository.Where(p => p.Name == "Douglas"))).ShouldBeGreaterThan(0);
await uow.CompleteAsync();
}
}
[Fact]
public async Task LongCountAsync()
{
using (var uow = _unitOfWorkManager.Begin())
{
(await _mongoDbAsyncQueryableProvider.LongCountAsync(_personRepository)).ShouldBeGreaterThan(0);
await uow.CompleteAsync();
}
}
//More MongoDbAsyncQueryableProvider's method test.
}
}

10
framework/test/Volo.Abp.MongoDB.Tests/Volo/Abp/MongoDB/Repositories/Repository_Basic_Tests.cs

@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver.Linq;
using Shouldly;
using Volo.Abp.TestApp;
using Volo.Abp.TestApp.Domain;
@ -12,6 +13,15 @@ namespace Volo.Abp.MongoDB.Repositories
[Collection(MongoTestCollection.Name)]
public class Repository_Basic_Tests : Repository_Basic_Tests<AbpMongoDbTestModule>
{
[Fact]
public void ToMongoQueryable_Test()
{
((IMongoQueryable<Person>) PersonRepository).ShouldNotBeNull();
PersonRepository.As<IMongoQueryable<Person>>().ShouldNotBeNull();
((IMongoQueryable<Person>) PersonRepository.Where(p => p.Name == "Douglas")).ShouldNotBeNull();
PersonRepository.Where(p => p.Name == "Douglas").As<IMongoQueryable<Person>>().ShouldNotBeNull();
}
[Fact]
public async Task Linq_Queries()
{

7
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Testing/Repository_Basic_Tests.cs

@ -28,6 +28,13 @@ namespace Volo.Abp.TestApp.Testing
person.Phones.Count.ShouldBe(2);
}
[Fact]
public async Task GetListAsync()
{
var persons = await PersonRepository.GetListAsync();
persons.Count.ShouldBeGreaterThan(0);
}
[Fact]
public async Task GetAsync_With_Predicate()
{

2
npm/lerna.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"packages": [
"packs/*"
],

2
npm/ng-packs/apps/dev-app/src/app/app.module.ts

@ -15,7 +15,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { APP_ROUTE_PROVIDER } from './route.provider';
const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: false })];
const LOGGERS = [NgxsLoggerPluginModule.forRoot({ disabled: true })];
@NgModule({
imports: [

2
npm/ng-packs/lerna.version.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"packages": [
"packages/*"
],

4
npm/ng-packs/packages/account/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.account",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

2
npm/ng-packs/packages/core/package.json

@ -1,6 +1,6 @@
{
"name": "@abp/ng.core",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",

8
npm/ng-packs/packages/core/src/lib/core.module.ts

@ -37,7 +37,7 @@ import { SessionState } from './states/session.state';
import { CORE_OPTIONS } from './tokens/options.token';
import { noop } from './utils/common-utils';
import './utils/date-extensions';
import { getInitialData, localeInitializer } from './utils/initial-utils';
import { getInitialData, localeInitializer, configureOAuth } from './utils/initial-utils';
export function storageFactory(): OAuthStorage {
return localStorage;
@ -179,6 +179,12 @@ export class CoreModule {
useClass: ApiInterceptor,
multi: true,
},
{
provide: APP_INITIALIZER,
multi: true,
deps: [Injector, NGXS_CONFIG_PLUGIN_OPTIONS],
useFactory: configureOAuth,
},
{
provide: APP_INITIALIZER,
multi: true,

6
npm/ng-packs/packages/core/src/lib/services/auth.service.ts

@ -20,11 +20,7 @@ export class AuthService {
private oAuthService: OAuthService,
private store: Store,
@Optional() @Inject('ACCOUNT_OPTIONS') private options: any,
) {
this.oAuthService.configure(
this.store.selectSnapshot(ConfigState.getOne('environment')).oAuthConfig,
);
}
) {}
login(username: string, password: string): Observable<any> {
const tenant = this.store.selectSnapshot(SessionState.getTenant);

31
npm/ng-packs/packages/core/src/lib/tests/initial-utils.spec.ts

@ -3,7 +3,8 @@ import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { Store } from '@ngxs/store';
import { of } from 'rxjs';
import { GetAppConfiguration } from '../actions';
import { getInitialData, localeInitializer } from '../utils';
import { getInitialData, localeInitializer, configureOAuth } from '../utils';
import { OAuthService } from 'angular-oauth2-oidc';
@Component({
selector: 'abp-dummy',
@ -15,16 +16,30 @@ describe('InitialUtils', () => {
let spectator: Spectator<DummyComponent>;
const createComponent = createComponentFactory({
component: DummyComponent,
mocks: [Store],
mocks: [Store, OAuthService],
});
beforeEach(() => (spectator = createComponent()));
describe('#configureOAuth', () => {
test('should be called the the configure method of OAuthService', async () => {
const injector = spectator.inject(Injector);
const injectorSpy = jest.spyOn(injector, 'get');
const oAuth = spectator.inject(OAuthService);
const configureSpy = jest.spyOn(oAuth, 'configure');
injectorSpy.mockReturnValueOnce(oAuth);
await configureOAuth(injector, { environment: { oAuthConfig: { issuer: 'test' } } })();
expect(configureSpy).toHaveBeenCalledWith({ issuer: 'test' });
});
});
describe('#getInitialData', () => {
test('should dispatch GetAppConfiguration and return', async () => {
const injector = spectator.get(Injector);
const injector = spectator.inject(Injector);
const injectorSpy = jest.spyOn(injector, 'get');
const store = spectator.get(Store);
const store = spectator.inject(Store);
const dispatchSpy = jest.spyOn(store, 'dispatch');
injectorSpy.mockReturnValueOnce(store);
@ -40,9 +55,9 @@ describe('InitialUtils', () => {
describe('#checkAccessToken', () => {
test('should call logOut fn of OAuthService when token is valid and current user not found', async () => {
const injector = spectator.get(Injector);
const injector = spectator.inject(Injector);
const injectorSpy = jest.spyOn(injector, 'get');
const store = spectator.get(Store);
const store = spectator.inject(Store);
const dispatchSpy = jest.spyOn(store, 'dispatch');
const logOutFn = jest.fn();
@ -58,9 +73,9 @@ describe('InitialUtils', () => {
describe('#localeInitializer', () => {
test('should resolve registerLocale', async () => {
const injector = spectator.get(Injector);
const injector = spectator.inject(Injector);
const injectorSpy = jest.spyOn(injector, 'get');
const store = spectator.get(Store);
const store = spectator.inject(Store);
store.selectSnapshot.andCallFake(selector => selector({ SessionState: { language: 'tr' } }));
injectorSpy.mockReturnValue(store);
expect(typeof localeInitializer(injector)).toBe('function');

10
npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts

@ -9,6 +9,16 @@ import { ABP } from '../models/common';
import { ConfigState } from '../states/config.state';
import { CORE_OPTIONS } from '../tokens/options.token';
export function configureOAuth(injector: Injector, options: ABP.Root) {
const fn = () => {
const oAuth = injector.get(OAuthService);
oAuth.configure(options.environment.oAuthConfig);
return Promise.resolve();
};
return fn;
}
export function getInitialData(injector: Injector) {
const fn = () => {
const store: Store = injector.get(Store);

4
npm/ng-packs/packages/feature-management/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.feature-management",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

6
npm/ng-packs/packages/identity/package.json

@ -1,14 +1,14 @@
{
"name": "@abp/ng.identity",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.permission-management": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.permission-management": "~3.0.2",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

4
npm/ng-packs/packages/permission-management/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.permission-management",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

4
npm/ng-packs/packages/setting-management/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.setting-management",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

6
npm/ng-packs/packages/tenant-management/package.json

@ -1,14 +1,14 @@
{
"name": "@abp/ng.tenant-management",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.feature-management": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.feature-management": "~3.0.2",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

4
npm/ng-packs/packages/theme-basic/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.theme.basic",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.theme.shared": "~3.0.0",
"@abp/ng.theme.shared": "~3.0.2",
"tslib": "^2.0.0"
},
"publishConfig": {

4
npm/ng-packs/packages/theme-shared/package.json

@ -1,13 +1,13 @@
{
"name": "@abp/ng.theme.shared",
"version": "3.0.0",
"version": "3.0.2",
"homepage": "https://abp.io",
"repository": {
"type": "git",
"url": "https://github.com/abpframework/abp.git"
},
"dependencies": {
"@abp/ng.core": "~3.0.0",
"@abp/ng.core": "~3.0.2",
"@fortawesome/fontawesome-free": "^5.13.1",
"@ng-bootstrap/ng-bootstrap": "^6.1.0",
"@ngx-validate/core": "^0.0.9",

4
npm/packs/anchor-js/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/anchor-js",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"anchor-js": "^4.2.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/aspnetcore.mvc.ui.theme.basic/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/aspnetcore.mvc.ui.theme.basic",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.shared": "~3.0.0"
"@abp/aspnetcore.mvc.ui.theme.shared": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

30
npm/packs/aspnetcore.mvc.ui.theme.shared/package.json

@ -1,24 +1,24 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/aspnetcore.mvc.ui.theme.shared",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/aspnetcore.mvc.ui": "~3.0.0",
"@abp/bootstrap": "~3.0.0",
"@abp/bootstrap-datepicker": "~3.0.0",
"@abp/datatables.net-bs4": "~3.0.0",
"@abp/font-awesome": "~3.0.0",
"@abp/jquery-form": "~3.0.0",
"@abp/jquery-validation-unobtrusive": "~3.0.0",
"@abp/lodash": "~3.0.0",
"@abp/luxon": "~3.0.0",
"@abp/malihu-custom-scrollbar-plugin": "~3.0.0",
"@abp/select2": "~3.0.0",
"@abp/sweetalert": "~3.0.0",
"@abp/timeago": "~3.0.0",
"@abp/toastr": "~3.0.0"
"@abp/aspnetcore.mvc.ui": "~3.0.2",
"@abp/bootstrap": "~3.0.2",
"@abp/bootstrap-datepicker": "~3.0.2",
"@abp/datatables.net-bs4": "~3.0.2",
"@abp/font-awesome": "~3.0.2",
"@abp/jquery-form": "~3.0.2",
"@abp/jquery-validation-unobtrusive": "~3.0.2",
"@abp/lodash": "~3.0.2",
"@abp/luxon": "~3.0.2",
"@abp/malihu-custom-scrollbar-plugin": "~3.0.2",
"@abp/select2": "~3.0.2",
"@abp/sweetalert": "~3.0.2",
"@abp/timeago": "~3.0.2",
"@abp/toastr": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

2
npm/packs/aspnetcore.mvc.ui/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/aspnetcore.mvc.ui",
"publishConfig": {
"access": "public"

10
npm/packs/blogging/package.json

@ -1,14 +1,14 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/blogging",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/aspnetcore.mvc.ui.theme.shared": "~3.0.0",
"@abp/owl.carousel": "~3.0.0",
"@abp/prismjs": "~3.0.0",
"@abp/tui-editor": "~3.0.0"
"@abp/aspnetcore.mvc.ui.theme.shared": "~3.0.2",
"@abp/owl.carousel": "~3.0.2",
"@abp/prismjs": "~3.0.2",
"@abp/tui-editor": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

2
npm/packs/bootstrap-datepicker/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/bootstrap-datepicker",
"publishConfig": {
"access": "public"

4
npm/packs/bootstrap/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/bootstrap",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"bootstrap": "^4.5.0",
"bootstrap-v4-rtl": "4.4.1-2"
},

2
npm/packs/chart.js/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/chart.js",
"publishConfig": {
"access": "public"

4
npm/packs/clipboard/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/clipboard",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"clipboard": "^2.0.6"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/codemirror/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/codemirror",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"codemirror": "^5.54.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

2
npm/packs/core/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/core",
"publishConfig": {
"access": "public"

4
npm/packs/datatables.net-bs4/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/datatables.net-bs4",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/datatables.net": "~3.0.0",
"@abp/datatables.net": "~3.0.2",
"datatables.net-bs4": "^1.10.21"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/datatables.net/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/datatables.net",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"datatables.net": "^1.10.21"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

12
npm/packs/docs/package.json

@ -1,15 +1,15 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/docs",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/anchor-js": "~3.0.0",
"@abp/clipboard": "~3.0.0",
"@abp/malihu-custom-scrollbar-plugin": "~3.0.0",
"@abp/popper.js": "~3.0.0",
"@abp/prismjs": "~3.0.0"
"@abp/anchor-js": "~3.0.2",
"@abp/clipboard": "~3.0.2",
"@abp/malihu-custom-scrollbar-plugin": "~3.0.2",
"@abp/popper.js": "~3.0.2",
"@abp/prismjs": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

2
npm/packs/flag-icon-css/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/flag-icon-css",
"publishConfig": {
"access": "public"

4
npm/packs/font-awesome/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/font-awesome",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"@fortawesome/fontawesome-free": "^5.13.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/highlight.js/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/highlight.js",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0"
"@abp/core": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

4
npm/packs/jquery-form/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/jquery-form",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"jquery-form": "^4.3.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/jquery-validation-unobtrusive/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/jquery-validation-unobtrusive",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery-validation": "~3.0.0",
"@abp/jquery-validation": "~3.0.2",
"jquery-validation-unobtrusive": "^3.2.11"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/jquery-validation/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/jquery-validation",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"jquery-validation": "^1.19.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/jquery/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/jquery",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"jquery": "~3.5.1"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/jstree/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/jstree",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"jstree": "^3.3.9"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/lodash/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/lodash",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"lodash": "^4.17.15"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

2
npm/packs/luxon/package.json

@ -1,5 +1,5 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/luxon",
"publishConfig": {
"access": "public"

4
npm/packs/malihu-custom-scrollbar-plugin/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/malihu-custom-scrollbar-plugin",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"malihu-custom-scrollbar-plugin": "^3.1.5"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/markdown-it/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/markdown-it",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"markdown-it": "^11.0.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/owl.carousel/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/owl.carousel",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"owl.carousel": "^2.3.4"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/popper.js/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/popper.js",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"popper.js": "^1.16.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

6
npm/packs/prismjs/package.json

@ -1,12 +1,12 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/prismjs",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/clipboard": "~3.0.0",
"@abp/core": "~3.0.0",
"@abp/clipboard": "~3.0.2",
"@abp/core": "~3.0.2",
"prismjs": "^1.20.0"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/select2/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/select2",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"select2": "^4.0.13"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/signalr/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/signalr",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"@microsoft/signalr": "~3.1.5"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/sweetalert/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/sweetalert",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"sweetalert": "^2.1.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/timeago/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/timeago",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"timeago": "^1.6.7"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/toastr/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/toastr",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/jquery": "~3.0.0",
"@abp/jquery": "~3.0.2",
"toastr": "^2.1.4"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

10
npm/packs/tui-editor/package.json

@ -1,14 +1,14 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/tui-editor",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/codemirror": "~3.0.0",
"@abp/highlight.js": "~3.0.0",
"@abp/jquery": "~3.0.0",
"@abp/markdown-it": "~3.0.0",
"@abp/codemirror": "~3.0.2",
"@abp/highlight.js": "~3.0.2",
"@abp/jquery": "~3.0.2",
"@abp/markdown-it": "~3.0.2",
"tui-editor": "^1.4.10"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

4
npm/packs/uppy/package.json

@ -1,11 +1,11 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/uppy",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/core": "~3.0.0",
"@abp/core": "~3.0.2",
"uppy": "^1.16.1"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"

2
npm/packs/utils/package.json

@ -1,6 +1,6 @@
{
"name": "@abp/utils",
"version": "3.0.0",
"version": "3.0.2",
"scripts": {
"prepublish": "yarn install --ignore-scripts && node prepublish.js",
"ng": "ng",

6
npm/packs/virtual-file-explorer/package.json

@ -1,12 +1,12 @@
{
"version": "3.0.0",
"version": "3.0.2",
"name": "@abp/virtual-file-explorer",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@abp/clipboard": "~3.0.0",
"@abp/prismjs": "~3.0.0"
"@abp/clipboard": "~3.0.2",
"@abp/prismjs": "~3.0.2"
},
"gitHead": "bb4ea17d5996f01889134c138d00b6c8f858a431"
}

3
nupkg/common.ps1

@ -58,6 +58,7 @@ $projects = (
"framework/src/Volo.Abp.BackgroundWorkers.Quartz",
"framework/src/Volo.Abp.BlobStoring",
"framework/src/Volo.Abp.BlobStoring.FileSystem",
"framework/src/Volo.Abp.BlobStoring.Azure",
"framework/src/Volo.Abp.Caching",
"framework/src/Volo.Abp.Caching.StackExchangeRedis",
"framework/src/Volo.Abp.Castle.Core",
@ -250,4 +251,4 @@ $projects = (
"modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared",
"modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.EntityFrameworkCore",
"modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.MongoDB"
)
)

13
samples/MicroserviceDemo/DeployToKubernetes.sh

@ -1,13 +0,0 @@
#!/bin/bash
set -e
export SHELL="/bin/bash"
minikube start
eval $(minikube docker-env)
docker-compose -f docker-compose.yml -f docker-compose.migrations.yml -f docker-compose.override.yml build
cd ./k8s
kubectl create -f $(ls -x | grep .yaml | grep -v deployment | tr " \t\n\r" "," | sed 's/.$//')
kubectl create -f $(ls -x | grep .yaml | grep deployment | tr " \t\n\r" "," | sed 's/.$//')

208
samples/MicroserviceDemo/MicroserviceDemo.sln

@ -1,208 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29609.76
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "microservices", "microservices", "{3B26D176-390B-4F51-BE52-E9B422C28A88}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "applications", "applications", "{8F6834D7-E6FA-4A04-83BB-955F68EA0A0A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{818134CC-2F7F-41B9-ACA6-87F0650F5D52}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "product", "product", "{8FFAECCC-B4A6-4441-AD10-379ADEDD5A19}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{D1526262-55E0-43F1-9EF1-C6095E76A9E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Domain.Shared", "modules\product\src\ProductManagement.Domain.Shared\ProductManagement.Domain.Shared.csproj", "{44A448CC-D8DD-4AA5-861A-78186FC5CE69}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Domain", "modules\product\src\ProductManagement.Domain\ProductManagement.Domain.csproj", "{65593638-9904-424B-831F-F5215EC4312B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Application.Contracts", "modules\product\src\ProductManagement.Application.Contracts\ProductManagement.Application.Contracts.csproj", "{217CD5A1-182F-4D8D-88CA-16DC1EA8525A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Application", "modules\product\src\ProductManagement.Application\ProductManagement.Application.csproj", "{66B2E371-2495-4E76-A6F9-540125C5FB37}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.EntityFrameworkCore", "modules\product\src\ProductManagement.EntityFrameworkCore\ProductManagement.EntityFrameworkCore.csproj", "{B22DCAA4-FC9E-4F06-B1BA-41169341B215}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.HttpApi", "modules\product\src\ProductManagement.HttpApi\ProductManagement.HttpApi.csproj", "{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.HttpApi.Client", "modules\product\src\ProductManagement.HttpApi.Client\ProductManagement.HttpApi.Client.csproj", "{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Web", "modules\product\src\ProductManagement.Web\ProductManagement.Web.csproj", "{4A8594CB-8877-412B-9C80-90A5D3366095}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.TestBase", "modules\product\test\ProductManagement.TestBase\ProductManagement.TestBase.csproj", "{4D3244F4-487F-4CED-A8C9-E88723EB835A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.EntityFrameworkCore.Tests", "modules\product\test\ProductManagement.EntityFrameworkCore.Tests\ProductManagement.EntityFrameworkCore.Tests.csproj", "{1FA2B816-7841-44B0-931C-D4F84DA7E146}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Domain.Tests", "modules\product\test\ProductManagement.Domain.Tests\ProductManagement.Domain.Tests.csproj", "{BDCDBC2D-C05B-4A18-A698-86525E3EFC95}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductManagement.Application.Tests", "modules\product\test\ProductManagement.Application.Tests\ProductManagement.Application.Tests.csproj", "{B6F469F0-FB01-4A60-B6A6-D4127907E3B6}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gateways", "gateways", "{617037ED-34E3-49A2-8958-BE2013E2D151}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicWebSiteGateway.Host", "gateways\PublicWebSiteGateway.Host\PublicWebSiteGateway.Host.csproj", "{D48F6DDC-4AFC-4554-86B1-7763C0679B59}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BackendAdminAppGateway.Host", "gateways\BackendAdminAppGateway.Host\BackendAdminAppGateway.Host.csproj", "{BD4ABDEA-2F09-4CB4-855F-B06C307A352E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InternalGateway.Host", "gateways\InternalGateway.Host\InternalGateway.Host.csproj", "{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BloggingService.Host", "microservices\BloggingService.Host\BloggingService.Host.csproj", "{79B45294-8352-4B19-824C-F5B84E52725A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IdentityService.Host", "microservices\IdentityService.Host\IdentityService.Host.csproj", "{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProductService.Host", "microservices\ProductService.Host\ProductService.Host.csproj", "{63E38ABD-0B26-44E5-84CA-557D3DFC9506}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthServer.Host", "applications\AuthServer.Host\AuthServer.Host.csproj", "{F9F6CCC2-5985-4853-BBA1-A85D60373DBC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BackendAdminApp.Host", "applications\BackendAdminApp.Host\BackendAdminApp.Host.csproj", "{2199D857-C926-4948-A7F7-A11E344F90AA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleClientDemo", "applications\ConsoleClientDemo\ConsoleClientDemo.csproj", "{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PublicWebSite.Host", "applications\PublicWebSite.Host\PublicWebSite.Host.csproj", "{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TenantManagementService.Host", "microservices\TenantManagementService.Host\TenantManagementService.Host.csproj", "{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{2B3B460C-0293-44A1-BEF4-91A778CE73CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MsDemo.Shared", "shared\MsDemo.Shared\MsDemo.Shared.csproj", "{D4549E30-18CC-4157-B994-C0097216C2C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{44A448CC-D8DD-4AA5-861A-78186FC5CE69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44A448CC-D8DD-4AA5-861A-78186FC5CE69}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44A448CC-D8DD-4AA5-861A-78186FC5CE69}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44A448CC-D8DD-4AA5-861A-78186FC5CE69}.Release|Any CPU.Build.0 = Release|Any CPU
{65593638-9904-424B-831F-F5215EC4312B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65593638-9904-424B-831F-F5215EC4312B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65593638-9904-424B-831F-F5215EC4312B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65593638-9904-424B-831F-F5215EC4312B}.Release|Any CPU.Build.0 = Release|Any CPU
{217CD5A1-182F-4D8D-88CA-16DC1EA8525A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{217CD5A1-182F-4D8D-88CA-16DC1EA8525A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{217CD5A1-182F-4D8D-88CA-16DC1EA8525A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{217CD5A1-182F-4D8D-88CA-16DC1EA8525A}.Release|Any CPU.Build.0 = Release|Any CPU
{66B2E371-2495-4E76-A6F9-540125C5FB37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66B2E371-2495-4E76-A6F9-540125C5FB37}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66B2E371-2495-4E76-A6F9-540125C5FB37}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66B2E371-2495-4E76-A6F9-540125C5FB37}.Release|Any CPU.Build.0 = Release|Any CPU
{B22DCAA4-FC9E-4F06-B1BA-41169341B215}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B22DCAA4-FC9E-4F06-B1BA-41169341B215}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B22DCAA4-FC9E-4F06-B1BA-41169341B215}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B22DCAA4-FC9E-4F06-B1BA-41169341B215}.Release|Any CPU.Build.0 = Release|Any CPU
{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5}.Release|Any CPU.Build.0 = Release|Any CPU
{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8}.Release|Any CPU.Build.0 = Release|Any CPU
{4A8594CB-8877-412B-9C80-90A5D3366095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A8594CB-8877-412B-9C80-90A5D3366095}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A8594CB-8877-412B-9C80-90A5D3366095}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A8594CB-8877-412B-9C80-90A5D3366095}.Release|Any CPU.Build.0 = Release|Any CPU
{4D3244F4-487F-4CED-A8C9-E88723EB835A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D3244F4-487F-4CED-A8C9-E88723EB835A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D3244F4-487F-4CED-A8C9-E88723EB835A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D3244F4-487F-4CED-A8C9-E88723EB835A}.Release|Any CPU.Build.0 = Release|Any CPU
{1FA2B816-7841-44B0-931C-D4F84DA7E146}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FA2B816-7841-44B0-931C-D4F84DA7E146}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FA2B816-7841-44B0-931C-D4F84DA7E146}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FA2B816-7841-44B0-931C-D4F84DA7E146}.Release|Any CPU.Build.0 = Release|Any CPU
{BDCDBC2D-C05B-4A18-A698-86525E3EFC95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDCDBC2D-C05B-4A18-A698-86525E3EFC95}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDCDBC2D-C05B-4A18-A698-86525E3EFC95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDCDBC2D-C05B-4A18-A698-86525E3EFC95}.Release|Any CPU.Build.0 = Release|Any CPU
{B6F469F0-FB01-4A60-B6A6-D4127907E3B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B6F469F0-FB01-4A60-B6A6-D4127907E3B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B6F469F0-FB01-4A60-B6A6-D4127907E3B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B6F469F0-FB01-4A60-B6A6-D4127907E3B6}.Release|Any CPU.Build.0 = Release|Any CPU
{D48F6DDC-4AFC-4554-86B1-7763C0679B59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D48F6DDC-4AFC-4554-86B1-7763C0679B59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D48F6DDC-4AFC-4554-86B1-7763C0679B59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D48F6DDC-4AFC-4554-86B1-7763C0679B59}.Release|Any CPU.Build.0 = Release|Any CPU
{BD4ABDEA-2F09-4CB4-855F-B06C307A352E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD4ABDEA-2F09-4CB4-855F-B06C307A352E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD4ABDEA-2F09-4CB4-855F-B06C307A352E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD4ABDEA-2F09-4CB4-855F-B06C307A352E}.Release|Any CPU.Build.0 = Release|Any CPU
{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2}.Release|Any CPU.Build.0 = Release|Any CPU
{79B45294-8352-4B19-824C-F5B84E52725A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{79B45294-8352-4B19-824C-F5B84E52725A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{79B45294-8352-4B19-824C-F5B84E52725A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{79B45294-8352-4B19-824C-F5B84E52725A}.Release|Any CPU.Build.0 = Release|Any CPU
{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B}.Release|Any CPU.Build.0 = Release|Any CPU
{63E38ABD-0B26-44E5-84CA-557D3DFC9506}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63E38ABD-0B26-44E5-84CA-557D3DFC9506}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63E38ABD-0B26-44E5-84CA-557D3DFC9506}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63E38ABD-0B26-44E5-84CA-557D3DFC9506}.Release|Any CPU.Build.0 = Release|Any CPU
{F9F6CCC2-5985-4853-BBA1-A85D60373DBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F9F6CCC2-5985-4853-BBA1-A85D60373DBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F9F6CCC2-5985-4853-BBA1-A85D60373DBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F9F6CCC2-5985-4853-BBA1-A85D60373DBC}.Release|Any CPU.Build.0 = Release|Any CPU
{2199D857-C926-4948-A7F7-A11E344F90AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2199D857-C926-4948-A7F7-A11E344F90AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2199D857-C926-4948-A7F7-A11E344F90AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2199D857-C926-4948-A7F7-A11E344F90AA}.Release|Any CPU.Build.0 = Release|Any CPU
{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1}.Release|Any CPU.Build.0 = Release|Any CPU
{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC}.Release|Any CPU.Build.0 = Release|Any CPU
{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61}.Release|Any CPU.Build.0 = Release|Any CPU
{D4549E30-18CC-4157-B994-C0097216C2C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4549E30-18CC-4157-B994-C0097216C2C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4549E30-18CC-4157-B994-C0097216C2C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4549E30-18CC-4157-B994-C0097216C2C8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8FFAECCC-B4A6-4441-AD10-379ADEDD5A19} = {818134CC-2F7F-41B9-ACA6-87F0650F5D52}
{F84AC200-1E5A-4FC3-9407-FB2FF527EDA8} = {8FFAECCC-B4A6-4441-AD10-379ADEDD5A19}
{D1526262-55E0-43F1-9EF1-C6095E76A9E2} = {8FFAECCC-B4A6-4441-AD10-379ADEDD5A19}
{44A448CC-D8DD-4AA5-861A-78186FC5CE69} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{65593638-9904-424B-831F-F5215EC4312B} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{217CD5A1-182F-4D8D-88CA-16DC1EA8525A} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{66B2E371-2495-4E76-A6F9-540125C5FB37} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{B22DCAA4-FC9E-4F06-B1BA-41169341B215} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{CFAD2A4B-445A-4EA3-8AF1-C054ECC2DFC5} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{4A1C1CF9-74A6-43F9-876C-BB0083EC6FB8} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{4A8594CB-8877-412B-9C80-90A5D3366095} = {F84AC200-1E5A-4FC3-9407-FB2FF527EDA8}
{4D3244F4-487F-4CED-A8C9-E88723EB835A} = {D1526262-55E0-43F1-9EF1-C6095E76A9E2}
{1FA2B816-7841-44B0-931C-D4F84DA7E146} = {D1526262-55E0-43F1-9EF1-C6095E76A9E2}
{BDCDBC2D-C05B-4A18-A698-86525E3EFC95} = {D1526262-55E0-43F1-9EF1-C6095E76A9E2}
{B6F469F0-FB01-4A60-B6A6-D4127907E3B6} = {D1526262-55E0-43F1-9EF1-C6095E76A9E2}
{D48F6DDC-4AFC-4554-86B1-7763C0679B59} = {617037ED-34E3-49A2-8958-BE2013E2D151}
{BD4ABDEA-2F09-4CB4-855F-B06C307A352E} = {617037ED-34E3-49A2-8958-BE2013E2D151}
{EAE8C1F5-C8D0-4132-A8CB-D374F2C363E2} = {617037ED-34E3-49A2-8958-BE2013E2D151}
{79B45294-8352-4B19-824C-F5B84E52725A} = {3B26D176-390B-4F51-BE52-E9B422C28A88}
{6FDF254B-DEAF-4336-8F70-9E360E3E5B8B} = {3B26D176-390B-4F51-BE52-E9B422C28A88}
{63E38ABD-0B26-44E5-84CA-557D3DFC9506} = {3B26D176-390B-4F51-BE52-E9B422C28A88}
{F9F6CCC2-5985-4853-BBA1-A85D60373DBC} = {8F6834D7-E6FA-4A04-83BB-955F68EA0A0A}
{2199D857-C926-4948-A7F7-A11E344F90AA} = {8F6834D7-E6FA-4A04-83BB-955F68EA0A0A}
{BB8FA269-460D-42BE-90A0-E97D6A3FDEB1} = {8F6834D7-E6FA-4A04-83BB-955F68EA0A0A}
{29A3A4EF-DEC4-4E43-B6B8-D565667F85EC} = {8F6834D7-E6FA-4A04-83BB-955F68EA0A0A}
{3E1DDEDA-A897-470F-81C2-5A3AFA6D0B61} = {3B26D176-390B-4F51-BE52-E9B422C28A88}
{D4549E30-18CC-4157-B994-C0097216C2C8} = {2B3B460C-0293-44A1-BEF4-91A778CE73CE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {37474F0D-2E52-4D2F-B39B-7FE3FF31B4EC}
EndGlobalSection
EndGlobal

4
samples/MicroserviceDemo/README.md

@ -1,4 +0,0 @@
# Microservice Demo Solution
This sample aims to demonstrate a simple yet complete microservice solution. See the [documentation](https://abp.io/documents/abp/latest/Samples/Microservice-Demo).

2
samples/MicroserviceDemo/_run/01_AuthServer.ps1

@ -1,2 +0,0 @@
cd ../applications/AuthServer.Host
dotnet run

2
samples/MicroserviceDemo/_run/02_IdentityService.ps1

@ -1,2 +0,0 @@
cd ../microservices/IdentityService.Host
dotnet run

2
samples/MicroserviceDemo/_run/03_BloggingService.ps1

@ -1,2 +0,0 @@
cd ../microservices/BloggingService.Host
dotnet run

2
samples/MicroserviceDemo/_run/04_ProductService.ps1

@ -1,2 +0,0 @@
cd ../microservices/ProductService.Host
dotnet run

2
samples/MicroserviceDemo/_run/05_InternalGateway.ps1

@ -1,2 +0,0 @@
cd ../gateways/InternalGateway.Host
dotnet run

2
samples/MicroserviceDemo/_run/06_BackendAdminAppGateway.ps1

@ -1,2 +0,0 @@
cd ../gateways/BackendAdminAppGateway.Host
dotnet run

2
samples/MicroserviceDemo/_run/07_PublicWebSiteGateway.ps1

@ -1,2 +0,0 @@
cd ../gateways/PublicWebSiteGateway.Host
dotnet run

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

Loading…
Cancel
Save