diff --git a/Directory.Build.props b/Directory.Build.props index d888f2a60a..6dd78ec400 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,13 +5,13 @@ 5.0.* - 16.8.3 + 16.9.1 4.2.2 - 4.0.1 + 4.0.3 2.4.1 @@ -23,7 +23,7 @@ 2.4.3 - 2.2.14 + 3.0.0 \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index 36e164942c..5167f46080 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -255,14 +255,22 @@ "ProjectDownloads": "Project Downloads", "ShowProjectDownloadsOfOrganization": "Project Downloads", "ShowAuditLogsOfOrganization": "Audit Logs", - "Enum:EntityChangeType:0": "Crated", + "Enum:EntityChangeType:0": "Created", "Enum:EntityChangeType:1": "Updated", "Enum:EntityChangeType:2": "Deleted", "TenantId": "Tenant ID", "ChangeTime": "Change time", "EntityTypeFullName": "Entity type full name", - "AuditLogsOf{0}Organization": "Audit logs of \"{0}\" organization", + "AuditLogsFor{0}Organization": "Audit logs for \"{0}\" organization", "Permission:EntityChange": "Entity Change", - "Permission:ProjectDownload": "Project Download" + "Permission:ProjectDownload": "Project Download", + "Permission:PaymentRequest": "Payment Request", + "CreatorEmailAddress": "Creator email address", + "EmailSendDate": "Email send date", + "PaymentRequestsFor{0}Organization": "Payment requests for \"{0}\" organization", + "PaymentDetails": "Payment Details", + "PaymentProduct": "Payment Product", + "ProductName": "Product Name", + "Code": "Code" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json index acec74804e..d6f086c1f6 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/tr.json @@ -204,14 +204,22 @@ "ProjectDownloads": "Proje İndirmeleri", "ShowProjectDownloadsOfOrganization": "Proje İndirmeleri", "ShowAuditLogsOfOrganization": "Denetim Günlükleri", - "Enum:EntityChangeType:0": "Crated", + "Enum:EntityChangeType:0": "Oluşturuldu", "Enum:EntityChangeType:1": "Güncellendi", "Enum:EntityChangeType:2": "Silindi", "TenantId": "Kiracı Kimliği", "ChangeTime": "Değişiklik Zamanı", "EntityTypeFullName": "Varlık türü tam adı", - "AuditLogsOf{0}Organization": "\"{0}\" kuruluşunun denetim günlükleri", + "AuditLogsFor{0}Organization": "\"{0}\" kuruluşu için denetim günlükleri", "Permission:EntityChange": "Varlık Değişikliği", - "Permission:ProjectDownload": "Proje Indirme" + "Permission:ProjectDownload": "Proje İndirme", + "Permission:PaymentRequest": "Ödeme isteği", + "CreatorEmailAddress": "Oluşturan kişinin e-posta adresi", + "EmailSendDate": "E-posta gönderme tarihi", + "PaymentRequestsFor{0}Organization": "\"{0}\" kuruluşu için ödeme istekleri", + "PaymentDetails": "Ödeme Detayları", + "PaymentProduct": "Ödeme Ürünü", + "ProductName": "Ürün İsmi", + "Code": "Kod" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json index 83d51d35da..46ba210b74 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json @@ -245,8 +245,16 @@ "TenantId": "租户ID", "ChangeTime": "变更时间", "EntityTypeFullName": "实体类型全名", - "AuditLogsOf{0}Organization": "\"{0}\" 组织的审核日志", + "AuditLogsFor{0}Organization": "\"{0}\" 组织的审核日志", "Permission:EntityChange": "实体变更", - "Permission:ProjectDownload": "项目下载" + "Permission:ProjectDownload": "项目下载", + "Permission:PaymentRequest": "支付请求", + "CreatorEmailAddress": "创作者的电子邮件地址", + "EmailSendDate": "电子邮件发送日期", + "PaymentRequestsFor{0}Organization": "\"{0}\" 组织的付款请求", + "PaymentDetails": "付款详情", + "PaymentProduct": "付款产品", + "ProductName": "产品名称", + "Code": "代码" } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json index 3e6173cff3..9b30514f03 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json @@ -128,13 +128,13 @@ "YourFullName": "Your full name", "EmailField": "E-mail Address", "YourEmailAddress": "Your e-mail address", - "HowMayWeHelpYou": "How may we help you", + "HowMayWeHelpYou": "How may we help you?", "SendMessage": "Send Message", "Success": "Success", - "WeWillReplyYou.": "Your message is sent! We will reply you in a short time.", + "WeWillReplyYou": "We received your message and will be in touch shortly.", "GoHome": "Go Home", "CreateLiveDemo": "Create Live Demo", - "RegisterToTheNewsletter": "Register to the newsletter to get information on happenings about ABP.IO, like new releases.", + "RegisterToTheNewsletter": "Register for the newsletter to receive information regarding ABP.IO, including new releases etc.", "EnterYourEmailOrLogin": "Enter your e-mail address to create your demo or Login using your existing account.", "ApplicationTemplate": "Application Template", "ApplicationTemplateExplanation": "Application startup template is used to create a new web application.", @@ -287,6 +287,8 @@ "PrivateTicketEmailSupport": "Private ticket & email support", "BuyNow": "Buy Now", "PayViaAmexCard": "How can I pay via my AMEX card?", - "PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to the security measures. In this case, you can pay through the alternative payment gateway '2Checkout'." + "PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to the security measures. In this case, you can pay through the alternative payment gateway '2Checkout'.", + "ThankYou": "Thank you", + "InvalidReCaptchaErrorMessage": "There was an error verifying reCAPTCHA. Please try again." } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json index 90db761f1b..e49c82c6fd 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json @@ -30,6 +30,7 @@ "UserNameNotFound": "{0} kullanıcı adı ile bir kullanıcı yok", "SuccessfullyAddedToNewsletter": "Bültenimize abone olduğunuz için teşekkürler!", "MyProfile": "Profilim", - "EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz" + "EmailNotValid": "Lütfen uygun bir e-posta adresi giriniz", + "InvalidReCaptchaErrorMessage": "ReCAPTCHA doğrulanırken hata oluştu, lütfen tekrar deneyin." } } \ No newline at end of file diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json index 55c1d98bab..789e377e9d 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json @@ -131,7 +131,7 @@ "HowMayWeHelpYou": "我们如何帮助你", "SendMessage": "发送消息", "Success": "成功", - "WeWillReplyYou.": "你的消息已经发送! 我们会在短时间内给你答复.", + "WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.", "GoHome": "回到主页面", "CreateLiveDemo": "创建在线演示", "RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.", @@ -287,6 +287,7 @@ "PrivateTicketEmailSupport": "私有票和email支持", "BuyNow": "现在购买", "PayViaAmexCard": "我如何通过我的AMEX卡付款?", - "PayViaAmexCardDescription": "由于安全措施,默认付款网关“ Iyzico”可能会拒绝某些AMEX信用卡。 在这种情况下,您可以通过备用付款网关“ 2Checkout”付款。" + "PayViaAmexCardDescription": "由于安全措施,默认付款网关“ Iyzico”可能会拒绝某些AMEX信用卡。 在这种情况下,您可以通过备用付款网关“ 2Checkout”付款。", + "InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试。" } } diff --git a/configureawait.props b/configureawait.props index 791c3e2a57..8b0b7f5933 100644 --- a/configureawait.props +++ b/configureawait.props @@ -1,7 +1,7 @@ - + All runtime; build; native; contentfiles; analyzers diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/POST.md b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/POST.md new file mode 100644 index 0000000000..50aab3559b --- /dev/null +++ b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/POST.md @@ -0,0 +1,139 @@ +# ABP Commercial 4.3 RC Has Been Published + +ABP Commercial version 4.3 RC (Release Candidate) has been published alongside ABP Framework 4.3. RC (TODO: link). I will introduce the new features in this blog post. Here, a list of highlights for this release; + +* The **microservice starter template** is getting more mature. We've also added a **service template** to add new microservices to the solution. +* New option for the application starter template to have a **separate database schema for tenant databases**. +* New **Forms** module to create surveys +* **Enable/disable modules** per edition/tenant. +* **Lepton theme** and **Account module**'s source codes are available with the Team License. + +Here, some other features already covered in the ABP Framework announcement, but worth mentioning here since they are also implemented for the ABP Commercial; + +* **Blazor UI server-side** support + +* **Email setting** management UI +* **Module extensibility** system is now available for the **Blazor UI** too. + +> This post doesn't cover the features and changes done on the ABP Framework side. Please also see the **ABP Framework 4.3. RC blog post** (TODO: link). + +## The Migration Guide + +**This upgrade requires some manual work documented in [the migration guide](https://docs.abp.io/en/commercial/4.3/migration-guides/v4_3).** Please read the guide carefully. Even if your application doesn't break on upgrade, you should apply the changes to avoid future release problems. + +## What's New With The ABP Commercial 4.3 + +### The Microservice Starter Template + +We'd introduced an initial version of the [microservice starter template](https://docs.abp.io/en/commercial/4.3/startup-templates/microservice/index) in the [previous version](https://blog.abp.io/abp/ABP-IO-Platform-v4-2-RC-Has-Been-Released). It is getting more mature with this release. We've made a lot of improvements and changes, including; + +* New **"service" template** to add new microservices for the solution. It still requires some manual work to integrate to other services and gateways; however, it makes progress very easy and straightforward. +* Added [Tye](https://github.com/dotnet/tye) configuration to develop and test the solution easier. +* Added [Prometheus](https://prometheus.io/), [Grafana](https://grafana.com/) integrations for monitoring the solution. +* **Automatic database migrations**. Every microservice automatically checks and migrates/seeds its database on startup (concurrency issues are resolved for multiple instances). For multi-tenant systems, tenant databases are also upgraded by the queue. +* For multi-tenant systems, **databases are being created on the fly** for new tenants with separate connection strings. +* Created **separate solution (`.sln`) file** for each microservice, gateway, and application. In this way, you can focus on what you are working on. The main (roof) solution file only includes the executable projects in these solutions. +* All microservices are converted to the standard **layered module structure**, making it easier to align with ABP application development practices. + +After this release, **we will be preparing microservice development guides** based on this startup solution. + +### Separate Tenant Schema + +ABP's multi-tenancy system allows to the creation of dedicated databases for tenants. However, the application startup solution comes with a single database migration path; hence it has a single database schema. As a result, tenant databases have some host-related tables. These tables are not used for tenants, and they are always empty. However, their existence may disturb us as a clean developer. + +With this release, the application startup template provides an option to address this problem. So, if you want, you can have a separate migration path for tenant databases. Of course, this has a cost; You will have two DbContexts for migration purposes, bringing additional complexity to your solution. We've done our best to reduce this complexity and added a README file into the migration assembly. If you prefer this approach, please check that README file. + +You can specify the new `--separate-tenant-schema` parameter while you are creating a new solution using the [ABP CLI](https://docs.abp.io/en/abp/4.3/CLI): + +````bash +abp new Acme.BookStore --separate-tenant-schema +```` + +If you prefer the [ABP Suite](https://docs.abp.io/en/commercial/latest/abp-suite/create-solution) to create solutions, you can check the *Separated tenant schema* option. + +![abp-suite-separate-tenant-schema](abp-suite-separate-tenant-schema.png) + +### Creating Tenant Databases On The Fly + +With this release, the separate tenant database feature becomes more mature. When you create a new tenant with specifying a connection string, the **new database is automatically created** with all the tables and the initial seed data if available. So, tenants can immediately start to use the new database. With this change, tenant connection string textboxes come in the tenant creation modal: + +![new-tenant-modal](new-tenant-modal.png) + +Besides, we've added an "**Apply database migrations**" action to the tenant management UI to manually trigger the database creation & migration in case you have a problem with automatic migration: + +![tenant-db-migrate](tenant-db-migrate.png) + +Automatic migration only tries one time. If it fails, it writes the exception log and discards this request. For example, this can happen if the connection string is wrong or the database server is not available. In this case, you can manually retry with this action. + +> Note that this feature requires to **make changes in your solution**, if you upgrade from an older version. Because the tenant database creation and migration code are located in the application startup template. See the [version 4.3 migration guide](https://docs.abp.io/en/commercial/4.3/migration-guides/v4_3) for details. + +### New Module: CMS Kit + +CMS Kit module initial version has been released with this version. As stated in the ABP Framework 4.3 announcement post (TODO: link), it should be considered premature for now. + +For ABP Commercial application startup template, we are providing an option to include the CMS Kit into the solution while creating new solutions: + +![cms-kit-selection](cms-kit-selection.png) + +It is available only if you select the *Public web site* option. Once you include CMS Kit, a *Cms* item is shown on the menu: + +![cms-kit-menu](cms-kit-menu.png) + +Each CMS Kit feature can be individually enabled/disabled, using the global feature system. Once you disable a feature, it becomes completely invisible; even the related tables are not included in your database. + +CMS Kit features are separated into two categories: Open source (free) features and pro (commercial) features. For now, only newsletter and contact form features are commercial. By the time, we will add more free and commercial features. + +> We will create a separate blog post for the CMS Kit module, so I keep it short. + +### New Module: Forms + +*Forms* is a new module that is being introduced with this version. It looks like the Google Forms application; You dynamically create forms on the UI and send them to people to answer. Then you can get statistics/report and export answers to a CSV file. + +Forms module currently supports the following question types; + +* **Free text** +* Selecting a **single option** from a **dropdown** list or a **radio button** list +* **Multiple choice**: Selecting multiple options from a checkbox list + +**Screenshot: editing form and questions - view responses** + +![forms-edit-report](forms-edit-report.png) + +**Screenshot: answering to the form** + +![forms-answer](forms-answer.png) + + + +### Team License Source Code for Modules + +Team License users can't access the source code of modules and themes as a license restriction. You have to buy a Business or Enterprise license to download any module/theme's full source code. However, we got a lot of feedback from the Team License owners on the source code of the account module and the lepton theme. We see that customization of these two modules is highly necessary for most of our customers. + +With this version, we decided to allow Team License holders to download the source code of the **Account Module** and the **Lepton Theme** to freely customize them based on their requirements. + +You can **Replace these modules with their source code** using the ABP Suite: + +![account-lepton-source](account-lepton-source.png) + +Remember that; when you include the source code in your solution, it is your responsibility to upgrade them when we release new versions (while you don't have to upgrade them). + +### Lepton Theme Public Website Layout + +We'd added a public website application in the application starter template in the previous versions. It was using the public website layout of the Lepton Theme. We realized that the layout of this application is customized or completely changed in most of the solutions. So, with this version, the layout is included inside the application in the downloaded solution. You can freely change it. Before, you had to download it separately and include it in your solution manually. + +### Enable/Disable Modules + +With this release, all modules can be enabled/disabled per edition/tenant. You can allow/disallow modules when you click *Features* action for an edition or tenant: + +![enable-disable-features](enable-disable-features.png) + +### Other Features/Changes + +* ABP Suite now supports defining *required* navigation properties on code generation. +* **Blazor server-side** (with tiered option) is added for the application and microservice starter templates. +* An **"Email"** tab has been added to the Settings page to configure the email settings. + +## Feedback + +Please check out the ABP Commercial 4.3 RC to help us to release a more stable version. **The planned release date for the 4.3.0 final version is April 15, 2021**. + diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/abp-suite-separate-tenant-schema.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/abp-suite-separate-tenant-schema.png new file mode 100644 index 0000000000..ae80e744f4 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/abp-suite-separate-tenant-schema.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/account-lepton-source.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/account-lepton-source.png new file mode 100644 index 0000000000..befdc83eb4 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/account-lepton-source.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-menu.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-menu.png new file mode 100644 index 0000000000..e8120946f4 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-menu.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-selection.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-selection.png new file mode 100644 index 0000000000..47552a3e25 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/cms-kit-selection.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/enable-disable-features.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/enable-disable-features.png new file mode 100644 index 0000000000..9718c806f7 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/enable-disable-features.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-answer.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-answer.png new file mode 100644 index 0000000000..0a3c3318d6 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-answer.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-edit-report.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-edit-report.png new file mode 100644 index 0000000000..670e5883b9 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/forms-edit-report.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/new-tenant-modal.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/new-tenant-modal.png new file mode 100644 index 0000000000..ff7777dfe8 Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/new-tenant-modal.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/tenant-db-migrate.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/tenant-db-migrate.png new file mode 100644 index 0000000000..59efac5add Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Commercial Preview/tenant-db-migrate.png differ diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md b/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md index 4ffeb34aee..cfb9bf0eed 100644 --- a/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md +++ b/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/POST.md @@ -1,6 +1,6 @@ # ABP Framework 4.3 RC Has Been Published -We are super excited to announce the ABP Framework 4.3 RC (Release Candidate). Here, a list of highlights for this release; +We are super excited to announce the ABP Framework 4.3 RC (Release Candidate). Here, a list of highlights of this release; * **CMS Kit** module initial release. * **Blazor UI server-side** support. @@ -9,21 +9,26 @@ We are super excited to announce the ABP Framework 4.3 RC (Release Candidate). H * **Volo.Abp.EntityFrameworkCore.Oracle** package is now compatible with .NET 5. * CLI support to easily add the **Basic Theme** into the solution. * New **IInitLogger** service to write logs before dependency injection phase completed. -* Infrastructure for **multi-lingual entities**. -Beside the new features above, we've done many performance improvements, enhancements and bug fixes on the current features. See the [4.3 milestone](https://github.com/abpframework/abp/milestone/49) on GitHub for all changes made on this version. +Besides the new features above, we've done many performance improvements, enhancements and bug fixes on the current features. See the [4.3 milestone](https://github.com/abpframework/abp/milestone/49) on GitHub for all changes made on this version. -This version was a big development journey for us; [150+ issues](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3A4.3-preview) resolved, [260+ PRs](https://github.com/abpframework/abp/pulls?q=is%3Aopen+is%3Apr+milestone%3A4.3-preview) merged and 1,600+ commits done only in the [main framework repository](https://github.com/abpframework/abp). **Thanks to the ABP Framework team and all the contributors.** +This version was a big development journey for us; [~160 issues](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3A4.3-preview) resolved, [~300 PRs](https://github.com/abpframework/abp/pulls?q=is%3Aopen+is%3Apr+milestone%3A4.3-preview) merged and **~1,700 commits** done only in the [main framework repository](https://github.com/abpframework/abp). **Thanks to the ABP Framework team and all the contributors.** + +> ABP Commercial 4.3 RC has also been published. We will write a separate blog post for it. ## The Migration Guide -We normally don't make breaking changes in feature versions. However, this version has some small **breaking changes** mostly related to Blazor UI WebAssembly & Server separation. **Please check the [migration guide](https://docs.abp.io/en/abp/4.3/Migration-Guides/Abp-4_3) before starting with the version 4.3**. +We normally don't make breaking changes in feature versions. However, this version has some small **breaking changes** mostly related to Blazor UI WebAssembly & Server separation. **Please check the [migration guide](https://docs.abp.io/en/abp/4.3/Migration-Guides/Abp-4_3) while upgrading to version 4.3**. + +## Known Issues + +Some minor issues will be fixed in the stable release. You can see the known issues [here](https://github.com/abpframework/abp/issues?q=is%3Aopen+is%3Aissue+milestone%3A4.3-final). ## Get Started With The 4.3 RC -If you want to try the version 4.3 today, follow the steps below; +If you want to try version 4.3 today, follow the steps below; -1) **Upgrade** the ABP CLI to the version `4.3.0-rc.1` using a command line terminal: +1) **Upgrade** the ABP CLI to the version `4.3.0-rc.1` using a command-line terminal: ````bash dotnet tool update Volo.Abp.Cli -g --version 4.3.0-rc.1 @@ -49,45 +54,136 @@ See the [ABP CLI documentation](https://docs.abp.io/en/abp/4.3/CLI) for all the ### CMS Kit -CMS Kit was a module we were working for the last couple of months. It is usable now and we are releasing the initial version with this release. +CMS (Content Management System) Kit was a module we worked on for the last couple of months. It is usable now, and we are releasing the initial version with this release. We are considering this module as pre-mature. It will be improved in the next versions. The goal to provide a flexible and extensible CMS infrastructure to .NET community. It currently has the following features; + +* **Pages**: Used to create UI pages with a Markdown + WYSIWYG editor. Once you create a page, it becomes available via URL like `/pages/my-page-url`. +* **Blog**: A built-in blog system that supports multiple blogs with blog posts. +* **Comments**: Allows users to write comments under contents. It is used for blog posts. +* **Tags**: To add tag feature to any content/entity. It is used for blog posts. +* **Reactions**: Allows users to react to content via emojis, like a smile, upvote, downvote, etc. +* **Rating**: This component is used to rate content by users. + +All features are separately usable. For example, you can create an image gallery and reuse the Comments and Tags features for the images. You can enable/disable features individually using the [Global Features System](https://docs.abp.io/en/abp/4.3/global-features). + +> We will create a separate blog post for the CMS Kit module, so I keep it short. ### Blazor Server Side -TODO +We'd implemented Blazor WebAssembly before. With version 4.3, we have the Blazor Server-Side option too. All the current functionalities are available to the Blazor Server. + +You can select Blazor Server as the UI type while creating a new solution. + +**Example:** + +````bash +abp new Acme.BookStore -u blazor-server +```` + +If you write `blazor` as the UI type, it will create Blazor WebAssembly just as before. + +> You can also select the Blazor Server on the [get started](https://abp.io/get-started) page. + +Blazor Server applications are mixed applications; You can mix the server-side MVC / Razor Pages with the Blazor SPA. This brings an interesting opportunity: MVC / Razor Pages modules can work seamlessly in the Blazor Server applications. For example, the CMS Kit module has no Blazor UI yet, but you can use its MVC UI inside your Blazor Server application. + +> Blazor Server UI has a `--tiered` option just [like](https://docs.abp.io/en/abp/latest/Startup-Templates/Application#tiered-structure) the MVC / Razor Pages UI. This can be used to separate the HTTP API server from the UI server (UI application doesn't directly connect to the database). ### Blazor UI Module Extensibility -TODO +Module Entity Extensions and some other extensibility features was not supported by the Blazor UI. With this version, we've implemented that system for Blazor UI. + +For anyone wondering what the module entity extensions is, please check [the document](https://docs.abp.io/en/abp/4.3/Module-Entity-Extensions) or [this community video](https://community.abp.io/articles/overview-of-abp-framework-4.1-module-extensions-part-1-n04f7bhf). + +### Email Setting Management UI + +With this release, a new item is added to the main menu to navigate to the setting management page. This page contains the email setting management UI, as shown below: + +![email-settings-page](email-settings-page.png) + +The setting page is provided by the [setting management module](https://docs.abp.io/en/abp/4.3/Modules/Setting-Management), and it is extensible; You can add your tabs to this page for your application settings. ### Angular UI Resource Owner Password Flow -TODO +The login page was removed from the Angular UI in previous versions because Authorization Code flow is the recommended approach for SPAs. However, it requires redirecting the user to the authentication server, logging there, and returning to the application. We got a lot of feedback because this brings overhead for simple applications. + +With version 4.3, Angular UI can use its login page with resource owner password flow. Please refer to [the documentation](https://github.com/abpframework/abp/blob/dev/docs/en/UI/Angular/Account-Module.md) to learn how to make it work. ### Volo.Abp.EntityFrameworkCore.Oracle Package -TODO +We couldn't update the [Oracle.EntityFrameworkCore](https://www.nuget.org/packages/Oracle.EntityFrameworkCore/) package on .NET 5.0 upgrade since it was not supporting .NET 5.0 at that time. Now, it supports .NET 5.0 and we've upgraded the package. + +See [the documentation](https://docs.abp.io/en/abp/4.3/Entity-Framework-Core-Oracle-Official) to learn how to switch to this package for the Oracle database. ### Add Basic Theme Into Your Solution -TODO +ABP Framework provides a strong theming system. However, the default theme, named the Basic Theme, has a non-styled, base Bootstrap UI. It is expected that you override the styles and UI components of that theme in a serious application. + +There are some articles (see for [mvc](https://community.abp.io/articles/creating-a-new-ui-theme-by-copying-the-basic-theme-for-mvc-ui-yt9b18io) & [blazor](https://community.abp.io/articles/creating-a-new-ui-theme-by-copying-the-basic-theme-for-blazor-ui-qaf5ho1b)) to explain how to include the Basic Theme's source code into your solution to modify it fully. However, it still requires some manual work. + +With this version, ABP CLI providing a command to add the Basic Theme's source code into your solution. Run the following command in a command-line terminal inside the root directory of your solution: + +**MVC UI** + +````bash +abp add-package Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic --with-source-code --add-to-solution +```` + +**Blazor Web Assembly UI** + +````bash +abp add-package Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme --with-source-code --add-to-solution +abp add-package Volo.Abp.AspNetCore.Components.Web.BasicTheme --with-source-code --add-to-solution +```` + +**Blazor Server UI** + +````bash +abp add-package Volo.Abp.AspNetCore.Components.Server.BasicTheme --with-source-code --add-to-solution +abp add-package Volo.Abp.AspNetCore.Components.Web.BasicTheme --with-source-code --add-to-solution +```` + +As you see, Blazor UI developers should add two packages. The Basic Theme consists of two packages for the Blazor UI: one for wasm/server and one shared. + +**Angular UI** + +Execute the following command in a terminal inside the `angular` folder of your solution: + +````bash +abp add-package @abp/ng.theme.basic --with-source-code +```` ### IInitLogger -TODO +In ASP.NET Core, logging is not possible before the dependency injection phase is completed. For example, you can't write log in `ConfigureServices` method. However, we sometimes need to write logs in this stage. + +We are introducing the `IInitLogger` service, which allows writing logs inside the `ConfigureServices` method. + +**Example:** + +````csharp +public class MyModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var logger = context.Services.GetInitLogger(); + logger.LogInformation("Some log..."); + } +} +```` -### Multi-Lingual Entities +Logs are written once the service registration phase is completed. It stores the written logs in memory and then writes logs to the actual `ILogger` when ready. -TODO +> Notice: Startup templates come with [Serilog](https://serilog.net/) pre-installed. So, you can write logs everywhere by directly using its static API (ex: `Log.Information("...");`). The `InitLogger` is a way to write pre-initialization logs without depending on a particular logging library. So, it makes it very handy to write logs inside reusable modules. -### Other News +### Other Features/Changes * [#7423](https://github.com/abpframework/abp/issues/7423) MongoDB repository base aggregation API. -* [#8163](https://github.com/abpframework/abp/issues/8163) Ignoring files on minification for MVC UI. +* [#8163](https://github.com/abpframework/abp/issues/8163) Ignoring given files on minification for MVC UI. * [#7799](https://github.com/abpframework/abp/pull/7799) Added `RequiredPermissionName` to `ApplicationMenuItem` for MVC & Blazor UI to easily show/hide menu items based on user permissions. Also added `RequiredPermissionName` to `ToolbarItem` for the MVC UI for the same purpose. * [#7523](https://github.com/abpframework/abp/pull/7523) Add more bundle methods to the distributed cache. +* [#8013](https://github.com/abpframework/abp/pull/8013) Handle `JsonProperty` attribute on Angular proxy generation. See the [4.3 milestone](https://github.com/abpframework/abp/milestone/49) on GitHub for all changes made on this version. ## Feedback -Please check out the ABP Framework 4.3 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us to release a more stable version. **The planned release date for the [4.3.0 final](https://github.com/abpframework/abp/milestone/50) version is April 15, 2021**. \ No newline at end of file +Please check out the ABP Framework 4.3 RC and [provide feedback](https://github.com/abpframework/abp/issues/new) to help us release a more stable version. **The planned release date for the [4.3.0 final](https://github.com/abpframework/abp/milestone/50) version is April 15, 2021**. diff --git a/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/email-settings-page.png b/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/email-settings-page.png new file mode 100644 index 0000000000..d2eda14b2a Binary files /dev/null and b/docs/en/Blog-Posts/2021-03-31 v4_3 Preview/email-settings-page.png differ diff --git a/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md new file mode 100644 index 0000000000..ad8b89faa0 --- /dev/null +++ b/docs/en/Blog-Posts/2021-04-05 CmsKit/POST.md @@ -0,0 +1,3 @@ +# Introducing the CMS Kit Module for the ABP Framework + +TODO... \ No newline at end of file diff --git a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md index 519a09fa42..7a88adde44 100644 --- a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md +++ b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/POST.md @@ -84,12 +84,13 @@ We added SignalR to the `package.json` but it comes into your `node_modules` fol #### 4- Usage We have completed the implementation part. Let's check if it's running... +We will show the current time which comes from server. +To do this replace the `Index.cshtml` and `Index.cshtml.cs` with the followings: -To do this easily, open your `Index.cshtml` which is in the Pages folder of your Web project. And replace the content with the following. Also replace the `Index.cshtml.cs` as well. +- [Index.cshtml](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml) -[Index.cshtml](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml) +- [Index.cshtml.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml-cs) -[Index.cshtml.cs](https://gist.github.com/ebicoglu/f7dc22cca2d353f8bf7f68a03e3395b8#file-index-cshtml-cs) #### 5- See it in action diff --git a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg index 4c9ca0663b..2da86ce6fa 100644 Binary files a/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg and b/docs/en/Community-Articles/2021-03-12-Simple-SignalR-Notification/result.jpg differ diff --git a/docs/en/Migration-Guides/Abp-4_3.md b/docs/en/Migration-Guides/Abp-4_3.md index c4541a6581..ddc40189a0 100644 --- a/docs/en/Migration-Guides/Abp-4_3.md +++ b/docs/en/Migration-Guides/Abp-4_3.md @@ -1,3 +1,31 @@ # ABP Framework 4.x to 4.3 Migration Guide -TODO \ No newline at end of file +## Blazor UI + +Implemented the Blazor Server Side support with this release. It required some packages and namespaces arrangements. **Existing Blazor (WebAssembly) applications should done the changes explained in this section**. + +### Namespace Changes + +- `AbpBlazorMessageLocalizerHelper` -> moved to Volo.Abp.AspNetCore.Components.Web +- `AbpRouterOptions` -> moved to Volo.Abp.AspNetCore.Components.Web.Theming.Routing +- `AbpToolbarOptions` and `IToolbarContributor` -> moved to Volo.Abp.AspNetCore.Components.Web.Theming.Toolbars +- `IAbpUtilsService` -> moved to Volo.Abp.AspNetCore.Components.Web +- `PageHeader` -> moved to `Volo.Abp.AspNetCore.Components.Web.Theming.Layout`. + +In practice, if your application is broken because of the `Volo.Abp.AspNetCore.Components.WebAssembly.*` namespace, please try to switch to `Volo.Abp.AspNetCore.Components.Web.*` namespace. + +Remember to change namespaces in the `_Imports.razor` files. + +### Package Changes + +No change on the framework packages, but **module packages are separated as Web Assembly & Server**; + +* Use `Volo.Abp.Identity.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.Identity.Blazor` package. Also, change `AbpIdentityBlazorModule` usage to `AbpIdentityBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class. +* Use `Volo.Abp.TenantManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.TenantManagement.Blazor` package. Also, change `AbpTenantManagementBlazorModule` usage to `AbpTenantManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class. +* Use `Volo.Abp.PermissionManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.PermissionManagement.Blazor` package. Also, change `AbpPermissionManagementBlazorModule` usage to `AbpPermissionManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class. +* Use `Volo.Abp.SettingManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.SettingManagement.Blazor` package. Also, change `AbpSettingManagementBlazorModule` usage to `AbpSettingManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class. +* Use `Volo.Abp.FeatureManagement.Blazor.WebAssembly` NuGet package instead of `Volo.Abp.FeatureManagement.Blazor` package. Also, change `AbpFeatureManagementBlazorModule` usage to `AbpFeatureManagementBlazorWebAssemblyModule` in the `[DependsOn]` attribute on your module class. + +### Other Changes + +* `EntityAction.RequiredPermission` has been marked as obsolete, because of performance reasons. It is suggested to use the `Visible` property by checking the permission/policy yourself and assigning to a variable. \ No newline at end of file diff --git a/docs/en/Tutorials/Part-5.md b/docs/en/Tutorials/Part-5.md index 213dd8821b..7ad9aed970 100644 --- a/docs/en/Tutorials/Part-5.md +++ b/docs/en/Tutorials/Part-5.md @@ -516,7 +516,7 @@ Wrap the *New Book* button by an `if` block as shown below: #### Hide the Edit/Delete Actions -`EntityAction` component defines `RequiredPolicy` attribute (parameter) to conditionally show the action based on the user permissions. +`EntityAction` component defines `Visible` attribute (parameter) to conditionally show the action. Update the `EntityActions` section as shown below: @@ -524,11 +524,11 @@ Update the `EntityActions` section as shown below: diff --git a/docs/en/Tutorials/images/blazor-edit-book-action-2.png b/docs/en/Tutorials/images/blazor-edit-book-action-2.png index 70856ab325..c3e2b1e0e1 100644 Binary files a/docs/en/Tutorials/images/blazor-edit-book-action-2.png and b/docs/en/Tutorials/images/blazor-edit-book-action-2.png differ diff --git a/docs/en/UI/Angular/Account-Module.md b/docs/en/UI/Angular/Account-Module.md index ffa89ec980..0227a53b62 100644 --- a/docs/en/UI/Angular/Account-Module.md +++ b/docs/en/UI/Angular/Account-Module.md @@ -2,7 +2,7 @@ Angular UI account module is available as of v4.3. It contains some pages (login, register, manage your profile, etc.). -If you implement the account module to your project; +If you add the account module to your project; - "Manage your profile" link in the current user dropdown on the top bar will redirect the user to a page in the account module. - You can switch the authentication flow to the resource owner password flow. @@ -93,15 +93,15 @@ export class AppRoutingModule {} ### Manage Profile Page -Before v4.3, the "Manage Your Profile" link in the current user dropdown on the top bar redirected the user to MVC's profile management page. As of v4.3, if you implemented the account module to your project, the same link will land on a page in the Angular UI account module instead. +Before v4.3, the "Manage Your Profile" link in the current user dropdown on the top bar redirected the user to MVC's profile management page. As of v4.3, if you added the account module to your project, the same link will land on a page in the Angular UI account module instead. ### My Security Logs Page [COMMERCIAL] -Before v4.3, the "My Security Logs" link in the current user dropdown on the top bar redirected the user to MVC's my security logs page. As of v4.3, if you implemented the account module to your project, the same link will land on a page in the Angular UI account public module instead. +Before v4.3, the "My Security Logs" link in the current user dropdown on the top bar redirected the user to MVC's my security logs page. As of v4.3, if you added the account module to your project, the same link will land on a page in the Angular UI account public module instead. ### Resource Owner Password Flow -OAuth is preconfigured as authorization code flow in Angular application templates by default. If you implemented the account module to your project, you can switch the flow to resource owner password flow by changing the OAuth configuration in the _environment.ts_ files as shown below: +OAuth is preconfigured as authorization code flow in Angular application templates by default. If you added the account module to your project, you can switch the flow to resource owner password flow by changing the OAuth configuration in the _environment.ts_ files as shown below: ```js import { Config } from '@abp/ng.core'; @@ -122,4 +122,4 @@ export const environment = { > Note: The resource owner password flow does not support the two-factor authentication for some technical reasons. -See the [Authorization in Angular UI](./Authorization) document for more details. \ No newline at end of file +See the [Authorization in Angular UI](./Authorization.md) document for more details. diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index ec3341c623..efca73a484 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -376,10 +376,6 @@ "text": "Entities & Aggregate Roots", "path": "Entities.md" }, - { - "text": "Multi-Lingual-Entities", - "path": "Multi-Lingual-Entities.md" - }, { "text": "Value Objects", "path": "Value-Objects.md" diff --git a/docs/zh-Hans/Multi-Lingual-Entities.md b/docs/zh-Hans/Multi-Lingual-Entities.md deleted file mode 100644 index 2deff4e38f..0000000000 --- a/docs/zh-Hans/Multi-Lingual-Entities.md +++ /dev/null @@ -1,100 +0,0 @@ -# 多语言实体 - -ABP框架为多语言实体定义了两个基本接口用于翻译实体的标准模型. - -## IHasMultiLingual - -`IHasMultiLingual` 接口用于标记多语言实体. 通过 `IHasMultiLingual` 接口被标记为多语言的实体定义与语言无关的信息. 多语言实体包含翻译集合,其中包含与语言有关的信息. - -示例: - -```csharp -public class Product : Entity, IMultiLingualEntity -{ - public decimal Price { get; set; } - - public ICollection Translations { get; set; } -} -``` - -## IMultiLingualTranslation - -`IMultiLingualTranslation` 接口用于标记多语言实体的翻译. 通过 `IHasMultiLingual` 接口被标记为的翻译实体定义与语言有关的信息. 翻译实体包含 `Language` 字段,用于翻译的语言代码. - -示例: - -```csharp -public class ProductTranslation : Entity, IMultiLingualTranslation -{ - public string Name { get; set; } - - public string Language { get; set; } -} -``` - -## 映射为DTO对象 - -ABP提供了[对象到对象的映射](Object-To-Object-Mapping.md)系统,你可以通过实现 `IObjectMapper` 接口将多语言实体映射为DTO. - -示例: - -```csharp -public class MultiLingualProductObjectMapper : IObjectMapper, ITransientDependency -{ - private readonly IMultiLingualObjectManager _multiLingualObjectManager; - - public MultiLingualProductObjectMapper(IMultiLingualObjectManager multiLingualObjectManager) - { - _multiLingualObjectManager = multiLingualObjectManager; - } - - public ProductDto Map(Product source) - { - var translation = _multiLingualObjectManager.GetTranslation(source); - - return new ProductDto - { - Price = source.Price, - Id = source.Id, - Name = translation?.Name - }; - } - - public ProductDto Map(Product source, ProductDto destination) - { - return default; - } -} - -``` - -### AutoMapper集成 - -ABP提供了 `CreateMultiLingualMap` 扩展方法用于将多语言实体映射为DTO. - -示例: - -```csharp -public class ProductProfile : Profile -{ - public ProductProfile() - { - var mapResult = this.CreateMultiLingualMap(); - } -} -``` - -`CreateMultiLingualMap` 扩展方法返回了一个类型为 `CreateMultiLingualMapResult` 的对象,它包含 `EntityMap` 和 `TranslationMap` 字段. 这些字段可以用于自定义多语言映射. - -示例: - -```csharp -this.CreateMultiLingualMap(context) - .EntityMap.ForMember(dest => dest.ProductCount, opt => opt.MapFrom(src => src.Products.Count)); -``` - -## IMultiLingualObjectManager - -`IMultiLingualObjectManager` 接口定义了 `GetTranslation` 和 `GetTranslationAsync` 方法用于获取实体当前的翻译对象. - -`IMultiLingualObjectManager` 的默认实现首先使用当前的UI语言寻找翻译, 如果当前的UI语言没有对应的翻译, 那么会搜索默认语言设置(参阅[设置](Settings.md))用于寻找翻译. 如果默认语言没有对应的翻译, 那么它会返回已存在翻译集合中的第一个翻译对象. diff --git a/docs/zh-Hans/docs-nav.json b/docs/zh-Hans/docs-nav.json index 241633caf5..4f47dd2760 100644 --- a/docs/zh-Hans/docs-nav.json +++ b/docs/zh-Hans/docs-nav.json @@ -354,10 +354,6 @@ "text": "实体&聚合根", "path": "Entities.md" }, - { - "text": "多语言实体", - "path": "Multi-Lingual-Entities.md" - }, { "text": "值对象" }, diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index fb631f3ee5..67d2fa2573 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -331,9 +331,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.GlobalFeatures", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.GlobalFeatures.Tests", "test\Volo.Abp.GlobalFeatures.Tests\Volo.Abp.GlobalFeatures.Tests.csproj", "{231F1581-AA21-44C3-BF27-51EB3AD5355C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiLingualObject", "src\Volo.Abp.MultiLingualObject\Volo.Abp.MultiLingualObject.csproj", "{C9142DED-1F6C-4385-A37D-81E46B233306}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiLingualObjects", "src\Volo.Abp.MultiLingualObjects\Volo.Abp.MultiLingualObjects.csproj", "{C9142DED-1F6C-4385-A37D-81E46B233306}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiLingualObject.Tests", "test\Volo.Abp.MultiLingualObject.Tests\Volo.Abp.MultiLingualObject.Tests.csproj", "{A30D63B0-E952-4052-BAEE-38B8BF924093}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.MultiLingualObjects.Tests", "test\Volo.Abp.MultiLingualObjects.Tests\Volo.Abp.MultiLingualObjects.Tests.csproj", "{A30D63B0-E952-4052-BAEE-38B8BF924093}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Client.IdentityModel.WebAssembly", "src\Volo.Abp.Http.Client.IdentityModel.WebAssembly\Volo.Abp.Http.Client.IdentityModel.WebAssembly.csproj", "{3D35A1E0-A9A1-404F-9B55-5F1A7EB6D5B8}" EndProject diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs index 23f920eb71..4040193b8b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.BasicTheme/Themes/Basic/NavToolbar.razor.cs @@ -18,11 +18,12 @@ namespace Volo.Abp.AspNetCore.Components.Web.BasicTheme.Themes.Basic ToolbarItemRenders.Clear(); + var sequence = 0; foreach (var item in toolbar.Items) { ToolbarItemRenders.Add(builder => { - builder.OpenComponent(0, item.ComponentType); + builder.OpenComponent(sequence++, item.ComponentType); builder.CloseComponent(); }); } diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor index aec0eada09..d874da0901 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor @@ -32,6 +32,11 @@ } + @if (Toolbar == null) + { + @ChildContent + } + @foreach (var toolbarItemRender in ToolbarItemRenders) { diff --git a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs index fb2db1b8a2..7806aa4b44 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs @@ -31,9 +31,6 @@ namespace Volo.Abp.AspNetCore.Components.Web.Theming.Layout [Parameter] public PageToolbar Toolbar { get; set; } - [Parameter] - public string PageName { get; set; } - public PageHeader() { BreadcrumbItems = new List(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj index a379c8057d..704b51f6b6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo.Abp.AspNetCore.Mvc.UI.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj index 81c4a3e7e6..fb5a3d3ae7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo.Abp.AspNetCore.Mvc.csproj @@ -30,7 +30,7 @@ - + diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs index ba07e28f77..340544f79d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentInputFormatter.cs @@ -15,7 +15,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters protected override bool CanReadType(Type type) { - return typeof(IRemoteStreamContent) == type; + return type == typeof(IRemoteStreamContent) || + type == typeof(RemoteStreamContent); } public override Task ReadRequestBodyAsync(InputFormatterContext context) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs index 685822a4b6..188306227a 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ContentFormatters/RemoteStreamContentOutputFormatter.cs @@ -28,7 +28,11 @@ namespace Volo.Abp.AspNetCore.Mvc.ContentFormatters using (var stream = remoteStream.GetStream()) { - stream.Position = 0; + if (stream.CanSeek) + { + stream.Position = 0; + } + await stream.CopyToAsync(context.HttpContext.Response.Body); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj index 0015b4e237..f42418a107 100644 --- a/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj +++ b/framework/src/Volo.Abp.AspNetCore.Serilog/Volo.Abp.AspNetCore.Serilog.csproj @@ -22,7 +22,7 @@ - + diff --git a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs b/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs deleted file mode 100644 index 83cb2b35b9..0000000000 --- a/framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperMultiLingualDtoExtensions.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Volo.Abp.MultiLingualObject; -using Volo.Abp.Threading; - -namespace AutoMapper -{ - public static class AbpAutoMapperMultiLingualDtoExtensions - { - public static CreateMultiLingualMapResult CreateMultiLingualMap(this Profile profile) - where TTranslation : class, IMultiLingualTranslation - where TSource : IHasMultiLingual - { - - return new( - profile.CreateMap().BeforeMap>(), - profile.CreateMap()); - } - } - - public class AbpMultiLingualMapperAction : IMappingAction - where TTranslation : class, IMultiLingualTranslation - where TSource : IHasMultiLingual - { - private readonly IMultiLingualObjectManager _multiLingualObjectManager; - - public AbpMultiLingualMapperAction(IMultiLingualObjectManager multiLingualObjectManager) - { - _multiLingualObjectManager = multiLingualObjectManager; - } - - public void Process(TSource source, TDestination destination, ResolutionContext context) - { - var translation = AsyncHelper.RunSync(() => _multiLingualObjectManager.GetTranslationAsync(source)); - if (translation != null) - { - context.Mapper.Map(translation, destination); - } - } - } - - public class CreateMultiLingualMapResult - { - public IMappingExpression EntityMap { get; } - - public IMappingExpression TranslateMap { get; } - - public CreateMultiLingualMapResult( - IMappingExpression entityMap, - IMappingExpression translateMap) - { - EntityMap = entityMap; - TranslateMap = translateMap; - } - } -} diff --git a/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj b/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj index 4a5f44f937..9f028d31ee 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj +++ b/framework/src/Volo.Abp.AutoMapper/Volo.Abp.AutoMapper.csproj @@ -16,7 +16,6 @@ - diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs index 3969a04a1a..cb576ba1de 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs @@ -27,8 +27,6 @@ namespace Volo.Abp.AutoMapper context.Services.AddSingleton(CreateMappings); context.Services.AddSingleton(provider => provider.GetRequiredService()); - - context.Services.AddTransient(typeof(AbpMultiLingualMapperAction<,,>)); } private MapperAccessor CreateMappings(IServiceProvider serviceProvider) diff --git a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj index a57ac74e62..cd3c6bd2fb 100644 --- a/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj +++ b/framework/src/Volo.Abp.Autofac/Volo.Abp.Autofac.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs b/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs index 822cca49d3..3cd2192cf6 100644 --- a/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs +++ b/framework/src/Volo.Abp.BlazoriseUI/Components/EntityAction.razor.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.BlazoriseUI.Components public partial class EntityAction : ComponentBase { [Parameter] - public bool Visible { get; set; } + public bool Visible { get; set; } = true; internal bool HasPermission { get; set; } = true; @@ -24,7 +24,7 @@ namespace Volo.Abp.BlazoriseUI.Components public EventCallback Clicked { get; set; } [Parameter] - [Obsolete("Use IsVisible to hide actions based on permissions. Check the permission yourself. It is more performant. This option might be removed in future versions.")] + [Obsolete("Use Visible to hide actions based on permissions. Check the permission yourself. It is more performant. This option might be removed in future versions.")] public string RequiredPolicy { get; set; } [Parameter] diff --git a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo.Abp.BlobStoring.Aliyun.csproj b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo.Abp.BlobStoring.Aliyun.csproj index 25c486d79f..e75ca9f362 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo.Abp.BlobStoring.Aliyun.csproj +++ b/framework/src/Volo.Abp.BlobStoring.Aliyun/Volo.Abp.BlobStoring.Aliyun.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/src/Volo.Abp.BlobStoring.Aws/Volo.Abp.BlobStoring.Aws.csproj b/framework/src/Volo.Abp.BlobStoring.Aws/Volo.Abp.BlobStoring.Aws.csproj index d36d2bfbf3..76692b5653 100644 --- a/framework/src/Volo.Abp.BlobStoring.Aws/Volo.Abp.BlobStoring.Aws.csproj +++ b/framework/src/Volo.Abp.BlobStoring.Aws/Volo.Abp.BlobStoring.Aws.csproj @@ -17,8 +17,8 @@ - - + + diff --git a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj index 73a8116e46..3273ae33c8 100644 --- a/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj +++ b/framework/src/Volo.Abp.BlobStoring.Azure/Volo.Abp.BlobStoring.Azure.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index feb1c075d5..1b7603194a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -13,12 +13,12 @@ - + - + - + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs index 96740fa418..f644706bd9 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Extensions.Logging; @@ -17,9 +18,12 @@ namespace Volo.Abp.Cli.Commands protected ProjectNugetPackageAdder ProjectNugetPackageAdder { get; } - public AddPackageCommand(ProjectNugetPackageAdder projectNugetPackageAdder) + public ProjectNpmPackageAdder ProjectNpmPackageAdder { get; } + + public AddPackageCommand(ProjectNugetPackageAdder projectNugetPackageAdder, ProjectNpmPackageAdder projectNpmPackageAdder) { ProjectNugetPackageAdder = projectNugetPackageAdder; + ProjectNpmPackageAdder = projectNpmPackageAdder; Logger = NullLogger.Instance; } @@ -34,18 +38,42 @@ namespace Volo.Abp.Cli.Commands ); } + var isAngularPackage = false; + var isNugetPackage = true; + + if (commandLineArgs.Target.StartsWith("@")) + { + isAngularPackage = true; + isNugetPackage = false; + } + var version = commandLineArgs.Options.GetOrNull(Options.Version.Short, Options.Version.Long); var withSourceCode =commandLineArgs.Options.ContainsKey(Options.SourceCode.Long); - var addSourceCodeToSolutionFile = withSourceCode && commandLineArgs.Options.ContainsKey("add-to-solution-file"); - - await ProjectNugetPackageAdder.AddAsync( - GetProjectFile(commandLineArgs), - commandLineArgs.Target, - version, - true, - withSourceCode, - addSourceCodeToSolutionFile - ); + + if (isNugetPackage) + { + var addSourceCodeToSolutionFile = withSourceCode && commandLineArgs.Options.ContainsKey("add-to-solution-file"); + + await ProjectNugetPackageAdder.AddAsync( + GetSolutionFile(commandLineArgs), + GetProjectFile(commandLineArgs), + commandLineArgs.Target, + version, + true, + withSourceCode, + addSourceCodeToSolutionFile + ); + } + else if (isAngularPackage) + { + await ProjectNpmPackageAdder.AddAngularPackageAsync( + GetAngularDirectory(commandLineArgs), + commandLineArgs.Target, + version, + withSourceCode + ); + } + } public string GetUsageInfo() @@ -54,7 +82,7 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine(""); sb.AppendLine("'add-package' command is used to add an ABP package to a project."); - sb.AppendLine("It should be used in a folder containing a .csproj file."); + sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file or angular.json."); sb.AppendLine(""); sb.AppendLine("Usage:"); sb.AppendLine(""); @@ -62,13 +90,18 @@ namespace Volo.Abp.Cli.Commands sb.AppendLine(""); sb.AppendLine("Options:"); sb.AppendLine(""); - sb.AppendLine(" -p|--project Specify the project file explicitly."); - sb.AppendLine(" -v|--version Specify the version of the package. Default is your project's ABP version or latest ABP version."); + sb.AppendLine(" -p|--project Specifies the project file explicitly. (Only available for NuGet packages)"); + sb.AppendLine(" -s|--solution Specifies the solution file explicitly. (Only available for NuGet packages)"); + sb.AppendLine(" --with-source-code Downloads the source code of the NPM/NuGet package and make other projects depends on it."); + sb.AppendLine(" --add-to-solution-file Adds the downloaded project to the .sln file, when source code is downloaded. (Only available for NuGet packages)"); + sb.AppendLine(" -ad|--angular-directory Specifies the Angular project directory explicitly. (Only available for Angular packages)"); + sb.AppendLine(" -v|--version Specifies the version of the package. Default is your project's ABP version or latest ABP version."); sb.AppendLine(""); sb.AppendLine("Examples:"); sb.AppendLine(""); - sb.AppendLine(" abp add-package Volo.Abp.FluentValidation Adds the package to the current project."); - sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the package to the given project."); + sb.AppendLine(" abp add-package Volo.Abp.FluentValidation Adds the NuGet package to the current project."); + sb.AppendLine(" abp add-package Volo.Abp.FluentValidation -p Acme.BookStore.Application Adds the NuGet package to the given project."); + sb.AppendLine(" abp add-package @abp/ng.theme.basic Adds the NPM package to the given corresponding project."); sb.AppendLine(""); sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); @@ -94,30 +127,41 @@ namespace Volo.Abp.Cli.Commands return providedProjectFile; } - var foundProjectFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj"); - if (foundProjectFiles.Length == 1) - { - return foundProjectFiles[0]; - } + return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.csproj").FirstOrDefault(); + } - if (foundProjectFiles.Length == 0) + protected virtual string GetSolutionFile(CommandLineArgs commandLineArgs) + { + var providedSolutionFile = PathHelper.NormalizePath( + commandLineArgs.Options.GetOrNull( + Options.Solution.Short, + Options.Solution.Long + ) + ); + + if (!providedSolutionFile.IsNullOrWhiteSpace()) { - throw new CliUsageException("'abp add-package' command should be used inside a folder contaning a .csproj file!"); + return providedSolutionFile; } - //foundProjectFiles.Length > 1 + return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln").FirstOrDefault(); + } - var sb = new StringBuilder("There are multiple project (.csproj) files in the current directory. Please specify one of the files below:"); + protected virtual string GetAngularDirectory(CommandLineArgs commandLineArgs) + { + var providedAngularDirectory = PathHelper.NormalizePath( + commandLineArgs.Options.GetOrNull( + Options.AngularDirectory.Short, + Options.AngularDirectory.Long + ) + ); - foreach (var foundProjectFile in foundProjectFiles) + if (!providedAngularDirectory.IsNullOrWhiteSpace()) { - sb.AppendLine("* " + foundProjectFile); + return providedAngularDirectory; } - sb.AppendLine("Example:"); - sb.AppendLine($"abp add-package {commandLineArgs.Target} -p {foundProjectFiles[0]}"); - - throw new CliUsageException(sb.ToString()); + return Directory.GetCurrentDirectory(); } public static class Options @@ -128,6 +172,18 @@ namespace Volo.Abp.Cli.Commands public const string Long = "project"; } + public static class Solution + { + public const string Short = "s"; + public const string Long = "solution"; + } + + public static class AngularDirectory + { + public const string Short = "ad"; + public const string Long = "angular-directory"; + } + public static class Version { public const string Short = "v"; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs index ad1c5cb7fe..088cadb707 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/Services/SourceCodeDownloadService.cs @@ -17,13 +17,17 @@ namespace Volo.Abp.Cli.Commands.Services public class SourceCodeDownloadService : ITransientDependency { public ModuleProjectBuilder ModuleProjectBuilder { get; } - public PackageProjectBuilder PackageProjectBuilder { get; } + public NugetPackageProjectBuilder NugetPackageProjectBuilder { get; } + public NpmPackageProjectBuilder NpmPackageProjectBuilder { get; } public ILogger Logger { get; set; } - public SourceCodeDownloadService(ModuleProjectBuilder moduleProjectBuilder, PackageProjectBuilder packageProjectBuilder) + public SourceCodeDownloadService(ModuleProjectBuilder moduleProjectBuilder, + NugetPackageProjectBuilder nugetPackageProjectBuilder, + NpmPackageProjectBuilder npmPackageProjectBuilder) { ModuleProjectBuilder = moduleProjectBuilder; - PackageProjectBuilder = packageProjectBuilder; + NugetPackageProjectBuilder = nugetPackageProjectBuilder; + NpmPackageProjectBuilder = npmPackageProjectBuilder; Logger = NullLogger.Instance; } @@ -92,13 +96,13 @@ namespace Volo.Abp.Cli.Commands.Services Logger.LogInformation($"'{moduleName}' has been successfully downloaded to '{outputFolder}'"); } - public async Task DownloadPackageAsync(string packageName, string outputFolder, string version) + public async Task DownloadNugetPackageAsync(string packageName, string outputFolder, string version) { Logger.LogInformation("Downloading source code of " + packageName); Logger.LogInformation("Version: " + version); Logger.LogInformation("Output folder: " + outputFolder); - var result = await PackageProjectBuilder.BuildAsync( + var result = await NugetPackageProjectBuilder.BuildAsync( new ProjectBuildArgs( SolutionName.Parse(packageName), packageName, @@ -113,12 +117,56 @@ namespace Volo.Abp.Cli.Commands.Services var zipEntry = zipInputStream.GetNextEntry(); while (zipEntry != null) { - if (IsAngularTestFile(zipEntry.Name)) + var fullZipToPath = Path.Combine(outputFolder, zipEntry.Name); + var directoryName = Path.GetDirectoryName(fullZipToPath); + + if (!string.IsNullOrEmpty(directoryName)) + { + Directory.CreateDirectory(directoryName); + } + + var fileName = Path.GetFileName(fullZipToPath); + if (fileName.Length == 0) { zipEntry = zipInputStream.GetNextEntry(); continue; } + var buffer = new byte[4096]; // 4K is optimum + using (var streamWriter = File.Create(fullZipToPath)) + { + StreamUtils.Copy(zipInputStream, streamWriter, buffer); + } + + zipEntry = zipInputStream.GetNextEntry(); + } + } + } + + Logger.LogInformation($"'{packageName}' has been successfully downloaded to '{outputFolder}'"); + } + + public async Task DownloadNpmPackageAsync(string packageName, string outputFolder, string version) + { + Logger.LogInformation("Downloading source code of " + packageName); + Logger.LogInformation("Version: " + version); + Logger.LogInformation("Output folder: " + outputFolder); + + var result = await NpmPackageProjectBuilder.BuildAsync( + new ProjectBuildArgs( + SolutionName.Parse(packageName), + packageName, + version + ) + ); + + using (var templateFileStream = new MemoryStream(result.ZipContent)) + { + using (var zipInputStream = new ZipInputStream(templateFileStream)) + { + var zipEntry = zipInputStream.GetNextEntry(); + while (zipEntry != null) + { var fullZipToPath = Path.Combine(outputFolder, zipEntry.Name); var directoryName = Path.GetDirectoryName(fullZipToPath); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs index 29ea93bd3d..fdafa7c01c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/AbpIoSourceCodeStore.cs @@ -91,7 +91,7 @@ namespace Volo.Abp.Cli.ProjectBuilding return new TemplateFile(File.ReadAllBytes(Path.Combine(templateSource, name + "-" + version + ".zip")), version, latestVersion, nugetVersion); } - var localCacheFile = Path.Combine(CliPaths.TemplateCache, name + "-" + version + ".zip"); + var localCacheFile = Path.Combine(CliPaths.TemplateCache, name.Replace("/",".") + "-" + version + ".zip"); #if DEBUG if (File.Exists(localCacheFile)) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NpmPackageProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NpmPackageProjectBuildPipelineBuilder.cs new file mode 100644 index 0000000000..4c28f08ccd --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NpmPackageProjectBuildPipelineBuilder.cs @@ -0,0 +1,18 @@ +using Volo.Abp.Cli.ProjectBuilding.Building.Steps; +using Volo.Abp.Cli.ProjectBuilding.Templates; + +namespace Volo.Abp.Cli.ProjectBuilding.Building +{ + public static class NpmPackageProjectBuildPipelineBuilder + { + public static ProjectBuildPipeline Build(ProjectBuildContext context) + { + var pipeline = new ProjectBuildPipeline(context); + + pipeline.Steps.Add(new FileEntryListReadStep()); + pipeline.Steps.Add(new CreateProjectResultZipStep()); + + return pipeline; + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/PackageProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NugetPackageProjectBuildPipelineBuilder.cs similarity index 91% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/PackageProjectBuildPipelineBuilder.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NugetPackageProjectBuildPipelineBuilder.cs index 79245dfaec..0bc074e7b8 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/PackageProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/NugetPackageProjectBuildPipelineBuilder.cs @@ -3,7 +3,7 @@ using Volo.Abp.Cli.ProjectBuilding.Templates; namespace Volo.Abp.Cli.ProjectBuilding.Building { - public static class PackageProjectBuildPipelineBuilder + public static class NugetPackageProjectBuildPipelineBuilder { public static ProjectBuildPipeline Build(ProjectBuildContext context) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs index b6c2baec88..6b1f606e28 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildContext.cs @@ -17,24 +17,28 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building public ModuleInfo Module { get; } - public NugetPackageInfo Package { get; } + public NugetPackageInfo NugetPackage { get; } + + public NpmPackageInfo NpmPackage { get; } public FileEntryList Files { get; set; } public ProjectResult Result { get; set; } - + public List Symbols { get; } //TODO: Fill the symbols, like "UI-Angular", "CMS-KIT"! - + public ProjectBuildContext( TemplateInfo template, ModuleInfo module, - NugetPackageInfo package, + NugetPackageInfo nugetPackage, + NpmPackageInfo npmPackage, [NotNull] TemplateFile templateFile, [NotNull] ProjectBuildArgs buildArgs) { Template = template; Module = module; - Package = package; + NugetPackage = nugetPackage; + NpmPackage = npmPackage; TemplateFile = Check.NotNull(templateFile, nameof(templateFile)); BuildArgs = Check.NotNull(buildArgs, nameof(buildArgs)); Symbols = new List(); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs new file mode 100644 index 0000000000..130afa4a60 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/INpmPackageInfoProvider.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Volo.Abp.Cli.ProjectModification; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public interface INpmPackageInfoProvider + { + Task GetAsync(string name); + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs index 029b687015..e621c58acc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ModuleProjectBuilder.cs @@ -68,6 +68,7 @@ namespace Volo.Abp.Cli.ProjectBuilding null, moduleInfo, null, + null, templateFile, args ); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs new file mode 100644 index 0000000000..458a419840 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageInfoProvider.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Json; +using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectModification; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Threading; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public class NpmPackageInfoProvider : INpmPackageInfoProvider, ITransientDependency + { + public IJsonSerializer JsonSerializer { get; } + public ICancellationTokenProvider CancellationTokenProvider { get; } + public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + + private readonly CliHttpClientFactory _cliHttpClientFactory; + + public NpmPackageInfoProvider( + IJsonSerializer jsonSerializer, + ICancellationTokenProvider cancellationTokenProvider, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler, + CliHttpClientFactory cliHttpClientFactory) + { + JsonSerializer = jsonSerializer; + CancellationTokenProvider = cancellationTokenProvider; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; + _cliHttpClientFactory = cliHttpClientFactory; + } + + public async Task GetAsync(string name) + { + var packageList = await GetPackageListInternalAsync(); + + var package = packageList.FirstOrDefault(m => m.Name == name); + + if (package == null) + { + throw new Exception("Package is not found or downloadable!"); + } + + return package; + } + + private async Task> GetPackageListInternalAsync() + { + var client = _cliHttpClientFactory.CreateClient(); + + using (var responseMessage = await client.GetAsync( + $"{CliUrls.WwwAbpIo}api/download/npmPackages/", + CancellationTokenProvider.Token + )) + { + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(responseMessage); + var result = await responseMessage.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize>(result); + } + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageProjectBuilder.cs new file mode 100644 index 0000000000..d60e76d9a7 --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NpmPackageProjectBuilder.cs @@ -0,0 +1,110 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.Licensing; +using Volo.Abp.Cli.ProjectBuilding.Analyticses; +using Volo.Abp.Cli.ProjectBuilding.Building; +using Volo.Abp.Cli.ProjectModification; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Json; + +namespace Volo.Abp.Cli.ProjectBuilding +{ + public class NpmPackageProjectBuilder : IProjectBuilder, ITransientDependency + { + public ILogger Logger { get; set; } + protected ISourceCodeStore SourceCodeStore { get; } + protected INpmPackageInfoProvider NpmPackageInfoProvider { get; } + protected ICliAnalyticsCollect CliAnalyticsCollect { get; } + protected AbpCliOptions Options { get; } + protected IJsonSerializer JsonSerializer { get; } + protected IApiKeyService ApiKeyService { get; } + + public NpmPackageProjectBuilder(ISourceCodeStore sourceCodeStore, + INpmPackageInfoProvider npmPackageInfoProvider, + ICliAnalyticsCollect cliAnalyticsCollect, + IOptions options, + IJsonSerializer jsonSerializer, + IApiKeyService apiKeyService) + { + SourceCodeStore = sourceCodeStore; + NpmPackageInfoProvider = npmPackageInfoProvider; + CliAnalyticsCollect = cliAnalyticsCollect; + Options = options.Value; + JsonSerializer = jsonSerializer; + ApiKeyService = apiKeyService; + + Logger = NullLogger.Instance; + } + + public async Task BuildAsync(ProjectBuildArgs args) + { + var packageInfo = await GetPackageInfoAsync(args); + + var templateFile = await SourceCodeStore.GetAsync( + args.TemplateName, + SourceCodeTypes.NpmPackage, + args.Version, + null, + args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long) + ); + + var apiKeyResult = await ApiKeyService.GetApiKeyOrNullAsync(); + if (apiKeyResult?.ApiKey != null) + { + args.ExtraProperties["api-key"] = apiKeyResult.ApiKey; + } + + if (apiKeyResult?.LicenseCode != null) + { + args.ExtraProperties["license-code"] = apiKeyResult.LicenseCode; + } + + var context = new ProjectBuildContext( + null, + null, + null, + packageInfo, + templateFile, + args + ); + + NpmPackageProjectBuildPipelineBuilder.Build(context).Execute(); + + // Exclude unwanted or known options. + var options = args.ExtraProperties + .Where(x => !x.Key.Equals(CliConsts.Command, StringComparison.InvariantCultureIgnoreCase)) + .Where(x => !x.Key.Equals(NewCommand.Options.OutputFolder.Long, StringComparison.InvariantCultureIgnoreCase) && + !x.Key.Equals(NewCommand.Options.OutputFolder.Short, StringComparison.InvariantCultureIgnoreCase)) + .Where(x => !x.Key.Equals(NewCommand.Options.Version.Long, StringComparison.InvariantCultureIgnoreCase) && + !x.Key.Equals(NewCommand.Options.Version.Short, StringComparison.InvariantCultureIgnoreCase)) + .Where(x => !x.Key.Equals(NewCommand.Options.TemplateSource.Short, StringComparison.InvariantCultureIgnoreCase) && + !x.Key.Equals(NewCommand.Options.TemplateSource.Long, StringComparison.InvariantCultureIgnoreCase)) + .Select(x => x.Key).ToList(); + + await CliAnalyticsCollect.CollectAsync(new CliAnalyticsCollectInputDto + { + Tool = Options.ToolName, + Command = args.ExtraProperties.ContainsKey(CliConsts.Command) ? args.ExtraProperties[CliConsts.Command] : "", + DatabaseProvider = null, + IsTiered = null, + UiFramework = null, + Options = JsonSerializer.Serialize(options), + ProjectName = null, + TemplateName = args.TemplateName, + TemplateVersion = templateFile.Version + }); + + return new ProjectBuildResult(context.Result.ZipContent, args.TemplateName); + } + + private async Task GetPackageInfoAsync(ProjectBuildArgs args) + { + return await NpmPackageInfoProvider.GetAsync(args.TemplateName); + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs index 06c39e66f7..af1bee7d23 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageInfoProvider.cs @@ -49,7 +49,7 @@ namespace Volo.Abp.Cli.ProjectBuilding var client = _cliHttpClientFactory.CreateClient(); using (var responseMessage = await client.GetAsync( - $"{CliUrls.WwwAbpIo}api/download/packages/", + $"{CliUrls.WwwAbpIo}api/download/nugetPackages/", CancellationTokenProvider.Token )) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/PackageProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageProjectBuilder.cs similarity index 90% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/PackageProjectBuilder.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageProjectBuilder.cs index 04518332a4..c68a45e080 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/PackageProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/NugetPackageProjectBuilder.cs @@ -14,9 +14,9 @@ using Volo.Abp.Json; namespace Volo.Abp.Cli.ProjectBuilding { - public class PackageProjectBuilder : IProjectBuilder, ITransientDependency + public class NugetPackageProjectBuilder : IProjectBuilder, ITransientDependency { - public ILogger Logger { get; set; } + public ILogger Logger { get; set; } protected ISourceCodeStore SourceCodeStore { get; } protected INugetPackageInfoProvider NugetPackageInfoProvider { get; } protected ICliAnalyticsCollect CliAnalyticsCollect { get; } @@ -24,7 +24,7 @@ namespace Volo.Abp.Cli.ProjectBuilding protected IJsonSerializer JsonSerializer { get; } protected IApiKeyService ApiKeyService { get; } - public PackageProjectBuilder(ISourceCodeStore sourceCodeStore, + public NugetPackageProjectBuilder(ISourceCodeStore sourceCodeStore, INugetPackageInfoProvider nugetPackageInfoProvider, ICliAnalyticsCollect cliAnalyticsCollect, IOptions options, @@ -38,7 +38,7 @@ namespace Volo.Abp.Cli.ProjectBuilding JsonSerializer = jsonSerializer; ApiKeyService = apiKeyService; - Logger = NullLogger.Instance; + Logger = NullLogger.Instance; } public async Task BuildAsync(ProjectBuildArgs args) @@ -47,7 +47,7 @@ namespace Volo.Abp.Cli.ProjectBuilding var templateFile = await SourceCodeStore.GetAsync( args.TemplateName, - SourceCodeTypes.Package, + SourceCodeTypes.NugetPackage, args.Version, null, args.ExtraProperties.ContainsKey(GetSourceCommand.Options.Preview.Long) @@ -68,11 +68,12 @@ namespace Volo.Abp.Cli.ProjectBuilding null, null, packageInfo, + null, templateFile, args ); - PackageProjectBuildPipelineBuilder.Build(context).Execute(); + NugetPackageProjectBuildPipelineBuilder.Build(context).Execute(); // Exclude unwanted or known options. var options = args.ExtraProperties diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs index 813ffe6b54..014f1959f0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/SourceCodeTypes.cs @@ -6,6 +6,8 @@ public const string Module = "module"; - public const string Package = "package"; + public const string NugetPackage = "nugetPackage"; + + public const string NpmPackage = "npmPackage"; } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs index 5823c3c488..0f224a20cb 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/TemplateProjectBuilder.cs @@ -106,6 +106,7 @@ namespace Volo.Abp.Cli.ProjectBuilding templateInfo, null, null, + null, templateFile, args ); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularModuleSourceCodeAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs similarity index 90% rename from framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularModuleSourceCodeAdder.cs rename to framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs index 08912f2f25..fdd4d58652 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularModuleSourceCodeAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/AngularSourceCodeAdder.cs @@ -11,16 +11,16 @@ using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.ProjectModification { - public class AngularModuleSourceCodeAdder : ITransientDependency + public class AngularSourceCodeAdder : ITransientDependency { public ILogger Logger { get; set; } - public AngularModuleSourceCodeAdder() + public AngularSourceCodeAdder() { Logger = NullLogger.Instance; } - public async Task AddAsync(string solutionFilePath, string angularPath) + public async Task AddFromModuleAsync(string solutionFilePath, string angularPath) { try { @@ -36,7 +36,7 @@ namespace Volo.Abp.Cli.ProjectModification await AddPathsToTsConfigAsync(angularPath, angularProjectsPath, projects); await CreateTsConfigProdJsonAsync(angularPath); await AddScriptsToPackageJsonAsync(angularPath); - await AddProjectToAngularJsonAsync(angularPath, projects); + await AddProjectsToAngularJsonAsync(angularPath, projects); } catch (Exception e) { @@ -44,7 +44,29 @@ namespace Volo.Abp.Cli.ProjectModification } } - private async Task AddProjectToAngularJsonAsync(string angularPath, List projects) + public async Task AddAsync(string angularPath, NpmPackageInfo package) + { + try + { + var angularProjectsPath = Path.Combine(angularPath, "projects"); + + var projects = new List + { + package.Name.RemovePreFix("@").Replace("/","-") + }; + + await AddPathsToTsConfigAsync(angularPath, angularProjectsPath, projects); + await CreateTsConfigProdJsonAsync(angularPath); + await AddScriptsToPackageJsonAsync(angularPath); + await AddProjectsToAngularJsonAsync(angularPath, projects); + } + catch (Exception e) + { + Logger.LogError("Unable to add angular source code: " + e.Message + Environment.NewLine + e.StackTrace); + } + } + + private async Task AddProjectsToAngularJsonAsync(string angularPath, List projects) { var angularJsonFilePath = Path.Combine(angularPath, "angular.json"); var fileContent = File.ReadAllText(angularJsonFilePath); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageInfo.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageInfo.cs index 6bd6297384..a3905b2006 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageInfo.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/NuGetPackageInfo.cs @@ -9,5 +9,9 @@ public NuGetPackageTarget Target { get; set; } public NuGetPackageTarget TieredTarget { get; set; } + + public string MinVersion { get; set; } + + public string MaxVersion { get; set; } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs index d0925c6d0d..7cc0423892 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectFinder.cs @@ -51,10 +51,10 @@ namespace Volo.Abp.Cli.ProjectModification return FindProjectEndsWith(projectFiles, assemblyNames, ".Blazor"); case NuGetPackageTarget.BlazorWebAssembly: var BlazorWebAssemblyTargetProject = FindProjectEndsWith(projectFiles, assemblyNames, ".Blazor"); - return !BlazorProjectTypeChecker.IsBlazorServerProject(BlazorWebAssemblyTargetProject) ? BlazorWebAssemblyTargetProject : null; + return BlazorWebAssemblyTargetProject != null && !BlazorProjectTypeChecker.IsBlazorServerProject(BlazorWebAssemblyTargetProject) ? BlazorWebAssemblyTargetProject : null; case NuGetPackageTarget.BlazorServer: var BlazorServerTargetProject = FindProjectEndsWith(projectFiles, assemblyNames, ".Blazor"); - return BlazorProjectTypeChecker.IsBlazorServerProject(BlazorServerTargetProject) ? BlazorServerTargetProject : null; + return BlazorServerTargetProject != null && BlazorProjectTypeChecker.IsBlazorServerProject(BlazorServerTargetProject) ? BlazorServerTargetProject : null; default: return null; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs index 7ed15f7b86..a0ee3b463a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNpmPackageAdder.cs @@ -1,23 +1,107 @@ -using System.IO; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; using System.Threading.Tasks; +using System.Xml; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Cli.Args; +using Volo.Abp.Cli.Commands; +using Volo.Abp.Cli.Commands.Services; +using Volo.Abp.Cli.Http; +using Volo.Abp.Cli.ProjectBuilding; using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; using Volo.Abp.IO; +using Volo.Abp.Json; namespace Volo.Abp.Cli.ProjectModification { public class ProjectNpmPackageAdder : ITransientDependency { + public IJsonSerializer JsonSerializer { get; } + public SourceCodeDownloadService SourceCodeDownloadService { get; } + public AngularSourceCodeAdder AngularSourceCodeAdder { get; } + public IRemoteServiceExceptionHandler RemoteServiceExceptionHandler { get; } + private readonly CliHttpClientFactory _cliHttpClientFactory; public ILogger Logger { get; set; } - public ProjectNpmPackageAdder() + public ProjectNpmPackageAdder(CliHttpClientFactory cliHttpClientFactory, + IJsonSerializer jsonSerializer, + SourceCodeDownloadService sourceCodeDownloadService, + AngularSourceCodeAdder angularSourceCodeAdder, + IRemoteServiceExceptionHandler remoteServiceExceptionHandler) { + JsonSerializer = jsonSerializer; + SourceCodeDownloadService = sourceCodeDownloadService; + AngularSourceCodeAdder = angularSourceCodeAdder; + RemoteServiceExceptionHandler = remoteServiceExceptionHandler; + _cliHttpClientFactory = cliHttpClientFactory; Logger = NullLogger.Instance; } - public Task AddAsync(string directory, NpmPackageInfo npmPackage, bool skipGulpCommand = false) + public async Task AddAngularPackageAsync(string directory, string npmPackageName, string version = null, bool withSourceCode = false) + { + await AddAngularPackageAsync( + directory, + await FindNpmPackageInfoAsync(npmPackageName), + version, + withSourceCode + ); + } + + public async Task AddAngularPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, bool withSourceCode = false) + { + var packageJsonFilePath = Path.Combine(directory, "package.json"); + if (!File.Exists(packageJsonFilePath)) + { + Logger.LogError($"package.json not found!"); + return; + } + + Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'..."); + + if (!File.ReadAllText(packageJsonFilePath).Contains($"\"{npmPackage.Name}\"")) + { + var versionPostfix = version != null ? $"@{version}" : string.Empty; + + using (DirectoryHelper.ChangeCurrentDirectory(directory)) + { + Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix); + CmdHelper.RunCmd("yarn add " + npmPackage.Name + versionPostfix); + } + } + else + { + Logger.LogInformation($"'{npmPackage.Name}' is already installed."); + } + + if (withSourceCode) + { + await DownloadAngularSourceCode(directory, npmPackage, version); + await AngularSourceCodeAdder.AddAsync(directory, npmPackage); + } + } + + protected virtual async Task DownloadAngularSourceCode(string angularDirectory, NpmPackageInfo package, string version = null) + { + var targetFolder = Path.Combine(angularDirectory, "projects", package.Name.RemovePreFix("@").Replace("/","-")); + + if (Directory.Exists(targetFolder)) + { + Directory.Delete(targetFolder, true); + } + + await SourceCodeDownloadService.DownloadNpmPackageAsync( + package.Name, + targetFolder, + version + ); + } + + public Task AddMvcPackageAsync(string directory, NpmPackageInfo npmPackage, string version = null, bool skipGulpCommand = false) { var packageJsonFilePath = Path.Combine(directory, "package.json"); if (!File.Exists(packageJsonFilePath) || @@ -29,11 +113,12 @@ namespace Volo.Abp.Cli.ProjectModification Logger.LogInformation($"Installing '{npmPackage.Name}' package to the project '{packageJsonFilePath}'..."); + var versionPostfix = version != null ? $"@{version}" : string.Empty; using (DirectoryHelper.ChangeCurrentDirectory(directory)) { - Logger.LogInformation("yarn add " + npmPackage.Name); - CmdHelper.RunCmd("yarn add " + npmPackage.Name); + Logger.LogInformation("yarn add " + npmPackage.Name + versionPostfix); + CmdHelper.RunCmd("yarn add " + npmPackage.Name + versionPostfix); if (skipGulpCommand) { @@ -46,5 +131,28 @@ namespace Volo.Abp.Cli.ProjectModification return Task.CompletedTask; } + + private async Task FindNpmPackageInfoAsync(string packageName) + { + + var url = $"{CliUrls.WwwAbpIo}api/app/npmPackage/byName/?name=" + packageName; + var client = _cliHttpClientFactory.CreateClient(); + + using (var response = await client.GetAsync(url, _cliHttpClientFactory.GetCancellationToken())) + { + if (!response.IsSuccessStatusCode) + { + if (response.StatusCode == HttpStatusCode.NotFound) + { + throw new CliUsageException($"'{packageName}' npm package could not be found!"); + } + + await RemoteServiceExceptionHandler.EnsureSuccessfulHttpResponseAsync(response); + } + + var responseContent = await response.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(responseContent); + } + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs index 8665a80bc3..7d9f81056f 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs @@ -58,6 +58,7 @@ namespace Volo.Abp.Cli.ProjectModification } public async Task AddAsync( + string solutionFile, string projectFile, string packageName, string version = null, @@ -66,6 +67,7 @@ namespace Volo.Abp.Cli.ProjectModification bool addSourceCodeToSolutionFile = false) { await AddAsync( + solutionFile, projectFile, await FindNugetPackageInfoAsync(packageName), version, @@ -76,6 +78,7 @@ namespace Volo.Abp.Cli.ProjectModification } public async Task AddAsync( + string solutionFile, string projectFile, NugetPackageInfo package, string version = null, @@ -83,6 +86,23 @@ namespace Volo.Abp.Cli.ProjectModification bool withSourceCode = false, bool addSourceCodeToSolutionFile = false) { + if (projectFile == null) + { + if (solutionFile == null) + { + throw new CliUsageException("Couldn't find any project/solution."); + } + + projectFile = GetProjectFile(solutionFile, package); + + if (projectFile == null) + { + throw new CliUsageException("Couldn't find any project/solution."); + } + } + + solutionFile ??= FindSolutionFile(projectFile); + if (version == null) { version = GetAbpVersionOrNull(projectFile); @@ -92,17 +112,30 @@ namespace Volo.Abp.Cli.ProjectModification if (withSourceCode) { - await AddSourceCode(projectFile, package, version); - await ConvertPackageReferenceToProjectReference(projectFile, package); + await AddSourceCode(projectFile, solutionFile, package, version); + await ConvertPackageReferenceToProjectReference(projectFile, solutionFile, package); if (addSourceCodeToSolutionFile) { - await SolutionFileModifier.AddPackageToSolutionFileAsync(package, FindSolutionFile(projectFile)); + await SolutionFileModifier.AddPackageToSolutionFileAsync(package, solutionFile); } } } - private async Task ConvertPackageReferenceToProjectReference(string projectFile, NugetPackageInfo package) + private string GetProjectFile(string solutionFile, NugetPackageInfo package) + { + var projectFiles = Directory.GetFiles(Path.GetDirectoryName(solutionFile), "*.csproj", SearchOption.AllDirectories); + var isSolutionTiered = IsSolutionTiered(projectFiles); + + var projectFile = ProjectFinder.FindNuGetTargetProjectFile( + projectFiles, + isSolutionTiered && package.TieredTarget != NuGetPackageTarget.Undefined + ? package.TieredTarget + : package.Target); + return projectFile; + } + + protected virtual async Task ConvertPackageReferenceToProjectReference(string projectFile,string solutionFile, NugetPackageInfo package) { var content = File.ReadAllText(projectFile); var doc = new XmlDocument() {PreserveWhitespace = true}; @@ -117,7 +150,7 @@ namespace Volo.Abp.Cli.ProjectModification return; } - var downloadedProjectPath = FindRelativeFolderToDownloadPackage(projectFile, package); + var downloadedProjectPath = FindRelativeFolderToDownloadPackage(projectFile, solutionFile, package); var oldNodeIncludeValue = nodes[0]?.Attributes?["Include"]?.Value; if (package.Name == oldNodeIncludeValue) @@ -135,9 +168,9 @@ namespace Volo.Abp.Cli.ProjectModification File.WriteAllText(projectFile, doc.OuterXml); } - private async Task AddSourceCode(string projectFile, NugetPackageInfo package, string version = null) + protected virtual async Task AddSourceCode(string projectFile, string solutionFile, NugetPackageInfo package, string version = null) { - var targetFolder = FindFolderToDownloadPackage(projectFile, package); + var targetFolder = FindFolderToDownloadPackage(solutionFile, package); if (Directory.Exists(targetFolder)) { @@ -147,35 +180,35 @@ namespace Volo.Abp.Cli.ProjectModification await DownloadSourceCode(targetFolder, package, version); } - private string FindFolderToDownloadPackage(string projectFile, NugetPackageInfo package) + protected virtual string FindFolderToDownloadPackage(string solutionFile, NugetPackageInfo package) { - return Path.Combine(FindSolutionFolder(projectFile), "packages", package.Name); + return Path.Combine(Path.GetDirectoryName(solutionFile), "packages", package.Name); } - private string FindRelativeFolderToDownloadPackage(string projectFile, NugetPackageInfo package) + protected virtual string FindRelativeFolderToDownloadPackage(string projectFile, string solutionFile, NugetPackageInfo package) { - var folder = Path.Combine(FindSolutionFolder(projectFile), "packages", package.Name); + var folder = Path.Combine(Path.GetDirectoryName(solutionFile), "packages", package.Name); return new Uri(projectFile).MakeRelativeUri(new Uri(folder)).ToString().Replace("/", "\\"); } - private async Task DownloadSourceCode(string targetFolder, NugetPackageInfo package, string version = null) + protected virtual async Task DownloadSourceCode(string targetFolder, NugetPackageInfo package, string version = null) { - await SourceCodeDownloadService.DownloadPackageAsync( + await SourceCodeDownloadService.DownloadNugetPackageAsync( package.Name, targetFolder, version ); } - private string FindSolutionFile(string projectFile) + protected virtual string FindSolutionFile(string projectFile) { var folder = FindSolutionFolder(projectFile); return Directory.GetFiles(folder, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault(); } - private string FindSolutionFolder(string projectFile) + protected virtual string FindSolutionFolder(string projectFile) { var targetFolder = Path.GetDirectoryName(projectFile); @@ -199,7 +232,7 @@ namespace Volo.Abp.Cli.ProjectModification return targetFolder; } - private async Task AddAsPackageReference(string projectFile, NugetPackageInfo package, string version, + protected virtual async Task AddAsPackageReference(string projectFile, NugetPackageInfo package, string version, bool useDotnetCliToInstall) { var projectFileContent = File.ReadAllText(projectFile); @@ -250,7 +283,7 @@ namespace Volo.Abp.Cli.ProjectModification Logger.LogInformation("Successfully installed."); } - private Task AddUsingDotnetCli(NugetPackageInfo package, string version = null) + protected virtual Task AddUsingDotnetCli(NugetPackageInfo package, string version = null) { var versionOption = version == null ? "" : $" -v {version}"; @@ -259,7 +292,7 @@ namespace Volo.Abp.Cli.ProjectModification return Task.CompletedTask; } - private Task AddToCsprojManuallyAsync(string projectFile, NugetPackageInfo package, string version = null) + protected virtual Task AddToCsprojManuallyAsync(string projectFile, NugetPackageInfo package, string version = null) { var projectFileContent = File.ReadAllText(projectFile); var doc = new XmlDocument() {PreserveWhitespace = true}; @@ -301,7 +334,7 @@ namespace Volo.Abp.Cli.ProjectModification return Task.CompletedTask; } - private string GetAbpVersionOrNull(string projectFile) + protected virtual string GetAbpVersionOrNull(string projectFile) { var projectFileContent = File.ReadAllText(projectFile); @@ -345,5 +378,13 @@ namespace Volo.Abp.Cli.ProjectModification await BundleCommand.ExecuteAsync(args); } + + protected virtual bool IsSolutionTiered(string[] projectFiles) + { + return projectFiles.Select(ProjectFileNameHelper.GetAssemblyNameFromProjectPath) + .Any(p => p.EndsWith(".HttpApi.Host")) + && projectFiles.Select(ProjectFileNameHelper.GetAssemblyNameFromProjectPath) + .Any(p => p.EndsWith(".IdentityServer")); + } } } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index caf47e0a87..4e66954dcc 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; +using NuGet.Versioning; using Volo.Abp.Cli.Args; using Volo.Abp.Cli.Commands; using Volo.Abp.Cli.Commands.Services; @@ -26,7 +27,7 @@ namespace Volo.Abp.Cli.ProjectModification public SourceCodeDownloadService SourceCodeDownloadService { get; } public SolutionFileModifier SolutionFileModifier { get; } public NugetPackageToLocalReferenceConverter NugetPackageToLocalReferenceConverter { get; } - public AngularModuleSourceCodeAdder AngularModuleSourceCodeAdder { get; } + public AngularSourceCodeAdder AngularSourceCodeAdder { get; } public NewCommand NewCommand { get; } public BundleCommand BundleCommand { get; } @@ -54,7 +55,7 @@ namespace Volo.Abp.Cli.ProjectModification SourceCodeDownloadService sourceCodeDownloadService, SolutionFileModifier solutionFileModifier, NugetPackageToLocalReferenceConverter nugetPackageToLocalReferenceConverter, - AngularModuleSourceCodeAdder angularModuleSourceCodeAdder, + AngularSourceCodeAdder angularSourceCodeAdder, NewCommand newCommand, BundleCommand bundleCommand, CliHttpClientFactory cliHttpClientFactory) @@ -70,7 +71,7 @@ namespace Volo.Abp.Cli.ProjectModification SourceCodeDownloadService = sourceCodeDownloadService; SolutionFileModifier = solutionFileModifier; NugetPackageToLocalReferenceConverter = nugetPackageToLocalReferenceConverter; - AngularModuleSourceCodeAdder = angularModuleSourceCodeAdder; + AngularSourceCodeAdder = angularSourceCodeAdder; NewCommand = newCommand; BundleCommand = bundleCommand; _cliHttpClientFactory = cliHttpClientFactory; @@ -91,6 +92,7 @@ namespace Volo.Abp.Cli.ProjectModification Check.NotNull(moduleName, nameof(moduleName)); var module = await GetModuleInfoAsync(moduleName, newTemplate, newProTemplate); + module = RemoveIncompatiblePackages(module, version); Logger.LogInformation( $"Installing module '{module.Name}' to the solution '{Path.GetFileNameWithoutExtension(solutionFile)}'"); @@ -131,6 +133,39 @@ namespace Volo.Abp.Cli.ProjectModification ModifyDbContext(projectFiles, module, skipDbMigrations); } + private ModuleWithMastersInfo RemoveIncompatiblePackages(ModuleWithMastersInfo module, string version) + { + module.NugetPackages.RemoveAll(np => IsPackageInCompatible(np, version)); + return module; + } + + private bool IsPackageInCompatible(NugetPackageInfo package, string version) + { + try + { + if (!string.IsNullOrWhiteSpace(package.MinVersion)) + { + if (SemanticVersion.Parse(package.MinVersion) > SemanticVersion.Parse(version)) + { + return true; + } + } + if (!string.IsNullOrWhiteSpace(package.MaxVersion)) + { + if (SemanticVersion.Parse(package.MaxVersion) < SemanticVersion.Parse(version)) + { + return true; + } + } + + return false; + } + catch (ArgumentException) + { + return false; + } + } + private async Task RunBundleForBlazorAsync(string[] projectFiles, ModuleWithMastersInfo module) { var blazorProject = projectFiles.FirstOrDefault(f => f.EndsWith(".Blazor.csproj")); @@ -292,7 +327,7 @@ namespace Volo.Abp.Cli.ProjectModification { foreach (var npmPackage in angularPackages) { - await ProjectNpmPackageAdder.AddAsync(angularPath, npmPackage, true); + await ProjectNpmPackageAdder.AddAngularPackageAsync(angularPath, npmPackage); } } } @@ -312,7 +347,7 @@ namespace Volo.Abp.Cli.ProjectModification MoveAngularFolderInNewTemplate(modulesFolderInSolution, moduleName); } - await AngularModuleSourceCodeAdder.AddAsync(solutionFilePath, angularPath); + await AngularSourceCodeAdder.AddFromModuleAsync(solutionFilePath, angularPath); } private static void DeleteAngularDirectoriesInModulesFolder(string modulesFolderInSolution) @@ -438,7 +473,7 @@ namespace Volo.Abp.Cli.ProjectModification continue; } - await ProjectNugetPackageAdder.AddAsync(targetProjectFile, nugetPackage, null, useDotnetCliToInstall); + await ProjectNugetPackageAdder.AddAsync(null, targetProjectFile, nugetPackage, null, useDotnetCliToInstall); } var mvcNpmPackages = module.NpmPackages?.Where(p => p.ApplicationType.HasFlag(NpmApplicationType.Mvc)) @@ -455,7 +490,7 @@ namespace Volo.Abp.Cli.ProjectModification { foreach (var npmPackage in mvcNpmPackages) { - await ProjectNpmPackageAdder.AddAsync(Path.GetDirectoryName(targetProject), npmPackage); + await ProjectNpmPackageAdder.AddMvcPackageAsync(Path.GetDirectoryName(targetProject), npmPackage, null, true); } } } diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs index 2d2ae9d6dc..148b34fa90 100644 --- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpDictionaryExtensions.cs @@ -67,7 +67,7 @@ namespace System.Collections.Generic { return dictionary.TryGetValue(key, out var obj) ? obj : default; } - + /// /// Gets a value from the dictionary with given key. Returns default value if can not find. /// @@ -100,7 +100,7 @@ namespace System.Collections.Generic return dictionary[key] = factory(key); } - + /// /// Gets a value from the dictionary with given key. Returns default value if can not find. /// @@ -114,5 +114,19 @@ namespace System.Collections.Generic { return dictionary.GetOrAdd(key, k => factory()); } + + /// + /// Gets a value from the concurrent dictionary with given key. Returns default value if can not find. + /// + /// Concurrent dictionary to check and get + /// Key to find the value + /// A factory method used to create the value if not found in the dictionary + /// Type of the key + /// Type of the value + /// Value if found, default if can not found. + public static TValue GetOrAdd(this ConcurrentDictionary dictionary, TKey key, Func factory) + { + return dictionary.GetOrAdd(key, k => factory()); + } } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs index bd85773a9b..62ad5a53b5 100644 --- a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs @@ -9,7 +9,10 @@ namespace System.IO { using (var memoryStream = new MemoryStream()) { - stream.Position = 0; + if (stream.CanSeek) + { + stream.Position = 0; + } stream.CopyTo(memoryStream); return memoryStream.ToArray(); } @@ -19,7 +22,10 @@ namespace System.IO { using (var memoryStream = new MemoryStream()) { - stream.Position = 0; + if (stream.CanSeek) + { + stream.Position = 0; + } await stream.CopyToAsync(memoryStream, cancellationToken); return memoryStream.ToArray(); } @@ -27,7 +33,10 @@ namespace System.IO public static Task CopyToAsync(this Stream stream, Stream destination, CancellationToken cancellationToken) { - stream.Position = 0; + if (stream.CanSeek) + { + stream.Position = 0; + } return stream.CopyToAsync( destination, 81920, //this is already the default value, but needed to set to be able to pass the cancellationToken diff --git a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj index c91b14e67b..15b967b9e4 100644 --- a/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj +++ b/framework/src/Volo.Abp.Core/Volo.Abp.Core.csproj @@ -26,7 +26,7 @@ - + diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj b/framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj index e676f24313..87879334af 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo.Abp.Ddd.Domain.csproj @@ -20,7 +20,6 @@ - diff --git a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs index 0ebbe859bd..523a6ee4f2 100644 --- a/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs +++ b/framework/src/Volo.Abp.Ddd.Domain/Volo/Abp/Domain/AbpDddDomainModule.cs @@ -6,7 +6,6 @@ using Volo.Abp.EventBus; using Volo.Abp.ExceptionHandling; using Volo.Abp.Guids; using Volo.Abp.Modularity; -using Volo.Abp.MultiLingualObject; using Volo.Abp.MultiTenancy; using Volo.Abp.ObjectMapping; using Volo.Abp.Specifications; @@ -26,7 +25,6 @@ namespace Volo.Abp.Domain typeof(AbpTimingModule), typeof(AbpUnitOfWorkModule), typeof(AbpObjectMappingModule), - typeof(AbpMultiLingualObjectModule), typeof(AbpExceptionHandlingModule), typeof(AbpSpecificationsModule) )] diff --git a/framework/src/Volo.Abp.EventBus.Rebus/Volo.Abp.EventBus.Rebus.csproj b/framework/src/Volo.Abp.EventBus.Rebus/Volo.Abp.EventBus.Rebus.csproj index 0a01911990..a1504caa8d 100644 --- a/framework/src/Volo.Abp.EventBus.Rebus/Volo.Abp.EventBus.Rebus.csproj +++ b/framework/src/Volo.Abp.EventBus.Rebus/Volo.Abp.EventBus.Rebus.csproj @@ -19,8 +19,8 @@ - - + + diff --git a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj index 772774a77e..f42977cd75 100644 --- a/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj +++ b/framework/src/Volo.Abp.FluentValidation/Volo.Abp.FluentValidation.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 136c9e42ef..dd96ad98a2 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -106,7 +106,8 @@ namespace Volo.Abp.Http.Client.DynamicProxying { var responseContent = await MakeRequestAsync(invocation); - if (typeof(T) == typeof(IRemoteStreamContent)) + if (typeof(T) == typeof(IRemoteStreamContent) || + typeof(T) == typeof(RemoteStreamContent)) { /* returning a class that holds a reference to response * content just to be sure that GC does not dispose of diff --git a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj index 9b1a1c9caf..e835e24e99 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj +++ b/framework/src/Volo.Abp.IdentityModel/Volo.Abp.IdentityModel.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs index 0fb4c32648..cc0b470a1e 100644 --- a/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs +++ b/framework/src/Volo.Abp.IdentityModel/Volo/Abp/IdentityModel/IdentityModelAuthenticationService.cs @@ -232,7 +232,7 @@ namespace Volo.Abp.IdentityModel { foreach (var pair in configuration.Where(p => p.Key.StartsWith("[o]", StringComparison.OrdinalIgnoreCase))) { - request.Parameters[pair.Key] = pair.Value; + request.Parameters.Add(pair); } return Task.CompletedTask; diff --git a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj index ef88ab752b..76cbe9f28f 100644 --- a/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj +++ b/framework/src/Volo.Abp.Json/Volo.Abp.Json.csproj @@ -17,7 +17,7 @@ - + diff --git a/framework/src/Volo.Abp.Kafka/Volo.Abp.Kafka.csproj b/framework/src/Volo.Abp.Kafka/Volo.Abp.Kafka.csproj index 4f8a94fe8e..b14caecacb 100644 --- a/framework/src/Volo.Abp.Kafka/Volo.Abp.Kafka.csproj +++ b/framework/src/Volo.Abp.Kafka/Volo.Abp.Kafka.csproj @@ -9,7 +9,7 @@ - + diff --git a/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj index edc3752d47..94c9411bc2 100644 --- a/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj +++ b/framework/src/Volo.Abp.MailKit/Volo.Abp.MailKit.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj index 45302cfab3..6bb0997c87 100644 --- a/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj +++ b/framework/src/Volo.Abp.Minify/Volo.Abp.Minify.csproj @@ -19,7 +19,7 @@ - + diff --git a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj index aa487ffc4e..1888ddf869 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj +++ b/framework/src/Volo.Abp.MongoDB/Volo.Abp.MongoDB.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs index 0d2722574c..99e732cf9c 100644 --- a/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs +++ b/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs @@ -517,7 +517,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB ); } - public async Task> GetMongoQueryableAsync(CancellationToken cancellationToken = default) + public virtual async Task> GetMongoQueryableAsync(CancellationToken cancellationToken = default) { cancellationToken = GetCancellationToken(cancellationToken); @@ -531,7 +531,7 @@ namespace Volo.Abp.Domain.Repositories.MongoDB ); } - public async Task> GetAggregateAsync(CancellationToken cancellationToken = default) + public virtual async Task> GetAggregateAsync(CancellationToken cancellationToken = default) { cancellationToken = GetCancellationToken(cancellationToken); diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IHasMultiLingual.cs b/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IHasMultiLingual.cs deleted file mode 100644 index 8ea05ecabd..0000000000 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IHasMultiLingual.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.Abp.MultiLingualObject -{ - public interface IHasMultiLingual - where TTranslation : class, IMultiLingualTranslation - { - ICollection Translations { get; set; } - } -} diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualObjectManager.cs b/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualObjectManager.cs deleted file mode 100644 index e6ddc840e5..0000000000 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualObjectManager.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.MultiLingualObject -{ - public interface IMultiLingualObjectManager - { - TTranslation GetTranslation( - TMultiLingual multiLingual, - bool fallbackToParentCultures = true, - string culture = null) - where TMultiLingual : IHasMultiLingual - where TTranslation : class, IMultiLingualTranslation; - - Task GetTranslationAsync( - TMultiLingual multiLingual, - bool fallbackToParentCultures = true, - string culture = null) - where TMultiLingual : IHasMultiLingual - where TTranslation : class, IMultiLingualTranslation; - } -} diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualTranslation.cs b/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualTranslation.cs deleted file mode 100644 index 3676e08b44..0000000000 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/IMultiLingualTranslation.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.MultiLingualObject -{ - public interface IMultiLingualTranslation - { - string Language { get; set; } - } -} diff --git a/framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xml b/framework/src/Volo.Abp.MultiLingualObjects/FodyWeavers.xml similarity index 100% rename from framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xml rename to framework/src/Volo.Abp.MultiLingualObjects/FodyWeavers.xml diff --git a/framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xsd b/framework/src/Volo.Abp.MultiLingualObjects/FodyWeavers.xsd similarity index 100% rename from framework/src/Volo.Abp.MultiLingualObject/FodyWeavers.xsd rename to framework/src/Volo.Abp.MultiLingualObjects/FodyWeavers.xsd diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo.Abp.MultiLingualObject.csproj b/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj similarity index 92% rename from framework/src/Volo.Abp.MultiLingualObject/Volo.Abp.MultiLingualObject.csproj rename to framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj index d6df31e1ed..da83bc80f4 100644 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo.Abp.MultiLingualObject.csproj +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo.Abp.MultiLingualObjects.csproj @@ -5,7 +5,6 @@ netstandard2.0 - Volo.Abp.MultiLingualObject Volo.Abp.MultiLingualObject $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; false diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectModule.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsModule.cs similarity index 57% rename from framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectModule.cs rename to framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsModule.cs index 120cf7bac1..248a0eff75 100644 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectModule.cs +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsModule.cs @@ -1,11 +1,11 @@ using Volo.Abp.Localization; using Volo.Abp.Modularity; -namespace Volo.Abp.MultiLingualObject +namespace Volo.Abp.MultiLingualObjects { [DependsOn( typeof(AbpLocalizationModule))] - public class AbpMultiLingualObjectModule : AbpModule + public class AbpMultiLingualObjectsModule : AbpModule { } } diff --git a/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObject.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObject.cs new file mode 100644 index 0000000000..31a82f1b06 --- /dev/null +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObject.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace Volo.Abp.MultiLingualObjects +{ + public interface IMultiLingualObject + where TTranslation : class, IObjectTranslation + { + ICollection Translations { get; set; } + } +} diff --git a/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObjectManager.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObjectManager.cs new file mode 100644 index 0000000000..8a649cd51a --- /dev/null +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IMultiLingualObjectManager.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.MultiLingualObjects +{ + public interface IMultiLingualObjectManager + { + Task GetTranslationAsync( + TMultiLingual multiLingual, + string culture = null, + bool fallbackToParentCultures = true) + where TMultiLingual : IMultiLingualObject + where TTranslation : class, IObjectTranslation; + } +} diff --git a/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IObjectTranslation.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IObjectTranslation.cs new file mode 100644 index 0000000000..c1a8caa492 --- /dev/null +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/IObjectTranslation.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.MultiLingualObjects +{ + public interface IObjectTranslation + { + string Language { get; set; } + } +} diff --git a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectManager.cs b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs similarity index 53% rename from framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectManager.cs rename to framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs index dc6a82a28d..e7185ec0c4 100644 --- a/framework/src/Volo.Abp.MultiLingualObject/Volo/Abp/MultiLingualObject/MultiLingualObjectManager.cs +++ b/framework/src/Volo.Abp.MultiLingualObjects/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager.cs @@ -6,9 +6,8 @@ using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.Settings; -using Volo.Abp.Threading; -namespace Volo.Abp.MultiLingualObject +namespace Volo.Abp.MultiLingualObjects { public class MultiLingualObjectManager : IMultiLingualObjectManager, ITransientDependency { @@ -21,27 +20,16 @@ namespace Volo.Abp.MultiLingualObject SettingProvider = settingProvider; } - public TTranslation GetTranslation( - TMultiLingual multiLingual, - bool fallbackToParentCultures = true, - string culture = null) - where TMultiLingual : IHasMultiLingual - where TTranslation : class, IMultiLingualTranslation - { - return AsyncHelper.RunSync(() => - GetTranslationAsync(multiLingual, fallbackToParentCultures, culture)); - } - public virtual async Task GetTranslationAsync( TMultiLingual multiLingual, - bool fallbackToParentCultures = true, - string culture = null) - where TMultiLingual : IHasMultiLingual - where TTranslation : class, IMultiLingualTranslation + string culture = null, + bool fallbackToParentCultures = true) + where TMultiLingual : IMultiLingualObject + where TTranslation : class, IObjectTranslation { culture ??= CultureInfo.CurrentUICulture.Name; - if (multiLingual.Translations == null || !multiLingual.Translations.Any()) + if (multiLingual.Translations.IsNullOrEmpty()) { return null; } @@ -54,9 +42,12 @@ namespace Volo.Abp.MultiLingualObject if (fallbackToParentCultures) { - translation = - GeTranslationBasedOnCulturalRecursive( - CultureInfo.CurrentUICulture.Parent, multiLingual.Translations, 0); + translation = GetTranslationBasedOnCulturalRecursive( + CultureInfo.CurrentUICulture.Parent, + multiLingual.Translations, + 0 + ); + if (translation != null) { return translation; @@ -75,21 +66,20 @@ namespace Volo.Abp.MultiLingualObject return translation; } - protected virtual TTranslation GeTranslationBasedOnCulturalRecursive( + protected virtual TTranslation GetTranslationBasedOnCulturalRecursive( CultureInfo culture, ICollection translations, int currentDepth) - where TTranslation : class, IMultiLingualTranslation + where TTranslation : class, IObjectTranslation { - if (culture == null || culture.Name.IsNullOrWhiteSpace() || translations.IsNullOrEmpty() || + if (culture == null || + culture.Name.IsNullOrWhiteSpace() || + translations.IsNullOrEmpty() || currentDepth > MaxCultureFallbackDepth) { return null; } - var translation = translations.FirstOrDefault(pt => - pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase)); - return translation ?? - GeTranslationBasedOnCulturalRecursive(culture.Parent, - translations, currentDepth + 1); + var translation = translations.FirstOrDefault(pt => pt.Language.Equals(culture.Name, StringComparison.OrdinalIgnoreCase)); + return translation ?? GetTranslationBasedOnCulturalRecursive(culture.Parent, translations, currentDepth + 1); } } } diff --git a/framework/src/Volo.Abp.Quartz/Volo.Abp.Quartz.csproj b/framework/src/Volo.Abp.Quartz/Volo.Abp.Quartz.csproj index 0fcc4da9f2..3566c9fabb 100644 --- a/framework/src/Volo.Abp.Quartz/Volo.Abp.Quartz.csproj +++ b/framework/src/Volo.Abp.Quartz/Volo.Abp.Quartz.csproj @@ -15,9 +15,9 @@ - - - + + + diff --git a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj index d2d0f0f13a..c7fa0a1d11 100644 --- a/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj +++ b/framework/src/Volo.Abp.Swashbuckle/Volo.Abp.Swashbuckle.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj index af14f9e42e..506b086a88 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -15,7 +15,7 @@ - + diff --git a/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj b/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj index 20a4521445..30206bb255 100644 --- a/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj +++ b/framework/src/Volo.Abp.Timing/Volo.Abp.Timing.csproj @@ -25,7 +25,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj index 7fa17a9fe7..b0cd1e1aeb 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj index fb39407b4b..b2515b431e 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Demo.csproj @@ -16,7 +16,7 @@ - + diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj index 9c96018145..728ea04844 100644 --- a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj +++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo.Abp.AspNetCore.Serilog.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDto_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDto_Tests.cs deleted file mode 100644 index 0efb72625b..0000000000 --- a/framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperMultiLingualDto_Tests.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp; -using Volo.Abp.AutoMapper; -using Volo.Abp.Localization; -using Volo.Abp.MultiLingualObject.TestObjects; -using Volo.Abp.Testing; -using Xunit; - -namespace AutoMapper -{ - public class AbpAutoMapperMultiLingualDto_Tests : AbpIntegratedTest - { - private readonly Volo.Abp.ObjectMapping.IObjectMapper _objectMapper; - private readonly MultiLingualBook _book; - - public AbpAutoMapperMultiLingualDto_Tests() - { - _objectMapper = ServiceProvider.GetRequiredService(); - - var id = Guid.NewGuid(); - _book = new MultiLingualBook(id, 100) - { - Translations = new List() - }; - - var en = new MultiLingualBookTranslation - { - Language = "en", - Name = "C# in Depth", - }; - var zh = new MultiLingualBookTranslation - { - Language = "zh-Hans", - Name = "深入理解C#", - }; - - _book.Translations.Add(en); - _book.Translations.Add(zh); - } - - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - - [Fact] - public void Should_Map_Current_UI_Culture() - { - using (CultureHelper.Use("zh-Hans")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("深入理解C#"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void Should_Map_Fallback_UI_Culture() - { - using (CultureHelper.Use("en-us")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("C# in Depth"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void Should_Map_Default_Language() - { - using (CultureHelper.Use("tr")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("C# in Depth"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void NoTranslations_ShouldStillMapObject() - { - _book.Translations.Clear(); - - using (CultureHelper.Use("tr")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBeNull(); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - } - - public class BookProfile : Profile - { - public BookProfile() - { - var mapResult = this.CreateMultiLingualMap(); - - mapResult.EntityMap.ValidateMemberList(MemberList.None); - mapResult.TranslateMap.ValidateMemberList(MemberList.None); - } - } -} diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj index 37ffca1657..2bedb82ed5 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs index 6e9fb10bf2..fcc9918dd4 100644 --- a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs @@ -1,13 +1,11 @@ using Volo.Abp.Modularity; -using Volo.Abp.MultiLingualObject; using Volo.Abp.ObjectExtending; namespace Volo.Abp.AutoMapper { [DependsOn( typeof(AbpAutoMapperModule), - typeof(AbpObjectExtendingTestModule), - typeof(AbpMultiLingualObjectModule) + typeof(AbpObjectExtendingTestModule) )] public class AutoMapperTestModule : AbpModule { diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObject_Tests.cs b/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObject_Tests.cs deleted file mode 100644 index 917a11a2a8..0000000000 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObject_Tests.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Shouldly; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Localization; -using Volo.Abp.MultiLingualObject.TestObjects; -using Volo.Abp.ObjectMapping; -using Volo.Abp.Testing; -using Xunit; - -namespace Volo.Abp.MultiLingualObject -{ - public class MultiLingualObject_Tests : AbpIntegratedTest - { - private readonly IObjectMapper _objectMapper; - private readonly MultiLingualBook _book; - - public MultiLingualObject_Tests() - { - _objectMapper = ServiceProvider.GetRequiredService(); - - var id = Guid.NewGuid(); - _book = new MultiLingualBook(id, 100) - { - Translations = new List() - }; - - var en = new MultiLingualBookTranslation - { - Language = "en", - Name = "C# in Depth", - }; - var zh = new MultiLingualBookTranslation - { - Language = "zh-Hans", - Name = "深入理解C#", - }; - - _book.Translations.Add(en); - _book.Translations.Add(zh); - } - - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - - [Fact] - public void Should_Map_Current_UI_Culture() - { - using (CultureHelper.Use("zh-Hans")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("深入理解C#"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void Should_Map_Fallback_UI_Culture() - { - using (CultureHelper.Use("en-us")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("C# in Depth"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void Should_Map_Default_Language() - { - using (CultureHelper.Use("tr")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBe("C# in Depth"); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - - [Fact] - public void NoTranslations_ShouldStillMapObject() - { - _book.Translations.Clear(); - - using (CultureHelper.Use("tr")) - { - var bookDto = _objectMapper.Map(_book); - - bookDto.Name.ShouldBeNull(); - bookDto.Price.ShouldBe(_book.Price); - bookDto.Id.ShouldBe(_book.Id); - } - } - } - - public class MultiLingualBookObjectMapper : IObjectMapper, - ITransientDependency - { - private readonly IMultiLingualObjectManager _multiLingualObjectManager; - - public MultiLingualBookObjectMapper(IMultiLingualObjectManager multiLingualObjectManager) - { - _multiLingualObjectManager = multiLingualObjectManager; - } - - public MultiLingualBookDto Map(MultiLingualBook source) - { - var translation = - _multiLingualObjectManager.GetTranslation(source); - - return new MultiLingualBookDto - { - Price = source.Price, - Id = source.Id, - Name = translation?.Name - }; - } - - public MultiLingualBookDto Map(MultiLingualBook source, MultiLingualBookDto destination) - { - return default; - } - } -} diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookTranslation.cs b/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookTranslation.cs deleted file mode 100644 index 5f35554078..0000000000 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookTranslation.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Volo.Abp.MultiLingualObject.TestObjects -{ - public class MultiLingualBookTranslation : IMultiLingualTranslation - { - public string Name { get; set; } - - public string Language { get; set; } - } -} diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo.Abp.MultiLingualObject.Tests.csproj b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo.Abp.MultiLingualObjects.Tests.csproj similarity index 93% rename from framework/test/Volo.Abp.MultiLingualObject.Tests/Volo.Abp.MultiLingualObject.Tests.csproj rename to framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo.Abp.MultiLingualObjects.Tests.csproj index 52d2f7ac2f..164a5da272 100644 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo.Abp.MultiLingualObject.Tests.csproj +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo.Abp.MultiLingualObjects.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectTestModule.cs b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsTestModule.cs similarity index 60% rename from framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectTestModule.cs rename to framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsTestModule.cs index f8f79a3065..d563a6aab3 100644 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/AbpMultiLingualObjectTestModule.cs +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/AbpMultiLingualObjectsTestModule.cs @@ -1,21 +1,20 @@ -using Autofac.Extensions.DependencyInjection; -using Volo.Abp.Autofac; +using Volo.Abp.Autofac; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.ObjectMapping; using Volo.Abp.Settings; -namespace Volo.Abp.MultiLingualObject +namespace Volo.Abp.MultiLingualObjects { [DependsOn( typeof(AbpAutofacModule), typeof(AbpLocalizationModule), typeof(AbpSettingsModule), typeof(AbpObjectMappingModule), - typeof(AbpMultiLingualObjectModule), + typeof(AbpMultiLingualObjectsModule), typeof(AbpTestBaseModule) )] - public class AbpMultiLingualObjectTestModule : AbpModule + public class AbpMultiLingualObjectsTestModule : AbpModule { } } diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObjectManager_Tests.cs b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager_Tests.cs similarity index 80% rename from framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObjectManager_Tests.cs rename to framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager_Tests.cs index 269bf91b54..d3d5ae3617 100644 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/MultiLingualObjectManager_Tests.cs +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/MultiLingualObjectManager_Tests.cs @@ -4,13 +4,13 @@ using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using Shouldly; using Volo.Abp.Localization; -using Volo.Abp.MultiLingualObject.TestObjects; +using Volo.Abp.MultiLingualObjects.TestObjects; using Volo.Abp.Testing; using Xunit; -namespace Volo.Abp.MultiLingualObject +namespace Volo.Abp.MultiLingualObjects { - public class MultiLingualObjectManager_Tests : AbpIntegratedTest + public class MultiLingualObjectManager_Tests : AbpIntegratedTest { private readonly IMultiLingualObjectManager _multiLingualObjectManager; private readonly MultiLingualBook _book; @@ -40,17 +40,6 @@ namespace Volo.Abp.MultiLingualObject _book.Translations.Add(zh); } - [Fact] - public void GetTranslation() - { - using (CultureHelper.Use("en-us")) - { - var translation = _multiLingualObjectManager.GetTranslation(_book); - - translation.Name.ShouldBe("C# in Depth"); - } - } - [Fact] public async Task GetTranslationAsync() { diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBook.cs b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBook.cs similarity index 72% rename from framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBook.cs rename to framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBook.cs index d12022a44b..2dcae93b73 100644 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBook.cs +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBook.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -namespace Volo.Abp.MultiLingualObject.TestObjects +namespace Volo.Abp.MultiLingualObjects.TestObjects { - public class MultiLingualBook : IHasMultiLingual + public class MultiLingualBook : IMultiLingualObject { public MultiLingualBook(Guid id, decimal price) { diff --git a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookDto.cs b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookDto.cs similarity index 79% rename from framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookDto.cs rename to framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookDto.cs index 8814f9a855..fe5868074f 100644 --- a/framework/test/Volo.Abp.MultiLingualObject.Tests/Volo/Abp/MultiLingualObject/TestObjects/MultiLingualBookDto.cs +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookDto.cs @@ -1,6 +1,6 @@ using System; -namespace Volo.Abp.MultiLingualObject.TestObjects +namespace Volo.Abp.MultiLingualObjects.TestObjects { public class MultiLingualBookDto { diff --git a/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookTranslation.cs b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookTranslation.cs new file mode 100644 index 0000000000..e1b85df173 --- /dev/null +++ b/framework/test/Volo.Abp.MultiLingualObjects.Tests/Volo/Abp/MultiLingualObjects/TestObjects/MultiLingualBookTranslation.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.MultiLingualObjects.TestObjects +{ + public class MultiLingualBookTranslation : IObjectTranslation + { + public string Name { get; set; } + + public string Language { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogFeatureAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogFeatureAdminAppService.cs index 008081367d..b6be3b3a47 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogFeatureAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogFeatureAdminAppService.cs @@ -3,11 +3,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.Application.Services; using Volo.CmsKit.Blogs; namespace Volo.CmsKit.Admin.Blogs { - public interface IBlogFeatureAdminAppService + public interface IBlogFeatureAdminAppService : IApplicationService { Task SetAsync(Guid blogId, BlogFeatureInputDto dto); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs index a6660a324f..1c42d3cf92 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs @@ -1,8 +1,9 @@ using System.Threading.Tasks; +using Volo.Abp.Application.Services; namespace Volo.CmsKit.Admin.Tags { - public interface IEntityTagAdminAppService + public interface IEntityTagAdminAppService : IApplicationService { Task AddTagToEntityAsync(EntityTagCreateDto input); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs index 5e8067ed6f..5c4d2fe22e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs @@ -11,7 +11,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { [RequiresGlobalFeature(typeof(BlogsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Authorize(CmsKitAdminPermissions.Blogs.Default)] [Route("api/cms-kit-admin/blogs")] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminController.cs index 46cdf2fe54..65ed95f646 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminController.cs @@ -12,7 +12,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { [RequiresGlobalFeature(typeof(BlogsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Authorize(CmsKitAdminPermissions.Blogs.Features)] [Route("api/cms-kit-admin/blogs/{blogId}/features")] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index a9b0727c17..72f16c5ef2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -11,7 +11,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { [RequiresGlobalFeature(typeof(BlogsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] [Route("api/cms-kit-admin/blogs/blog-posts")] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Comments/CommentAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Comments/CommentAdminController.cs index 91482d137a..e74e413534 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Comments/CommentAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Comments/CommentAdminController.cs @@ -12,7 +12,7 @@ namespace Volo.CmsKit.Admin.Comments { [Authorize(CmsKitAdminPermissions.Comments.Default)] [RequiresGlobalFeature(typeof(CommentsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Route("api/cms-kit-admin/comments")] public class CommentAdminController : CmsKitAdminController, ICommentAdminAppService diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs index 91cd5170a5..da84dc8a3d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminController.cs @@ -12,7 +12,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.MediaDescriptors { [RequiresGlobalFeature(typeof(MediaFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Route("api/cms-kit-admin/media")] public class MediaDescriptorAdminController : CmsKitAdminController, IMediaDescriptorAdminAppService diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs index 810f09330f..3b11c3f850 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Pages/PageAdminController.cs @@ -11,7 +11,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Pages { [RequiresGlobalFeature(typeof(PagesFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Authorize(CmsKitAdminPermissions.Pages.Default)] [Route("api/cms-kit-admin/pages")] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs index 532fae8554..80f483c856 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs @@ -9,7 +9,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Tags { [RequiresGlobalFeature(typeof(TagsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Route("api/cms-kit-admin/entity-tags")] public class EntityTagAdminController : CmsKitAdminController, IEntityTagAdminAppService diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs index 4655c60bd6..064fc203aa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/TagAdminController.cs @@ -14,7 +14,7 @@ using Volo.CmsKit.Tags; namespace Volo.CmsKit.Admin.Tags { [RequiresGlobalFeature(typeof(TagsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitAdminRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Authorize(CmsKitAdminPermissions.Tags.Default)] [Route("api/cms-kit-admin/tags")] diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js index 669a25ee8c..ac91dfe150 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Web/Pages/CmsKit/Blogs/updateModal.js @@ -2,7 +2,7 @@ $(function () { abp.modals.updateBlog = function () { var initModal = function (publicApi, args) { - debugger; + var $slug = $('#ViewModel_Slug'); $slug.on('change', function () { diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/IBlogFeatureAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/IBlogFeatureAppService.cs index 968a820ae9..52a1dbd71a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/IBlogFeatureAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Blogs/IBlogFeatureAppService.cs @@ -1,9 +1,10 @@ using System; using System.Threading.Tasks; +using Volo.Abp.Application.Services; namespace Volo.CmsKit.Blogs { - public interface IBlogFeatureAppService + public interface IBlogFeatureAppService : IApplicationService { Task GetOrDefaultAsync(Guid blogId, string featureName); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Blogs/BlogFeatureAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Blogs/BlogFeatureAppService.cs index f5a796a33b..5f6a38c95c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Blogs/BlogFeatureAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Blogs/BlogFeatureAppService.cs @@ -2,9 +2,12 @@ using System; using System.Threading.Tasks; using Volo.Abp.Caching; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; namespace Volo.CmsKit.Blogs { + [RequiresGlobalFeature(typeof(BlogsFeature))] public class BlogFeatureAppService : CmsKitAppServiceBase, IBlogFeatureAppService { protected virtual IBlogFeatureRepository BlogFeatureRepository { get; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/Volo/CmsKit/CmsKitCommonHttpApiClientModule.cs b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/Volo/CmsKit/CmsKitCommonHttpApiClientModule.cs index a1eff90aa4..e46e347d22 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/Volo/CmsKit/CmsKitCommonHttpApiClientModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi.Client/Volo/CmsKit/CmsKitCommonHttpApiClientModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Http.Client; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Http.Client; using Volo.Abp.Modularity; namespace Volo.CmsKit @@ -9,5 +10,12 @@ namespace Volo.CmsKit )] public class CmsKitCommonHttpApiClientModule : AbpModule { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddHttpClientProxies( + typeof(CmsKitCommonApplicationContractsModule).Assembly, + CmsKitCommonRemoteServiceConsts.RemoteServiceName + ); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitCommonHttpApiModule.cs b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitCommonHttpApiModule.cs index b839fe9ef7..e94344d1a0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitCommonHttpApiModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.HttpApi/Volo/CmsKit/CmsKitCommonHttpApiModule.cs @@ -1,4 +1,5 @@ using Localization.Resources.AbpUi; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.Localization; using Volo.Abp.Modularity; @@ -12,6 +13,15 @@ namespace Volo.CmsKit )] public class CmsKitCommonHttpApiModule : AbpModule { + + public override void PreConfigureServices(ServiceConfigurationContext context) + { + PreConfigure(mvcBuilder => + { + mvcBuilder.AddApplicationPartIfNotExists(typeof(CmsKitCommonHttpApiModule).Assembly); + }); + } + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs index adfe84228e..ed0b01e69f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/GlobalCmsKitFeatures.cs @@ -10,7 +10,7 @@ namespace Volo.CmsKit.GlobalFeatures public ReactionsFeature Reactions => GetFeature(); public CommentsFeature Comments => GetFeature(); - + public MediaFeature Media => GetFeature(); public RatingsFeature Ratings => GetFeature(); @@ -19,6 +19,8 @@ namespace Volo.CmsKit.GlobalFeatures public PagesFeature Pages => GetFeature(); + public BlogsFeature Blogs => GetFeature(); + public CmsUserFeature User => GetFeature(); public GlobalCmsKitFeatures([NotNull] GlobalFeatureManager featureManager) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index b0dfb01ecd..2d43eb3fa5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -64,7 +64,8 @@ namespace Volo.CmsKit.MongoDB.Blogs { var token = GetCancellationToken(cancellationToken); var dbContext = await GetDbContextAsync(token); - var blogPostQueryable = dbContext.Collection().AsQueryable(); + var blogPostQueryable = await GetQueryableAsync(); + var usersQueryable = dbContext.Collection().AsQueryable(); var queryable = blogPostQueryable diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index 7034b37f98..3878d0a907 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -9,7 +9,7 @@ using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Tags; using Volo.CmsKit.Users; -using Tag = MongoDB.Driver.Tag; +using Tag = Volo.CmsKit.Tags.Tag; namespace Volo.CmsKit.MongoDB { diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index 1dbbfc0f98..8f6e4625c0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -9,7 +9,7 @@ using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; using Volo.CmsKit.Tags; using Volo.CmsKit.Users; -using Tag = MongoDB.Driver.Tag; +using Tag = Volo.CmsKit.Tags.Tag; namespace Volo.CmsKit.MongoDB { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs index 4709e1219c..b74cc70dbf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs @@ -1,13 +1,11 @@ using JetBrains.Annotations; -using System; -using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; -using Volo.Abp.Content; +using Volo.Abp.Application.Services; namespace Volo.CmsKit.Public.Blogs { - public interface IBlogPostPublicAppService + public interface IBlogPostPublicAppService : IApplicationService { Task> GetListAsync([NotNull] string blogSlug, PagedAndSortedResultRequestDto input); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/IPagePublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/IPagePublicAppService.cs index 1e37e92b71..f81887d360 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/IPagePublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Pages/IPagePublicAppService.cs @@ -1,9 +1,10 @@ -using System.Threading.Tasks; -using JetBrains.Annotations; +using JetBrains.Annotations; +using System.Threading.Tasks; +using Volo.Abp.Application.Services; namespace Volo.CmsKit.Public.Pages { - public interface IPagePublicAppService + public interface IPagePublicAppService : IApplicationService { Task FindBySlugAsync([NotNull] string slug); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs index b1f18e2511..7d36b60160 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Tags/TagPublicController.cs @@ -9,7 +9,7 @@ using Volo.CmsKit.Tags; namespace Volo.CmsKit.Public.Tags { [RequiresGlobalFeature(typeof(TagsFeature))] - [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Route("api/cms-kit-public/tags")] public class TagPublicController : CmsKitPublicControllerBase, ITagAppService diff --git a/npm/ng-packs/packages/components/page/src/page.component.html b/npm/ng-packs/packages/components/page/src/page.component.html index ffb01a14bc..71715fd82e 100644 --- a/npm/ng-packs/packages/components/page/src/page.component.html +++ b/npm/ng-packs/packages/components/page/src/page.component.html @@ -1,41 +1,41 @@
- - - - + + - - - - + + - - - - + +
-
-

- {{ title }} -

-
+ +
+

+ {{ title }} +

+
+
-
- -
+ +
+ +
+
-
- -
+ +
+ +
+
diff --git a/npm/ng-packs/packages/components/page/src/page.component.ts b/npm/ng-packs/packages/components/page/src/page.component.ts index 3536dc0357..49e884fb2c 100644 --- a/npm/ng-packs/packages/components/page/src/page.component.ts +++ b/npm/ng-packs/packages/components/page/src/page.component.ts @@ -13,11 +13,19 @@ import { }) export class PageComponent { @Input() title: string; - @Input() record: any; - @Input() titleVisible = true; - @Input() breadcrumbVisible = true; - @Input() toolbarVisible = true; + toolbarVisible = false; + _toolbarData: any; + @Input('toolbar') set toolbarData(val: any) { + this._toolbarData = val; + this.toolbarVisible = true; + } + + get toolbarData() { + return this._toolbarData; + } + + @Input('breadcrumb') breadcrumbVisible = true; pageParts = { title: PageParts.title, diff --git a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts index 390a46db8e..dbcb2c8517 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/multi-tenancy-utils.ts @@ -41,41 +41,40 @@ export async function parseTenantFromUrl(injector: Injector) { }), ) .toPromise(); + } else { + /** + * If there is no tenant, we still have to clean up {0}. from baseUrl to avoid incorrect http requests. + */ + setEnvironment(injector, '', tenancyPlaceholder + '.'); } return Promise.resolve(); } -function setEnvironment(injector: Injector, tenancyName: string) { +function setEnvironment(injector: Injector, tenancyName: string, placeholder = tenancyPlaceholder) { const environmentService = injector.get(EnvironmentService); const environment = clone(environmentService.getEnvironment()) as Environment; if (environment.application.baseUrl) { environment.application.baseUrl = environment.application.baseUrl.replace( - tenancyPlaceholder, + placeholder, tenancyName, ); } if (environment.oAuthConfig.redirectUri) { environment.oAuthConfig.redirectUri = environment.oAuthConfig.redirectUri.replace( - tenancyPlaceholder, + placeholder, tenancyName, ); } - environment.oAuthConfig.issuer = environment.oAuthConfig.issuer.replace( - tenancyPlaceholder, - tenancyName, - ); + environment.oAuthConfig.issuer = environment.oAuthConfig.issuer.replace(placeholder, tenancyName); Object.keys(environment.apis).forEach(api => { Object.keys(environment.apis[api]).forEach(key => { - environment.apis[api][key] = environment.apis[api][key].replace( - tenancyPlaceholder, - tenancyName, - ); + environment.apis[api][key] = environment.apis[api][key].replace(placeholder, tenancyName); }); }); diff --git a/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html b/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html index 90b3fe9c9e..a1334e5f95 100644 --- a/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html +++ b/npm/ng-packs/packages/setting-management/src/lib/components/setting-management.component.html @@ -1,4 +1,4 @@ - +
diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index 006f5c79d4..9fd545dc35 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -147,7 +147,6 @@ $projects = ( "framework/src/Volo.Abp.Validation", "framework/src/Volo.Abp.VirtualFileSystem", "framework/src/Volo.Abp.Kafka", - "framework/src/Volo.Abp.MultiLingualObject", "framework/src/Volo.Abp.Swashbuckle", # modules/account @@ -260,12 +259,16 @@ $projects = ( "modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.WebAssembly", # modules/setting-management + "modules/setting-management/src/Volo.Abp.SettingManagement.Application.Contracts", + "modules/setting-management/src/Volo.Abp.SettingManagement.Application", "modules/setting-management/src/Volo.Abp.SettingManagement.Blazor", "modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.Server", "modules/setting-management/src/Volo.Abp.SettingManagement.Blazor.WebAssembly", "modules/setting-management/src/Volo.Abp.SettingManagement.Domain", "modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared", "modules/setting-management/src/Volo.Abp.SettingManagement.EntityFrameworkCore", + "modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi.Client", + "modules/setting-management/src/Volo.Abp.SettingManagement.HttpApi", "modules/setting-management/src/Volo.Abp.SettingManagement.MongoDB", "modules/setting-management/src/Volo.Abp.SettingManagement.Web", diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj index 55e8952172..b691486fc0 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server.Tiered/MyCompanyName.MyProjectName.Blazor.Server.Tiered.csproj @@ -14,7 +14,7 @@ - + @@ -52,4 +52,4 @@ - \ No newline at end of file + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj index ee1b9d8a9c..f764a3f82f 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Blazor.Server/MyCompanyName.MyProjectName.Blazor.Server.csproj @@ -14,7 +14,7 @@ - + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj index a8938a59f3..26ae8ce6c3 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations/MyCompanyName.MyProjectName.EntityFrameworkCore.DbMigrations.csproj @@ -13,8 +13,8 @@ - all runtime; build; native; contentfiles; analyzers + compile; contentFiles; build; buildMultitargeting; buildTransitive; analyzers; native diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj index 3f2e3a1bd0..ec64f8b082 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj @@ -10,7 +10,7 @@ - + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj index 7483325232..b24dc50c4e 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.HttpApi.HostWithIds/MyCompanyName.MyProjectName.HttpApi.HostWithIds.csproj @@ -10,7 +10,7 @@ - + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj index 7c512b79db..56210d82ff 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj @@ -32,7 +32,7 @@ - + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj index 147e21ad18..115c35de50 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj @@ -16,7 +16,7 @@ - + diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj index a0f3449eab..56ec66098c 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/MyCompanyName.MyProjectName.Web.csproj @@ -32,7 +32,7 @@ - + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index 1b92fbb738..bb38c32f74 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj index bc1f5389d4..914ca98873 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj index b1cf8ab6e0..dcbb7fe3a6 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj @@ -14,7 +14,7 @@ - + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj index 06e9ef3430..333f9dd2ea 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj index 6e2e2a2071..dc97795afc 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj @@ -15,12 +15,12 @@ - + - + - + diff --git a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj index e9f915231a..f4e2263bae 100644 --- a/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj +++ b/templates/app/aspnet-core/test/MyCompanyName.MyProjectName.Web.Tests/MyCompanyName.MyProjectName.Web.Tests.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/templates/module/aspnet-core/common.props b/templates/module/aspnet-core/common.props index 1e88b23715..7f8f815100 100644 --- a/templates/module/aspnet-core/common.props +++ b/templates/module/aspnet-core/common.props @@ -8,7 +8,7 @@ - + All runtime; build; native; contentfiles; analyzers diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj index 1705d64e93..ee2b36f016 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.HttpApi.Host/MyCompanyName.MyProjectName.HttpApi.Host.csproj @@ -10,9 +10,9 @@ - + - + diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj index 11905455a4..84a1d50169 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.IdentityServer/MyCompanyName.MyProjectName.IdentityServer.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj index 2476a0ff07..e4389e0bda 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Host/MyCompanyName.MyProjectName.Web.Host.csproj @@ -10,7 +10,7 @@ - + diff --git a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj index 8124338091..ab9d27e450 100644 --- a/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj +++ b/templates/module/aspnet-core/host/MyCompanyName.MyProjectName.Web.Unified/MyCompanyName.MyProjectName.Web.Unified.csproj @@ -10,7 +10,7 @@ - + all diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index 29889c1888..bb28f75669 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj index b2818d0afd..803693448d 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.Domain.Tests/MyCompanyName.MyProjectName.Domain.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj index 265806176f..27fc557dfd 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj index fb807fa2d1..069545e840 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.MongoDB.Tests/MyCompanyName.MyProjectName.MongoDB.Tests.csproj @@ -8,8 +8,8 @@ - - + + diff --git a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj index 8b8105cb05..faf15c5a1f 100644 --- a/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj +++ b/templates/module/aspnet-core/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj @@ -8,12 +8,12 @@ - + - + - +