diff --git a/.github/workflows/auto-pr.yml b/.github/workflows/auto-pr.yml
index 647397ea04..4f28b14a9c 100644
--- a/.github/workflows/auto-pr.yml
+++ b/.github/workflows/auto-pr.yml
@@ -1,13 +1,13 @@
-name: Merge branch dev with prerel-9.0
+name: Merge branch dev with rel-9.0
on:
push:
branches:
- - prerel-9.0
+ - rel-9.0
permissions:
contents: read
jobs:
- merge-dev-with-prerel-9-0:
+ merge-dev-with-rel-9-0:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR
@@ -18,19 +18,19 @@ jobs:
ref: dev
- name: Reset promotion branch
run: |
- git fetch origin prerel-9.0:prerel-9.0
- git reset --hard prerel-9.0
+ git fetch origin rel-9.0:rel-9.0
+ git reset --hard rel-9.0
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
- branch: auto-merge/prerel-9-0/${{github.run_number}}
- title: Merge branch dev with prerel-9.0
- body: This PR generated automatically to merge dev with prerel-9.0. Please review the changed files before merging to prevent any errors that may occur.
+ branch: auto-merge/rel-9-0/${{github.run_number}}
+ title: Merge branch dev with rel-9.0
+ body: This PR generated automatically to merge dev with rel-9.0. Please review the changed files before merging to prevent any errors that may occur.
reviewers: maliming
token: ${{ github.token }}
- name: Merge Pull Request
env:
GH_TOKEN: ${{ secrets.BOT_SECRET }}
run: |
- gh pr review auto-merge/prerel-9-0/${{github.run_number}} --approve
- gh pr merge auto-merge/prerel-9-0/${{github.run_number}} --merge --auto --delete-branch
+ gh pr review auto-merge/rel-9-0/${{github.run_number}} --approve
+ gh pr merge auto-merge/rel-9-0/${{github.run_number}} --merge --auto --delete-branch
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index b535d05afa..6991b372b7 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -6,7 +6,7 @@
-
+
@@ -166,6 +166,7 @@
+
diff --git a/common.props b/common.props
index f189fd7d3f..fda9b5e35b 100644
--- a/common.props
+++ b/common.props
@@ -1,8 +1,8 @@
latest
- 9.0.0-preview
- 4.0.0-preview
+ 9.1.0-preview
+ 4.1.0-preview$(NoWarn);CS1591;CS0436https://abp.io/assets/abp_nupkg.pnghttps://abp.io/
diff --git a/docs/en/Community-Articles/2024-06-27-how-to-use-Aspire-with-ABP-framework/How to use Aspire with ABP framework.md b/docs/en/Community-Articles/2024-06-27-how-to-use-Aspire-with-ABP-framework/How to use Aspire with ABP framework.md
index 7d78d476c5..4afe83c7c9 100644
--- a/docs/en/Community-Articles/2024-06-27-how-to-use-Aspire-with-ABP-framework/How to use Aspire with ABP framework.md
+++ b/docs/en/Community-Articles/2024-06-27-how-to-use-Aspire-with-ABP-framework/How to use Aspire with ABP framework.md
@@ -300,3 +300,7 @@ After making all our changes, we can run the `AspirationalAbp.AppHost` project.
## Conclusion
Combining .NET Aspire with the ABP framework creates a powerful setup for building robust, observable, and feature-rich applications. By integrating Aspire's observability and cloud capabilities with ABP's approach of focusing on your business without repeating yourself, you can develop feature-rich, scalable applications with enhanced monitoring and seamless cloud integration. This guide provides a clear path to set up and configure these technologies, ensuring your applications are well-structured, maintainable, and ready for modern cloud environments.
+
+## See Also
+
+* [.NET Aspire vs ABP Studio: Side by Side](https://abp.io/community/articles/.net-aspire-vs-abp-studio-side-by-side-t1c73d1l)
diff --git a/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/Post.md b/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/Post.md
new file mode 100644
index 0000000000..bac7f69596
--- /dev/null
+++ b/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/Post.md
@@ -0,0 +1,63 @@
+# When to Use Cookies, When to Use Local Storage?
+
+
+
+
+
+## Cookies vs Local Storage
+
+When you want to save client-side data on browsers, you can use `Cookies` or `Local Storage` of the browser. While these methods look similar, they have different behaviors. You need to decide based on the specific use-case, security concerns and the data size being stored. I'll clarify the differences between these methods.
+
+
+
+## When to use Cookies đȘ?
+
+1. **Server Communication (e.g: Authentication Tokens):** Cookies are ideal when you need to send data automatically with HTTP requests to the server, such as authentication tokens (JWTs) or session IDs. Cookies can be configured to be sent only to specific domains or paths, making them useful for session management.
+2. **Cross-Domain Communication:** Cookies can be shared across subdomains, which is useful when working with multiple subdomains under the same parent domain for microservice architecture.
+3. **Expiration Control:** Cookies come with built-in expiration times. You donât need to manually remove them after a certain period that should expire.
+4. **Security:** Cookies can be marked as `HttpOnly` which makes them accessible **only via the server**, not via JavaScript! Also, when you set a cookie attribute, `Secure` it can be sent only over HTTPS, which forces enhanced security for sensitive data.
+
+
+### Considerations for Cookies
+
+- **Size Limitation:** Cookies are generally limited to around 4KB of data.
+- **Security Risks:** Cookies are susceptible to cross-site scripting (XSS) attacks unless marked `HttpOnly`.
+
+
+---
+
+
+## When to use Local Storageđïž?
+
+1. **Client-Side Data Storage:** Local storage is ideal for storing large amounts of data (up to 5â10 MB) that doesnât need to be sent to the server with every request. For example; *user preferences*, *settings*, or *cached data*.
+2. **Persistence:** Data in local storage persists even after the browser is restarted. This behavior makes it useful for long-term storage needs.
+3. **No Automatic Server Transmission:** Local storage data is never automatically sent to the server, which can be a security advantage if you donât want certain data to be exposed to the server or included in the requests.
+
+
+### Considerations for Local Storage
+
+- **Security Risks:** Local storage is accessible via JavaScript, making it vulnerable to XSS attacks. Sensitive data should not be stored in local storage unless adequately encrypted.
+
+- **No Expiration Mechanism:** Local storage does not have a built-in expiration mechanism. You must manually remove the data when itâs no longer needed.
+
+
+---
+
+
+
+## Summary
+
+### Use Cookies
+
+- For data that needs to be sent to the server with HTTP requests, particularly for session management or authentication purposes.
+
+### Use Local Storage
+
+- For storing large amounts of client-side data that doesnât need to be automatically sent to the server and for data that should persist across browser sessions.
+
+
+
+In many cases, you might use both cookies and local storage, depending on the specific requirements of different parts of your application. There are also other places where you can store the client-side data. You can check out [this article](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage) for more information.
+
+
+Happy coding đ§đœâđ»
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/cover.png b/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/cover.png
new file mode 100644
index 0000000000..68a18b85fe
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-09-Cookies-vs-Local-Storage/cover.png differ
diff --git a/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/Post.md b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/Post.md
new file mode 100644
index 0000000000..67e451f0df
--- /dev/null
+++ b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/Post.md
@@ -0,0 +1,96 @@
+# .NET 9 Performance Improvements Summary
+
+With every release, .NET becomes faster & faster! You get these improvements for free by just updating your project to the latest .NET!
+
+
+
+Itâs very interesting that **20% of these improvements** are implemented by **open-source volunteers** rather than Microsoft employees. These improvements mostly focus on cloud-native and high-throughput applications. Iâll briefly list them below.
+
+
+
+
+
+## 1. Dynamic PGO with JIT Compiler
+
+* ### What is dynamic PGO?
+ With âProfile Guided Optimizationâ the compiler optimizes the code, based on the flow and the way the code executes. It is predicated on the idea that every potential behavior of the code will always transpire.
+
+* ### Whatâs Improved?
+ The tiered compilation, inlining, and dynamic PGO are three ways that .NET 9 optimizes the JIT compiler. This enhances runtime performance and speeds up the time for apps to launch.
+
+* ### Performance Gains
+ CPU use is lower during execution; therefore, **startup times are about 15% faster**.
+
+* ### As a Developer
+ Faster, smoother deployments with reduced warm-up times... These enhancements reduce latency for applications with complex workflows, particularly in microservices and high-throughput environments.
+
+* ### How to activate Dynamic PGO?
+ Add the following to your `csproj` file, or if you have several `csproj` files, you can add it once in `Directory.Build.props` file. Check out [this link](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/compilation#profile-guided-optimization) to understand PGO.
+
+```xml
+
+ true
+
+```
+
+
+
+## 2. Library Improvements
+
+* ### Whatâs Improved?
+
+ LINQ and JSON serialization, collections and libraries are significantly improved with .NET 9.
+
+* ### Performance Gains
+
+ **JSON serialization** performance **increases by about 35%**. This helps with heavy data parsing and API requests. Less memory is allocated to `Span` operations as well, and LINQ techniques such as `Where` and `Select` are now faster.
+
+* ### As a Developer
+
+ This means that apps will be faster, especially those that handle data primarily in JSON or manipulate data with LINQ.
+
+
+
+## 3. ASP.NET Core
+
+* ### Whatâs Improved?
+ Kestrel server has undergone significant modifications, mostly in processing the HTTP/2 and HTTP/3 protocols.
+
+* ### Performance Gains
+ Now, **Kestrel handles requests up to 20% faster** and **has a 25% reduction in average latency**. Improved connection management and SSL processing also result in overall efficiency gains.
+
+* ### As a Developer
+ These modifications result in less resource use, quicker response times for web applications, and more seamless scaling in high-traffic situations.
+
+
+
+## 4. Garbage Collection & Memory Management
+
+* ### Whatâs Improved?
+ NET 9âs garbage collection (GC) is more effective, especially for apps with high allocation rates.
+
+* ### Performance Gains
+ Applications experience smoother **garbage collection cycles with 8â12% less memory overhead**, which lowers latency and delays.
+
+* ### As a Developer
+ The performance will be more reliable and predictable for developers as there will be fewer memory-related bottlenecks, particularly in applications that involve frequent object allocations.
+
+
+
+## 5. Native AOT Compilation
+
+* ### Whatâs Improved?
+ Native AOT (Ahead-of-Time) compilation is now more efficient by lowering memory footprint and cold-start times. This leads to better support for cloud-native applications.
+
+* ### Performance Gains
+ Native AOT apps now have faster cold launches and use **30â40% less memory**. This improvement focuses on containerized applications.
+
+---
+
+
+
+**References:**
+
+* [Microsoft .NET blog post](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-9/).
+* [Whatâs new in the .NET 9 runtime?](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/runtime#performance-improvements)
+
diff --git a/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cited-from-microsoft-blog-post.png b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cited-from-microsoft-blog-post.png
new file mode 100644
index 0000000000..c35771b071
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cited-from-microsoft-blog-post.png differ
diff --git a/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cover.png b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cover.png
new file mode 100644
index 0000000000..91ed380f6d
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-09-NET9-Performance-Improvements/cover.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/POST.md b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/POST.md
new file mode 100644
index 0000000000..519925de30
--- /dev/null
+++ b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/POST.md
@@ -0,0 +1,138 @@
+# .NET Aspire vs ABP Studio: Side by Side
+
+In this article, I will compare [.NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/) by [ABP Studio](https://abp.io/docs/latest/studio) by explaining their similarities and differences.
+
+
+
+## Introduction
+
+While .NET Aspire and ABP Studio are tools for different purpose with different scope and they have different approaches to solve the problems, many developers still may confuse since they also have some similar functionalities and solves some common problems.
+
+In this article, I will clarify all, and you will have a clear understanding of what are the similarities and differences of them. Let's start by briefly define what are .NET Aspire and ABP Studio.
+
+### What is .NET Aspire?
+
+**[.NET Aspire](https://learn.microsoft.com/en-us/dotnet/aspire/)** is a **cloud-ready framework** designed to simplify building distributed, observable, and production-ready applications. It provides a set of opinionated tools and NuGet packages tailored for cloud-native concerns like **orchestration**, **service integration** (e.g., Redis, PostgreSQL), and **telemetry**. Aspire focuses on the **local development experience**, making it easier to manage complex, multi-service apps by **abstracting away configuration details**.
+
+Here, a screenshot from [.NET Aspire dashboard](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/overview) that is used for application monitoring and inspection:
+
+
+
+### What is ABP Studio?
+
+**[ABP Studio](https://abp.io/docs/latest/studio)** is a cross-platform **desktop application** designed to **simplify development** on the ABP Framework by **automating various tasks** and offering a streamlined, **integrated development environment**. It allows developers to **build**, **run**, **test**, **monitor**, and **deploy applications** more efficiently. With features like Kubernetes integration and support for complex multi-application systems, ABP Studio **enhances productivity**, especially in **microservice or modular monolith architectures**.
+
+Here, a screenshot from the ABP Studio [Solution Runner panel](https://abp.io/docs/latest/studio/running-applications) that is used to run, browse, monitor and inspect applications:
+
+
+
+## A Brief Comparison
+
+Before deep diving details, I want to show a **table of features** to compare ABP Studio and .NET Aspire side by side:
+
+
+
+## Comparing the Features
+
+In the next sections, I will go through each feature and explain differences and similarities.
+
+### Integration Packages
+
+ABP Framework has tens of integration packages to 3rd-party libraries and services. .NET Aspire also has some library integrations. But these integrations have different purposes:
+
+* **ABP Framework**'s integrations (like [MongoDB](https://abp.io/docs/latest/framework/data/mongodb), [RabbitMQ](https://abp.io/docs/latest/framework/infrastructure/background-jobs/rabbitmq), [Dapr](https://abp.io/docs/latest/framework/dapr), etc) are integrations for its abstractions and aimed to be **used directly by your application code**. They are complete and sophisticated integrations with the ABP Framework and your codebase.
+* **.NET Aspire**'s integrations (like [MongoDB](https://learn.microsoft.com/en-us/dotnet/aspire/database/mongodb-integration), [RabbitMQ](https://learn.microsoft.com/en-us/dotnet/aspire/messaging/rabbitmq-integration), [Dapr](https://learn.microsoft.com/en-us/dotnet/aspire/frameworks/dapr), etc), on the other hand, for simplifying configuration, service discovery, orchestration and monitoring of these tools within .NET Aspire host. Basically, these are mostly for **integrating to .NET Aspire**, not for integrating to your application.
+
+For example, ABP's [MongoDB](https://abp.io/docs/latest/framework/data/mongodb) integration allows you to use MongoDB over [repository services](https://abp.io/docs/latest/framework/architecture/domain-driven-design/repositories), automatically handles database transactions, [audit logs](https://abp.io/docs/latest/framework/infrastructure/audit-logging), [event publishing](https://abp.io/docs/latest/framework/infrastructure/event-bus/distributed) on data saves, dynamic [connection string](https://abp.io/docs/latest/framework/fundamentals/connection-strings) management, [multi-tenancy](https://abp.io/docs/latest/framework/architecture/multi-tenancy) integration and so on.
+
+On the other hand, .NET Aspire's [MongoDB](https://learn.microsoft.com/en-us/dotnet/aspire/database/mongodb-integration) integration basically adds [MongoDB driver library](https://www.nuget.org/packages/MongoDB.Driver/) to your .NET Aspire host application and configures it so you can discover MongoDB server on runtime, use a MongoDB Docker container and see its health status, logs and traces on .NET Aspire dashboard.
+
+### Starter Templates
+
+Both of ABP Studio and .NET Aspire provide **startup solution templates for new applications**. However, there are huge differences between these startup solution templates and their purpose are completely different.
+
+* ABP Studio provides **production-ready** and [advanced solution templates](https://abp.io/docs/latest/solution-templates) for **layered**, **modular** or **microservice** solution development. They are well configured for **local development** and deploying to **Kubernetes** and other **production environments**. They provide different **UI and database options**, many optional modules and configuration. For example, you can check the [microservice solution template](https://abp.io/docs/latest/solution-templates/microservice/overview) to see how **sophisticated** it is.
+* .NET Aspire's [project templates](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/setup-tooling?tabs=windows&pivots=visual-studio#net-aspire-project-templates)' main purpose is to provide a minimal application structure that is **pre-integrated to .NET Aspire** libraries and configured for **local development** environment.
+
+So, when you start with .NET Aspire project template, you will need to deal with a lot of work to make your solution production and enterprise ready. On the other hand, ABP Studio's solution templates are ready to lunch your system from the first day and they provide you a perfect starting point for your new business idea.
+
+### Monitoring & Application Running
+
+Monitoring applications and services is an important requirement for building **complex distributed systems**. Both of ABP Studio and .NET Aspire provide **excellent tools** for that purpose.
+
+* ABP Studio's [Solution Runner panel](https://abp.io/docs/latest/studio/running-applications) provides a powerful UI to run and monitor application and services. You can see all HTTP requests, distributed events, exceptions and detailed application logs, trace and find problems in your system. You can use its fully functional built-in browser to navigate application UIs easily. You can also create multiple profiles to group and configure the applications for different teams.
+* .NET Aspire's [dashboard](https://learn.microsoft.com/en-us/dotnet/aspire/fundamentals/dashboard/overview) can be used to see the states of the running applications and containers, explore their console output, logs, traces and metrics to understand what is happing in your distributed system.
+
+Both tools are pretty useful for monitoring. In addition to monitoring, **ABP Studio offers an advanced UI to control the running applications**, build, start and stop individually or by a group of applications.
+
+### Architecting / Building Solutions
+
+One of the unique features of **ABP Studio** is that it **is an architectural tool** that helps you create the structure and architecture of your solution. You can create any kind of application, from **single-layer** simple web applications to **layered multi-application** solutions, from **monolith modular** to **microservice** systems. In the next section, I will briefly explains these architectural features.
+
+#### Building Modular Monolith Solutions
+
+With ABP Studio, you can create a new solution, **create modules and establish relations** (dependencies) between modules to architect your overall **modular monolith system** easily.
+
+Here, a screenshot where we are adding an existing package reference to the Products module of a modular CRM solution:
+
+
+
+You can see the [Modular Application Development tutorial](https://abp.io/docs/latest/tutorials/modular-crm) to learn how to build such an application step by step.
+
+#### Building Microservice Solutions
+
+ABP Studio provides a full featured [microservice startup solution template](https://abp.io/docs/latest/solution-templates/microservice) and the fundamental tooling to build **large-scale microservice systems**.
+
+Here a screenshot that shows how to add new microservices, API gateways or web applications to a microservice solution:
+
+
+
+.NET Aspire has no such a feature and has no such a plan to provide that kind of architectural solution building experience.
+
+### Kubernetes Integration
+
+Another great ABP Studio feature is [Kubernetes Integration](https://abp.io/docs/latest/studio/kubernetes). It allows you to develop your distributed / microservice solutions as integrated to [Kubernetes](https://kubernetes.io/).
+
+Here, a few tasks you can accomplish using ABP Studio's Kubernetes integration:
+
+* **Build docker images** of your applications and services
+* **Install and uninstall Helm charts** to your Kubernetes cluster
+* **Connect to internal services** of your Kubernetes cluster
+* **Monitor** services and applications that are running in your Kubernetes cluster
+* **Intercept traffic** of a service and redirect requests to your local machine. In that way, you can develop, test and run individual services or applications in your local computer that is **fully integrated** to other services and applications running in Kubernetes.
+
+ABP Studio's Kubernetes Integration makes microservice development so easy and comfortable. On the other hand, .NET Aspire has no such a Kubernetes integrated development experience.
+
+## The ABP Platform
+
+Until now, I directly compared ABP Studio and .NET Aspire features. .NET Aspire is directly built on .NET and ASP.NET Core. However, ABP Studio is not a standalone tool that is built on .NET and ASP.NET Core. It is built on the [ABP Platform](https://abp.io/) (which is built on .NET and ASP.NET Core).
+
+The following diagram shows ABP Platform components at a glance:
+
+
+
+So, when you use ABP Studio, you also take full power of the [open source ABP Framework](https://github.com/abpframework/abp) and other ABP Platform features.
+
+## ABP and .NET Aspire Integration
+
+I have a good news to you. It is actually possible and pretty easy to make ABP Platform and .NET Aspire working together.
+
+You can check [@berkansasmaz](https://abp.io/community/members/berkansasmaz)'s great article: **[How to use .NET Aspire with ABP framework](https://abp.io/community/articles/how-to-use-.net-aspire-with-abp-framework-h29km4kk)**.
+
+## Licensing
+
+ABP Studio has a Community Edition which is completely free and available to everyone. It includes many of the features I mentioned here. There is also a commercial edition that is included in [commercial ABP licenses](https://abp.io/pricing). You can [check that blog post](https://abp.io/blog/announcing-abp-studio-general-availability) which clearly explains the license differences and introduces the fundamental ABP Studio features.
+
+On the other hand, .NET Aspire is a free tool developed and published by Microsoft. It has no commercial version.
+
+## Conclusion
+
+Both .NET Aspire and ABP Studio serve distinct purposes, catering to different types of development environments. While .NET Aspire excels in simplifying cloud-native application setups and observability, ABP Studio provides a comprehensive framework for modular monoliths and microservice architectures with full-fledged enterprise level production-ready startup solution templates and integrated tools.
+
+In the previous section, it was mentioned that it is possible to [use them together](https://abp.io/community/articles/how-to-use-.net-aspire-with-abp-framework-h29km4kk). You don't have to select one of them. However, in my opinion, when you use ABP Studio, you won't need .NET Aspire since ABP Studio can do everything and much more. If you have budget, I suggest to purchase a commercial ABP Studio [license](https://abp.io/pricing) so you can fully unlock its power.
+
+## Resources / Further Reading
+
+* [ABP Studio documentation](https://abp.io/docs/latest/studio)
+* [.NET Aspire documentation](https://learn.microsoft.com/en-us/dotnet/aspire/)
+* [How to use .NET Aspire with ABP framework](https://abp.io/community/articles/how-to-use-.net-aspire-with-abp-framework-h29km4kk)
\ No newline at end of file
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-overall-diagram.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-overall-diagram.png
new file mode 100644
index 0000000000..16d397466a
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-overall-diagram.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-existing-package.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-existing-package.png
new file mode 100644
index 0000000000..27b445c6d4
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-existing-package.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-new-microservice.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-new-microservice.png
new file mode 100644
index 0000000000..5acbb8e582
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-add-new-microservice.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-solution-runner.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-solution-runner.png
new file mode 100644
index 0000000000..d761a60374
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-solution-runner.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-vs-dotnet-aspire-comparison-table.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-vs-dotnet-aspire-comparison-table.png
new file mode 100644
index 0000000000..170220507e
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/abp-studio-vs-dotnet-aspire-comparison-table.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/cover.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/cover.png
new file mode 100644
index 0000000000..cec722e760
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/cover.png differ
diff --git a/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/dotnet-aspire-dashboard.png b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/dotnet-aspire-dashboard.png
new file mode 100644
index 0000000000..e42f39d948
Binary files /dev/null and b/docs/en/Community-Articles/2024-10-11-NET-Aspire-vs-ABP-Studio/dotnet-aspire-dashboard.png differ
diff --git a/docs/en/cli/index.md b/docs/en/cli/index.md
index 9acb0bb2e8..2c8a4d894e 100644
--- a/docs/en/cli/index.md
+++ b/docs/en/cli/index.md
@@ -2,7 +2,7 @@
ABP CLI (Command Line Interface) is a command line tool to perform some common operations for ABP based solutions or ABP Studio features.
-> đ With **v8.2+**, the old/legacy ABP CLI has been replaced with a new CLI system to align with the new templating system and [ABP Studio](../studio/index.md). The new ABP CLI commands are explained in this documentation. However, if you want to learn more about the differences between the old and new CLIs, want to learn the reason for the change, or need guidance to use the old ABP CLI, please refer to the [Old vs New CLI](differences-between-old-and-new-cli.md) documentation.
+> With **v8.2+**, the old/legacy ABP CLI has been replaced with a new CLI system to align with the new templating system and [ABP Studio](../studio/index.md). The new ABP CLI commands are explained in this documentation. However, if you want to learn more about the differences between the old and new CLIs, want to learn the reason for the change, or need guidance to use the old ABP CLI, please refer to the [Old vs New CLI](differences-between-old-and-new-cli.md) documentation.
>
> You may need to remove the Old CLI before installing the New CLI, by running the following command: `dotnet tool uninstall -g Volo.Abp.Cli`
@@ -142,6 +142,9 @@ For more samples, go to [ABP CLI Create Solution Samples](new-command-samples.md
* `angular`: Angular UI. There are some additional options for this template:
* `--tiered`: The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*)
* `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application.
+ * `blazor-webapp`: Blazor Web App UI. There are some additional options for this template:
+ * `--tiered`: The Auth Server and the API Host project comes as separate projects and run at different endpoints. It has 3 startup projects: *HttpApi.Host*, *AuthServer* and *Blazor* and and each runs on different endpoints. If not specified, you will have a single endpoint for your web project.
+ * `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application.
* `blazor`: Blazor UI. There are some additional options for this template:
* `--tiered`The Auth Server project comes as a separate project and runs at a different endpoint. It separates the Auth Server from the API Host application. If not specified, you will have a single endpoint in the server side. (*Available for* ***Team*** *or higher licenses*)
* `--progressive-web-app` or `-pwa`: Specifies the project as Progressive Web Application.
diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json
index 2ffd98439a..a36e293284 100644
--- a/docs/en/docs-nav.json
+++ b/docs/en/docs-nav.json
@@ -23,19 +23,19 @@
"text": "Others",
"items": [
{
- "text": "Empty ASP.NET Core MVC / Razor Pages Application",
+ "text": "Empty ASP.NET Core Application",
"path": "get-started/empty-aspnet-core-application.md"
},
{
- "text": "MAUI Application Startup Template",
+ "text": "MAUI Application",
"path": "get-started/maui.md"
},
{
- "text": "WPF Application Startup Template",
+ "text": "WPF Application",
"path": "get-started/wpf.md"
},
{
- "text": "Console Application Startup Template",
+ "text": "Console Application",
"path": "get-started/console.md"
}
]
@@ -67,7 +67,7 @@
]
},
{
- "text": "Web Application Development",
+ "text": "Book Store Application",
"items": [
{
"text": "Overview",
@@ -657,7 +657,7 @@
"path": "framework/architecture"
},
{
- "text": "Module Development Best Practices & Conventions",
+ "text": "Module Development Best Practices",
"items": [
{
"text": "Overview",
@@ -1655,7 +1655,7 @@
"path": "solution-templates/microservice"
},
{
- "text": "Module Solution",
+ "text": "Application Module",
"path": "solution-templates/application-module"
}
]
diff --git a/docs/en/framework/architecture/domain-driven-design/specifications.md b/docs/en/framework/architecture/domain-driven-design/specifications.md
index 867080b86e..68ff038b7e 100644
--- a/docs/en/framework/architecture/domain-driven-design/specifications.md
+++ b/docs/en/framework/architecture/domain-driven-design/specifications.md
@@ -81,7 +81,7 @@ namespace MyProject
{
public class CustomerService : ITransientDependency
{
- public async Task BuyAlcohol(Customer customer)
+ public async Task BookRoom(Customer customer)
{
if (!new Age18PlusCustomerSpecification().IsSatisfiedBy(customer))
{
@@ -120,7 +120,7 @@ namespace MyProject
_customerRepository = customerRepository;
}
- public async Task> GetCustomersCanBuyAlcohol()
+ public async Task> GetCustomersCanBookRoom()
{
var queryable = await _customerRepository.GetQueryableAsync();
var query = queryable.Where(
@@ -254,4 +254,4 @@ Some benefits of using specifications:
### When To Not Use?
- **Non business expressions**: Do not use specifications for non business-related expressions and operations.
-- **Reporting**: If you are just creating a report, do not create specifications, but directly use `IQueryable` & LINQ expressions. You can even use plain SQL, views or another tool for reporting. DDD does not necessarily care about reporting, so the way you query the underlying data store can be important from a performance perspective.
\ No newline at end of file
+- **Reporting**: If you are just creating a report, do not create specifications, but directly use `IQueryable` & LINQ expressions. You can even use plain SQL, views or another tool for reporting. DDD does not necessarily care about reporting, so the way you query the underlying data store can be important from a performance perspective.
diff --git a/docs/en/framework/architecture/modularity/extending/module-entity-extensions.md b/docs/en/framework/architecture/modularity/extending/module-entity-extensions.md
index 7cb7b8e421..8a5b50652e 100644
--- a/docs/en/framework/architecture/modularity/extending/module-entity-extensions.md
+++ b/docs/en/framework/architecture/modularity/extending/module-entity-extensions.md
@@ -48,7 +48,7 @@ public static void ConfigureExtraProperties()
* `AddOrUpdateProperty` gets a second argument (the `property =>` lambda expression) to configure additional options for the new property.
* We can add data annotation attributes like shown here, just like adding a data annotation attribute to a class property.
-#### Create & Update Forms
+### Create & Update Forms
Once you define a property, it appears in the create and update forms of the related entity:
diff --git a/docs/en/framework/data/entity-framework-core/migrations.md b/docs/en/framework/data/entity-framework-core/migrations.md
index 5528b34291..93a5e3905f 100644
--- a/docs/en/framework/data/entity-framework-core/migrations.md
+++ b/docs/en/framework/data/entity-framework-core/migrations.md
@@ -4,7 +4,7 @@ This document begins by **introducing the default structure** provided by [the a
> This document is for who want to fully understand and customize the database structure comes with [the application startup template](../../../solution-templates/layered-web-application). If you simply want to create entities and manage your code first migrations, just follow [the startup tutorials](../../../tutorials/book-store/part-01.md).
-### Source Code
+## Source Code
You can find the source code of the example project referenced by this document [here](https://github.com/abpframework/abp-samples/tree/master/EfCoreMigrationDemo). However, you need to read and understand this document in order to understand the example project's source code.
@@ -554,4 +554,4 @@ This document explains how to split your databases and manage your database migr
## Source Code
-You can find the source code of the example project referenced by this document [here](https://github.com/abpframework/abp-samples/tree/master/EfCoreMigrationDemo). You can also find the changes explained in this document as a [single commit](https://github.com/abpframework/abp-samples/pull/95/commits/c2ffd76175e0a6fdfcf6477bbaea23dc2793fedd).
\ No newline at end of file
+You can find the source code of the example project referenced by this document [here](https://github.com/abpframework/abp-samples/tree/master/EfCoreMigrationDemo). You can also find the changes explained in this document as a [single commit](https://github.com/abpframework/abp-samples/pull/95/commits/c2ffd76175e0a6fdfcf6477bbaea23dc2793fedd).
diff --git a/docs/en/framework/fundamentals/exception-handling.md b/docs/en/framework/fundamentals/exception-handling.md
index 44692e8e68..a85ae58e24 100644
--- a/docs/en/framework/fundamentals/exception-handling.md
+++ b/docs/en/framework/fundamentals/exception-handling.md
@@ -31,7 +31,7 @@ Error Message is an instance of the `RemoteServiceErrorResponse` class. The simp
There are **optional fields** those can be filled based upon the exception that has occurred.
-##### Error Code
+#### Error Code
Error **code** is an optional and unique string value for the exception. Thrown `Exception` should implement the `IHasErrorCode` interface to fill this field. Example JSON value:
@@ -46,7 +46,7 @@ Error **code** is an optional and unique string value for the exception. Thrown
Error code can also be used to localize the exception and customize the HTTP status code (see the related sections below).
-##### Error Details
+#### Error Details
Error **details** in an optional field of the JSON error message. Thrown `Exception` should implement the `IHasErrorDetails` interface to fill this field. Example JSON value:
@@ -60,7 +60,7 @@ Error **details** in an optional field of the JSON error message. Thrown `Except
}
```
-##### Validation Errors
+#### Validation Errors
**validationErrors** is a standard field that is filled if the thrown exception implements the `IHasValidationErrors` interface.
@@ -340,4 +340,4 @@ Here, a list of the options you can configure:
## See Also
-* [Video tutorial](https://abp.io/video-courses/essentials/exception-handling)
\ No newline at end of file
+* [Video tutorial](https://abp.io/video-courses/essentials/exception-handling)
diff --git a/docs/en/framework/fundamentals/localization.md b/docs/en/framework/fundamentals/localization.md
index 61f8e58691..61118fd742 100644
--- a/docs/en/framework/fundamentals/localization.md
+++ b/docs/en/framework/fundamentals/localization.md
@@ -183,7 +183,7 @@ public class MyService : ITransientDependency
}
````
-##### Format Arguments
+### Format Arguments
Format arguments can be passed after the localization key. If your message is `Hello {0}, welcome!`, then you can pass the `{0}` argument to the localizer like `_localizer["HelloMessage", "John"]`.
@@ -255,4 +255,4 @@ See the following documents to learn how to reuse the same localization texts in
* [Localization for the MVC / Razor Pages UI](../ui/mvc-razor-pages/javascript-api/localization)
* [Localization for the Blazor UI](../ui/blazor/localization.md)
* [Localization for the Angular UI](../ui/angular/localization.md)
-* [Video tutorial](https://abp.io/video-courses/essentials/localization)
\ No newline at end of file
+* [Video tutorial](https://abp.io/video-courses/essentials/localization)
diff --git a/docs/en/framework/infrastructure/audit-logging.md b/docs/en/framework/infrastructure/audit-logging.md
index f14d522d25..f04bfafbe5 100644
--- a/docs/en/framework/infrastructure/audit-logging.md
+++ b/docs/en/framework/infrastructure/audit-logging.md
@@ -14,7 +14,7 @@ An **audit log object** (see the Audit Log Object section below) is typically cr
> [Startup templates](../../solution-templates) are configured for the audit logging system which is suitable for most of the applications. Use this document for a detailed control over the audit log system.
-### Database Provider Support
+## Database Provider Support
* Fully supported by the [Entity Framework Core](../data/entity-framework-core) provider.
* Entity change logging is not supported by the [MongoDB](../data/mongodb) provider. Other features work as expected.
diff --git a/docs/en/framework/infrastructure/json.md b/docs/en/framework/infrastructure/json.md
index d5bdc8c22e..67126edceb 100644
--- a/docs/en/framework/infrastructure/json.md
+++ b/docs/en/framework/infrastructure/json.md
@@ -63,7 +63,7 @@ Properties:
Add [Volo.Abp.Json.Newtonsoft](https://www.nuget.org/packages/Volo.Abp.Json.Newtonsoft) package and depends on `AbpJsonNewtonsoftModule` to replace the `System Text Json`.
-#### AbpNewtonsoftJsonSerializerOptions
+### AbpNewtonsoftJsonSerializerOptions
- **JsonSerializerSettings(`Newtonsoft.Json.JsonSerializerSettings`)**: Global options for Newtonsoft library operations. See [here](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonSerializerSettings.htm) for reference.
diff --git a/docs/en/framework/ui/angular/account-module.md b/docs/en/framework/ui/angular/account-module.md
index dac9771fb7..eb149af61e 100644
--- a/docs/en/framework/ui/angular/account-module.md
+++ b/docs/en/framework/ui/angular/account-module.md
@@ -7,7 +7,7 @@ If you add the account module to your project;
- "My account" 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.
-### Account Module Implementation
+## Account Module Implementation
Install the `@abp/ng.account` NPM package by running the below command:
@@ -49,7 +49,7 @@ const routes: Routes = [
export class AppRoutingModule {}
```
-### Account Public Module Implementation for Commercial Templates
+## Account Public Module Implementation for Commercial Templates
The pro startup template comes with `@volo/abp.ng.account` package. You should update the package version to v4.3 or higher version. The package can be updated by running the following command:
@@ -97,11 +97,11 @@ const routes: Routes = [
export class AppRoutingModule {}
```
-### My Account Page
+## My Account Page
Before v4.3, the "My account" 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.
-### Personal Info Page Confirm Message
+## Personal Info Page Confirm Message
When the user changes their own data on the personal settings tab in My Account, The data can not update the CurrentUser key of Application-Configuration. The information of the user is stored in claims. The only way to apply this information to the CurrentUser of Application-Configuration is user should log out and log in. When the Refresh-Token feature is implemented, it will be fixed. So We've added a confirmation alert.
@@ -119,11 +119,11 @@ const routes: Routes = [
export class AppRoutingModule {}
```
-### Security Logs Page [COMMERCIAL]
+## Security Logs Page [COMMERCIAL]
Before v4.3, the "Security Logs" link in the current user dropdown on the top bar redirected the user to MVC's 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
+## Resource Owner Password Flow
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:
diff --git a/docs/en/framework/ui/angular/current-user.md b/docs/en/framework/ui/angular/current-user.md
index c4b5e3db14..8d90b0cfda 100644
--- a/docs/en/framework/ui/angular/current-user.md
+++ b/docs/en/framework/ui/angular/current-user.md
@@ -2,7 +2,7 @@
The current user information stored in Config State.
-### How to Get a Current User Information Configuration
+## How to Get a Current User Information Configuration
You can use the `getOne` or `getOne$` method of `ConfigStateService` to get a specific configuration property. For that, the property name should be passed to the method as parameter.
diff --git a/docs/en/framework/ui/angular/datetime-format-pipe.md b/docs/en/framework/ui/angular/datetime-format-pipe.md
index 3a95b25379..88eb9fb604 100644
--- a/docs/en/framework/ui/angular/datetime-format-pipe.md
+++ b/docs/en/framework/ui/angular/datetime-format-pipe.md
@@ -11,21 +11,21 @@ Example
ShortDate, ShortTime and ShortDateTime format data like angular's data pipe but easier. Also the pipes get format from config service by culture.
-# ShortDate Pipe
+## ShortDate Pipe
```html
{{today | shortDate }}
```
-# ShortTime Pipe
+## ShortTime Pipe
```html
{{today | shortTime }}
```
-# ShortDateTime Pipe
+## ShortDateTime Pipe
```html
{{today | shortDateTime }}
diff --git a/docs/en/framework/ui/angular/http-error-handling.md b/docs/en/framework/ui/angular/http-error-handling.md
index 21e13d46e7..e165ac7125 100644
--- a/docs/en/framework/ui/angular/http-error-handling.md
+++ b/docs/en/framework/ui/angular/http-error-handling.md
@@ -1,6 +1,6 @@
# HTTP Error Handling
-### Error Configurations
+## Error Configurations
ABP offers a configurations for errors handling like below
diff --git a/docs/en/framework/ui/angular/localization.md b/docs/en/framework/ui/angular/localization.md
index 9f2b71bc7b..4ff0744212 100644
--- a/docs/en/framework/ui/angular/localization.md
+++ b/docs/en/framework/ui/angular/localization.md
@@ -215,7 +215,7 @@ The localizations above can be used like this:
As of v2.9 ABP has RTL support. If you are generating a new project with v2.9 and above, everything is set, you do not need to do any changes. If you are migrating your project from an earlier version, please follow the 2 steps below:
-#### Step 1. Create Chunks for Bootstrap LTR and RTL
+### Step 1. Create Chunks for Bootstrap LTR and RTL
Find [styles configuration in angular.json](https://angular.io/guide/workspace-config#style-script-config) and make sure the chunks in your project has `bootstrap-rtl.min` and `bootstrap-ltr.min` as shown below.
@@ -257,7 +257,7 @@ Find [styles configuration in angular.json](https://angular.io/guide/workspace-c
}
```
-#### Step 2. Clear Lazy Loaded Fontawesome in AppComponent
+### Step 2. Clear Lazy Loaded Fontawesome in AppComponent
If you have created and injected chunks for Fontawesome as seen above, you no longer need the lazy loading in the `AppComponent` which was implemented before v2.9. Simply remove them. The `AppComponent` in the template of the new version looks like this:
diff --git a/docs/en/framework/ui/angular/sorting-navigation-elements.md b/docs/en/framework/ui/angular/sorting-navigation-elements.md
index 07267957a6..7385a1681c 100644
--- a/docs/en/framework/ui/angular/sorting-navigation-elements.md
+++ b/docs/en/framework/ui/angular/sorting-navigation-elements.md
@@ -5,7 +5,7 @@ This documentation describes how the navigation elements are sorted and how to c
- When you want to add the `Navigation Element` you can use the `RoutesService`. For more details, see the [document](../angular/modifying-the-menu.md).
- However, in this documentation, we will talk more about how to sort the navigation elements.
-### Order Property
+## Order Property
- Normally, you are able to sort your routes with this property. But you can customize our default sorting algorithm.
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png
index 9f9df8991f..af701b00d8 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options-microservice.png differ
diff --git a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png
index 4a2d3c2dd2..cf6700d1b6 100644
Binary files a/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png and b/docs/en/get-started/images/abp-studio-new-solution-dialog-additional-options.png differ
diff --git a/docs/en/get-started/layered-web-application.md b/docs/en/get-started/layered-web-application.md
index 0b051b9681..188e0cfd15 100644
--- a/docs/en/get-started/layered-web-application.md
+++ b/docs/en/get-started/layered-web-application.md
@@ -41,7 +41,7 @@ The following tools should be installed on your development machine:
## Creating a New Solution
-> đ This document uses [ABP Studio](../studio/index.md) to create new ABP solutions. **ABP Studio** is in the beta version now. If you have any issues, you can use the [ABP CLI](../cli/index.md) to create new solutions. You can also use the [getting started page](https://abp.io/get-started) to easily build ABP CLI commands for new project creations.
+> This document uses [ABP Studio](../studio/index.md) to create new ABP solutions. **ABP Studio** is in the beta version now. If you have any issues, you can use the [ABP CLI](../cli/index.md) to create new solutions. You can also use the [getting started page](https://abp.io/get-started) to easily build ABP CLI commands for new project creations.
> ABP startup solution templates have many options for your specific needs. If you don't understand an option that probably means you don't need it. We selected common defaults for you, so you can leave these options as they are.
@@ -119,7 +119,7 @@ Here, you can select the database management systems (DBMS){{ if DB == "EF" }} a

-If you uncheck the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files, such as Helm charts and other Kubernetes-related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login.
+If you uncheck the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files, such as Helm charts and other Kubernetes-related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login. Lastly, you can specify the *Include Tests* option to include or exclude the test projects from the solution.
Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you. After clicking the Create button, the dialog is closed and your solution is loaded into ABP Studio:
diff --git a/docs/en/get-started/microservice.md b/docs/en/get-started/microservice.md
index 47f1091b14..5be705e215 100644
--- a/docs/en/get-started/microservice.md
+++ b/docs/en/get-started/microservice.md
@@ -71,7 +71,7 @@ Click the Next button to see *Additional Options* selection:

-If you unchecked the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files which include the Helm charts and other Kubernetes related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login.
+If you unchecked the *Kubernetes Configuration* option, the solution will not include the Kubernetes configuration files which include the Helm charts and other Kubernetes related files. You can also specify *Social Logins*; if you uncheck this option, the solution will not be configured for social login. Lastly, you can specify the *Include Tests* option to include the test projects in the solution.
Now, we are ready to allow ABP Studio to create our solution. Just click the *Create* button and let the ABP Studio do the rest for you. After clicking the Create button, the dialog is closed and your solution is loaded into ABP Studio:
diff --git a/docs/en/index.md b/docs/en/index.md
index e8bdac3184..187bd6ff83 100644
--- a/docs/en/index.md
+++ b/docs/en/index.md
@@ -2,6 +2,7 @@
ABP offers an **opinionated architecture** to build enterprise software solutions with **best practices** on top of the **.NET** and the **ASP.NET Core** platforms. It provides the fundamental infrastructure, production-ready startup templates, pre-built application modules, UI themes, tooling, guides and documentation to implement that architecture properly and **automate the details** and repetitive works as much as possible.
+## Why ABP Platform?
The following pages outline why you should use the ABP Platform and how it is used:
* [Why choose ABP?](https://abp.io/why-choose-abp)
diff --git a/docs/en/modules/chat.md b/docs/en/modules/chat.md
index 6a7930e3c3..589980ec98 100644
--- a/docs/en/modules/chat.md
+++ b/docs/en/modules/chat.md
@@ -100,19 +100,19 @@ You can visit [Chat module package list page](https://abp.io/packages?moduleName
## User interface
-#### Manage chat feature
+### Manage chat feature
Chat module defines the chat feature, you need to enable the chat feature to use chat.

-#### Chat page
+### Chat page
This is the page that users send messages to each other.

-#### Chat icon on navigation bar
+### Chat icon on navigation bar
An icon that shows unread message count of the user and leads to chat page when clicked is added to navigation menu.
diff --git a/docs/en/modules/gdpr.md b/docs/en/modules/gdpr.md
index 45d380ecd9..76875e0403 100644
--- a/docs/en/modules/gdpr.md
+++ b/docs/en/modules/gdpr.md
@@ -236,9 +236,17 @@ This [Event Transfer Object](../framework/infrastructure/event-bus/distributed#e
Cookie Consent can be used to inform the users of the application, before saving any specific data about the users.
-This feature is enabled by default for the [Application](../solution-templates/layered-web-application) and [Application Single Layer](../solution-templates/single-layer-web-application) Startup Templates.
+This feature is enabled by default for the [Application](../solution-templates/layered-web-application) and [Application Single Layer](../solution-templates/single-layer-web-application) Startup Templates. You can easily enable/disable showing Cookie Consent by configuring the `AbpCookieConsentOptions`
-> You can easily enable/disable to show the Cookie Consent by configuring the `AbpCookieConsentOptions`, which explained above.
+If you want to override the texts in the Cookie Consent component, you just need to define the following localization keys in your localization resource files and change text as you wish:
+
+```json
+ "ThisWebsiteUsesCookie": "This website uses cookies to ensure you get the best experience on the website.",
+ "CookieConsentAgreePolicies": "If you continue to browse, then you agree to our {0} and {1}.",
+ "CookieConsentAgreePolicy": "If you continue to browse, then you agree to our {0}.",
+```
+
+> Refer to the [Localization documentation](../framework/fundamentals/localization.md) for more info about defining localization resources and overriding existing localization entries that comes from pre-built modules.
### Configuring the Cookie Consent
diff --git a/docs/en/modules/openiddict-pro.md b/docs/en/modules/openiddict-pro.md
index b9102cee6d..b70cd83ac2 100644
--- a/docs/en/modules/openiddict-pro.md
+++ b/docs/en/modules/openiddict-pro.md
@@ -333,7 +333,7 @@ LogoutController -> connect/logout
UserInfoController -> connect/userinfo
```
-#### AbpOpenIddictAspNetCoreOptions
+### AbpOpenIddictAspNetCoreOptions
`AbpOpenIddictAspNetCoreOptions` can be configured in the `PreConfigureServices` method of your OpenIddict [module](../framework/architecture/modularity/basics.md).
diff --git a/docs/en/modules/openiddict.md b/docs/en/modules/openiddict.md
index f3e8f88975..5f421d9001 100644
--- a/docs/en/modules/openiddict.md
+++ b/docs/en/modules/openiddict.md
@@ -516,7 +516,7 @@ In the module's `app` directory there are six projects(including `angular`)
* `OpenIddict.Demo.Client.BlazorWASM:` ASP NET Core Blazor application using `OidcAuthentication` for authentication.
* `angular`: An angular application that integrates the abp ng modules and uses oauth for authentication.
-#### How to run?
+### How to run?
Confirm the connection string of `appsettings.json` in the `OpenIddict.Demo.Server` project. Running the project will automatically create the database and initialize the data.
After running the `OpenIddict.Demo.API` project, then you can run the rest of the projects to test.
diff --git a/docs/en/modules/tenant-management.md b/docs/en/modules/tenant-management.md
index b5e7f6156d..4116bccb33 100644
--- a/docs/en/modules/tenant-management.md
+++ b/docs/en/modules/tenant-management.md
@@ -6,7 +6,7 @@
> Please **refer to the [Multi-Tenancy](../framework/architecture/multi-tenancy) documentation** to understand the multi-tenancy system of the ABP. This document focuses on the Tenant Management module.
-### About the ABP SaaS Module
+## About the ABP SaaS Module
The [SaaS Module](https://abp.io/modules/Volo.Saas) is an alternative implementation of this module with more features and possibilities. It is distributed as a part of the [ABP](https://abp.io/) subscription.
diff --git a/docs/en/solution-templates/microservice/how-to-use-with-abp-suite.md b/docs/en/solution-templates/microservice/how-to-use-with-abp-suite.md
index d5ffbf1b2c..8549032089 100644
--- a/docs/en/solution-templates/microservice/how-to-use-with-abp-suite.md
+++ b/docs/en/solution-templates/microservice/how-to-use-with-abp-suite.md
@@ -6,14 +6,54 @@ You can open ABP Suite from ABP Studio by using the **ABP Suite** -> **Open** to

-It opens the ABP Suite in a built-in browser window. You can also access the suite by visiting `http://localhost:3000` through your browser. From there, you can visually design your solution and generate code. In this example, we create a **Product** entity.
+It opens the ABP Suite in a built-in browser window. You can also access the suite by visiting `http://localhost:3000` through your browser. From there, you can visually design your solution and generate code.
+
+In the following example, we've defined the entity name as **Product** and provide other metadata for the related entity:

After clicking **Save and generate** for the entity in ABP Suite, use **Run** -> **Build & Restart** in the [Solution Runner](../../studio/running-applications.md#start) to apply the changes.
-To confirm, visit the Swagger UI to verify that the necessary API endpoints and services have been created.
+> ABP Suite requires you to stop all running instances in the related solution/project to be able to generate codes properly. Otherwise, it might not work effectively.
+
+Then, to confirm, you can visit the Swagger UI to verify that the necessary API endpoints and services have been created.

-> Currently, you can't generate UI code with ABP Suite for microservice solutions. This feature will be added in future releases.
\ No newline at end of file
+If you selected the *Create user interface* option for the entity, the related UI components (pages, styles, scripts etc.) will also be created. To be able to see the related pages in your host application/UI you should apply the following steps:
+
+1. Generate [*client-proxies*](../../framework/api-development/static-csharp-clients.md) with the following command:
+
+```bash
+abp generate-proxy -t csharp -url http://localhost:{your-service-port}/ -m {remote-service-name} --without-contracts
+```
+
+* You should run this command in the directory of your host application, and your microservices should be up and running.
+* The command will generate proxy classes for your microservice in the host application, which you can see under the **ClientProxies** folder.
+
+> **Note:** After each entity generation/modification in your services, then you should run this command to update client-proxies.
+
+2. Configure the application for the static client proxy:
+
+```csharp
+public class MyClientAppModule : AbpModule
+{
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ // Prepare for static client proxy generation
+ context.Services.AddStaticHttpClientProxies(
+ typeof(MyServiceApplicationContractsModule).Assembly
+ );
+
+ // Include the generated app-generate-proxy.json in the virtual file system
+ Configure(options =>
+ {
+ options.FileSets.AddEmbedded();
+ });
+ }
+}
+```
+
+After you apply these steps, you're ready to go to run your microservices and see the generated CRUD pages:
+
+
diff --git a/docs/en/solution-templates/microservice/images/abp-suite-products-pages.png b/docs/en/solution-templates/microservice/images/abp-suite-products-pages.png
new file mode 100644
index 0000000000..01bee7ed5e
Binary files /dev/null and b/docs/en/solution-templates/microservice/images/abp-suite-products-pages.png differ
diff --git a/docs/en/studio/images/solution-explorer/abp-solution.png b/docs/en/studio/images/solution-explorer/abp-solution.png
index b15e7f46f0..347ecdfbb4 100644
Binary files a/docs/en/studio/images/solution-explorer/abp-solution.png and b/docs/en/studio/images/solution-explorer/abp-solution.png differ
diff --git a/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-additional-options.png b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-additional-options.png
new file mode 100644
index 0000000000..3d99055917
Binary files /dev/null and b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-additional-options.png differ
diff --git a/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png
index a1aa31887f..86896e8ac4 100644
Binary files a/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png and b/docs/en/studio/images/solution-explorer/create-new-microservice-nolayers-enable-integration.png differ
diff --git a/docs/en/studio/images/solution-explorer/create-new-module.png b/docs/en/studio/images/solution-explorer/create-new-module.png
index 320b9d9bb5..a489679877 100644
Binary files a/docs/en/studio/images/solution-explorer/create-new-module.png and b/docs/en/studio/images/solution-explorer/create-new-module.png differ
diff --git a/docs/en/studio/images/solution-explorer/folder-context-menu.png b/docs/en/studio/images/solution-explorer/folder-context-menu.png
index 3d98774bdc..8e53fd32ef 100644
Binary files a/docs/en/studio/images/solution-explorer/folder-context-menu.png and b/docs/en/studio/images/solution-explorer/folder-context-menu.png differ
diff --git a/docs/en/studio/images/solution-explorer/imported-module.png b/docs/en/studio/images/solution-explorer/imported-module.png
index a8f3054fe7..94c703b6ab 100644
Binary files a/docs/en/studio/images/solution-explorer/imported-module.png and b/docs/en/studio/images/solution-explorer/imported-module.png differ
diff --git a/docs/en/studio/images/solution-explorer/imports-context-menu.png b/docs/en/studio/images/solution-explorer/imports-context-menu.png
index 24ec244c4c..23a189d920 100644
Binary files a/docs/en/studio/images/solution-explorer/imports-context-menu.png and b/docs/en/studio/images/solution-explorer/imports-context-menu.png differ
diff --git a/docs/en/studio/images/solution-explorer/module-context-menu.png b/docs/en/studio/images/solution-explorer/module-context-menu.png
index 5f05f8026c..e58dc89b36 100644
Binary files a/docs/en/studio/images/solution-explorer/module-context-menu.png and b/docs/en/studio/images/solution-explorer/module-context-menu.png differ
diff --git a/docs/en/studio/images/solution-explorer/package-context-menu.png b/docs/en/studio/images/solution-explorer/package-context-menu.png
index 93279e37ef..0272b8e477 100644
Binary files a/docs/en/studio/images/solution-explorer/package-context-menu.png and b/docs/en/studio/images/solution-explorer/package-context-menu.png differ
diff --git a/docs/en/studio/release-notes.md b/docs/en/studio/release-notes.md
index 5140de9647..7d5575786b 100644
--- a/docs/en/studio/release-notes.md
+++ b/docs/en/studio/release-notes.md
@@ -2,6 +2,14 @@
This document contains **brief release notes** for each ABP Studio release. Release notes only include **major features** and **visible enhancements**. Therefore, they don't include all the development done in the related version.
+## 0.9.2 (2024-10-22)
+
+* Added "Sample CRUD Page" option for pro templates
+* Generated *Signing-Certificate* for appnolayers template
+* Added test projects optionally for all templates
+* Added automapper configuration to apps/web project for ms template
+* Disabled *transaction* for `MongoDB` and `SQLite` by default
+
## 0.9.1 (2024-10-10)
* Fixed the ABP Studio CLI's Bundle Command
diff --git a/docs/en/studio/solution-explorer.md b/docs/en/studio/solution-explorer.md
index 8aa0ea4404..df0ca04a4f 100644
--- a/docs/en/studio/solution-explorer.md
+++ b/docs/en/studio/solution-explorer.md
@@ -123,7 +123,7 @@ A [module](./concepts.md#module) is a sub-solution that can contains zero, one o
### Adding a New Empty Module
-Create a new module by clicking the *Add* -> *New Module* -> *Empty Module* button at the root of the solution or in the solution folder context menu. The *Microservice* solution template also includes *Microservice*, *Gateway*, and *Web* modules. Other solution templates, such as *Application (Layered)*, can only create *Empty*, and *DDD* modules.
+Create a new module by clicking the *Add* -> *New Module* -> *Empty Module* button at the root of the solution or in the solution folder context menu. The *Microservice* solution template also includes *Microservice*, *Gateway*, and *Web* modules. Other solution templates, such as *Application (Layered)*, can only create *Empty*, *DDD* and *Standard* modules.

@@ -149,6 +149,10 @@ When you create a microservice, you must edit some [configurations](../solution-

+You can uncheck the *Include Tests* option if you don't want to include test projects in your microservice module. Click the *Create* button to add the microservice module to the solution.
+
+
+
After creating the *Microservice (service-nolayers)* module, it will be added to the solution, and you should see the following structure in the solution explorer.

diff --git a/docs/en/studio/version-compatibility.md b/docs/en/studio/version-compatibility.md
index cd6850fcab..8cfc373bcb 100644
--- a/docs/en/studio/version-compatibility.md
+++ b/docs/en/studio/version-compatibility.md
@@ -4,6 +4,7 @@ This document provides an overview of the compatibility between various versions
| **ABP Studio Version** | **ABP Version** |
|------------------------|---------------------------|
+| 0.9.2 | 8.3.2 |
| 0.8.4 - 0.9.1 | 8.3.1 |
| 0.8.1 to 0.8.3 | 8.3.0 |
| 0.8.0 | 8.2.3 |
diff --git a/docs/en/suite/generating-crud-page.md b/docs/en/suite/generating-crud-page.md
index 8d98bb7df9..e1461e3d0a 100644
--- a/docs/en/suite/generating-crud-page.md
+++ b/docs/en/suite/generating-crud-page.md
@@ -115,7 +115,7 @@ To create a new entity, make sure the *-New entity-* is selected in the **Entity
## Properties
-##### Define a property
+### Define a property
A property is a field in the entity which refers a column in the relational database table or a `JSON` field in `NoSQL` database collection. In the properties section, you can manage the properties your entity. To add a new property, click the "Add Property" button on the top-right of the page.
@@ -306,7 +306,7 @@ abp suite generate --entity D:\Projects\BookStore\.suite\entities\Book.json --so
In this example, `Book.json` was previously created via ABP Suite.
-##### Parameters
+### Parameters
* `--entity` or `-e`: Path of the entity's JSON file.
* `--solution` or `-s`: Path of the target solution file (***.sln**).
diff --git a/docs/en/suite/generating-entities-from-an-existing-database-table.md b/docs/en/suite/generating-entities-from-an-existing-database-table.md
index e877adf425..481bd32ff5 100644
--- a/docs/en/suite/generating-entities-from-an-existing-database-table.md
+++ b/docs/en/suite/generating-entities-from-an-existing-database-table.md
@@ -16,13 +16,13 @@
If you have an existing database table, you can generate the entities using ABP Suite and create a CRUD page based on those entities, let's get started.
-# Create/open your project
+## Create/open your project

Either create a new project or open an existing project that's based on an app or module template.
-# Generate the Entities
+## Generate the Entities
After opening the project in ABP Suite, scroll down to the bottom and click the **Load Entity From Database** button:
@@ -41,6 +41,6 @@ After that, make sure the primary key type is selected, then click **Save and ge
The following GIF is a summary of the previous steps: 
-# Run the Project!
+## Run the Project!
After that, run the project and watch the magic! An easy CRUD app using the entities from an existing database table!
diff --git a/docs/en/tutorials/book-store/part-09.md b/docs/en/tutorials/book-store/part-09.md
index c42dd22d8a..d1c446bc3f 100644
--- a/docs/en/tutorials/book-store/part-09.md
+++ b/docs/en/tutorials/book-store/part-09.md
@@ -677,6 +677,10 @@ export class AuthorComponent implements OnInit {
this.selectedAuthor.birthDate ? new Date(this.selectedAuthor.birthDate) : null,
Validators.required,
],
+ shortBio: [
+ this.selectedAuthor.shortBio ? this.selectedAuthor.shortBio : null,
+ Validators.required,
+ ],
});
}
@@ -768,6 +772,7 @@ Open the `/src/app/author/author.component.html` and replace the content as belo
{%{{{ row.birthDate | date }}}%}
+
@@ -795,6 +800,10 @@ Open the `/src/app/author/author.component.html` and replace the content as belo
(click)="datepicker.toggle()"
/>
+
+ *
+
+
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-ddd-module.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-ddd-module.png
index ed11a95f57..e4ef112a1c 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-ddd-module.png and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-ddd-module.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module-dialog.png
deleted file mode 100644
index 882323b4b6..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module-dialog.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module.png
deleted file mode 100644
index 53d453cd37..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-empty-module.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-class-library.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-class-library.png
deleted file mode 100644
index 247ee96ca0..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-class-library.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-mvc-ui.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-mvc-ui.png
deleted file mode 100644
index 41214c0ddc..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package-mvc-ui.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package.png
deleted file mode 100644
index 7e28d708bf..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-package.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-additional-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-additional-dialog.png
new file mode 100644
index 0000000000..435e608626
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-additional-dialog.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-db-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-db-dialog.png
new file mode 100644
index 0000000000..19eae2a53c
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-db-dialog.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-dialog.png
new file mode 100644
index 0000000000..112491fc8a
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-dialog.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog.png
new file mode 100644
index 0000000000..6e0152dfd7
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module-ui-dialog.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module.png
new file mode 100644
index 0000000000..0a2459296e
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-add-new-standard-module.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-nuget-package-reference.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-nuget-package-reference.png
deleted file mode 100644
index c52df6d559..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-nuget-package-reference.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-2.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-2.png
deleted file mode 100644
index 308d32c6ad..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-2.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-3.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-3.png
deleted file mode 100644
index dc51826734..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-3.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-4.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-4.png
index b29850cce6..c9c3a36596 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-4.png and b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-4.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-6.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-6.png
deleted file mode 100644
index 954ea41060..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-6.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-7.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-7.png
deleted file mode 100644
index 3dea701062..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-7.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-2.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-2.png
deleted file mode 100644
index 09682f0b6f..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-2.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3.png
index 2d9d1e504b..91f0e9f948 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3.png and b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-3.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-5.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-5.png
deleted file mode 100644
index ad78c4eee7..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-5.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-6.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-6.png
deleted file mode 100644
index bd1c968b03..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog-6.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog.png
deleted file mode 100644
index 34342dad2e..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference-dialog.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference.png b/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference.png
deleted file mode 100644
index a6870e4c0e..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-add-package-reference.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-contracts-package.png b/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-contracts-package.png
deleted file mode 100644
index f451a550d8..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-contracts-package.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-domain-package.png b/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-domain-package.png
deleted file mode 100644
index ed03c6b3bb..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-added-ddd-domain-package.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-browser-list-of-orders-with-product-name.png b/docs/en/tutorials/modular-crm/images/abp-studio-browser-list-of-orders-with-product-name.png
index ecbd5a7fbc..50cfc86eb4 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-browser-list-of-orders-with-product-name.png and b/docs/en/tutorials/modular-crm/images/abp-studio-browser-list-of-orders-with-product-name.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png b/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png
index cb3af02592..3e4d83fee1 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png and b/docs/en/tutorials/modular-crm/images/abp-studio-browser-orders-menu-item.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-additional-options.png b/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-additional-options.png
new file mode 100644
index 0000000000..60031dd61b
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-additional-options.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-db.png b/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-db.png
index 714eeac483..f173c08cff 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-db.png and b/docs/en/tutorials/modular-crm/images/abp-studio-create-new-module-dialog-step-db.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png
index 21af63a949..7ecb6b6262 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog-for-ordering.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png
index 17eb6d0ecc..5ea22e8e3e 100644
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png and b/docs/en/tutorials/modular-crm/images/abp-studio-install-module-dialog.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module.png b/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module.png
new file mode 100644
index 0000000000..02cec6ad68
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-standard-module.png differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-two-modules.png b/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-two-modules.png
deleted file mode 100644
index 3e04717081..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-modular-crm-with-two-modules.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-new-package-under-the-module.png b/docs/en/tutorials/modular-crm/images/abp-studio-new-package-under-the-module.png
deleted file mode 100644
index 8ac9bb987e..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-new-package-under-the-module.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-project-reference-example.png b/docs/en/tutorials/modular-crm/images/abp-studio-project-reference-example.png
deleted file mode 100644
index 7694d8013b..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-project-reference-example.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-orders-page.png b/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-orders-page.png
deleted file mode 100644
index fbd419d145..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/abp-studio-solution-runner-orders-page.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/file-system-odering-module-initial-folder.png b/docs/en/tutorials/modular-crm/images/file-system-odering-module-initial-folder.png
deleted file mode 100644
index eb10f3e26e..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/file-system-odering-module-initial-folder.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/file-system-ordering-module-initial-folder.png b/docs/en/tutorials/modular-crm/images/file-system-ordering-module-initial-folder.png
new file mode 100644
index 0000000000..467236d60a
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/file-system-ordering-module-initial-folder.png differ
diff --git a/docs/en/tutorials/modular-crm/images/ordering-module-visual-studio.png b/docs/en/tutorials/modular-crm/images/ordering-module-visual-studio.png
new file mode 100644
index 0000000000..3a39951a6b
Binary files /dev/null and b/docs/en/tutorials/modular-crm/images/ordering-module-visual-studio.png differ
diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-order-entity.png b/docs/en/tutorials/modular-crm/images/visual-studio-order-entity.png
index 33ea2b9d24..112ee3d7d3 100644
Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-order-entity.png and b/docs/en/tutorials/modular-crm/images/visual-studio-order-entity.png differ
diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-order-event.png b/docs/en/tutorials/modular-crm/images/visual-studio-order-event.png
index 21377ac3ee..5008c9b45c 100644
Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-order-event.png and b/docs/en/tutorials/modular-crm/images/visual-studio-order-event.png differ
diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-module-initial.png b/docs/en/tutorials/modular-crm/images/visual-studio-ordering-module-initial.png
deleted file mode 100644
index 0b238370b1..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-module-initial.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-ui-package-dependency.png b/docs/en/tutorials/modular-crm/images/visual-studio-ordering-ui-package-dependency.png
deleted file mode 100644
index 4fe2d6f935..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-ordering-ui-package-dependency.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-pages-folder.png b/docs/en/tutorials/modular-crm/images/visual-studio-pages-folder.png
deleted file mode 100644
index f1b5742ce9..0000000000
Binary files a/docs/en/tutorials/modular-crm/images/visual-studio-pages-folder.png and /dev/null differ
diff --git a/docs/en/tutorials/modular-crm/part-02.md b/docs/en/tutorials/modular-crm/part-02.md
index de8fd69f92..6ebc22f20c 100644
--- a/docs/en/tutorials/modular-crm/part-02.md
+++ b/docs/en/tutorials/modular-crm/part-02.md
@@ -69,7 +69,11 @@ The next step is to select the database provider (or providers) you want to supp

-Since our main application is using Entity Framework Core and we will use the `ModularCrm.Products` module only for that main application, we can select the *Entity Framework Core* option and click the *Create* button.
+Since our main application is using Entity Framework Core and we will use the `ModularCrm.Products` module only for that main application, we can select the *Entity Framework Core* option and click the *Next* button.
+
+
+
+Lastly, you can uncheck the *Include Tests* option if you don't want to include test projects in your module. Click the *Create* button to create the new module.
### Exploring the New Module
diff --git a/docs/en/tutorials/modular-crm/part-04.md b/docs/en/tutorials/modular-crm/part-04.md
index ea7e66cc8b..1674ced6c6 100644
--- a/docs/en/tutorials/modular-crm/part-04.md
+++ b/docs/en/tutorials/modular-crm/part-04.md
@@ -16,76 +16,41 @@
In this part, you will build a new module for placing orders and install it in the main CRM application.
-## Creating an Empty Module
+## Creating a Standard Module
-In this part, we have used the *DDD Module* template for the Product module and will use the *Empty Module* template for the Ordering module.
+In this part, we have used the *DDD Module* template for the Product module and will use the *Standard Module* template for the Ordering module.
-Right-click the `modules` folder on the *Solution Explorer* panel, and select the *Add* -> *New Module* -> *Empty Module* command:
+Right-click the `modules` folder on the *Solution Explorer* panel, and select the *Add* -> *New Module* -> *Standard Module* command:
-
+
That command opens a dialog to define the properties of the new module:
-
+
-Set `ModularCrm.Ordering` as the *Module name*, leave the *Output folder* as is and click the *Create* button. It will create the new `ModularCrm.Ordering` module under the `modules` folder in the *Solution Explorer*:
+Set `ModularCrm.Ordering` as the *Module name*, leave the *Output folder* as is and click the *Next* button.
-
+
-Since we've created an empty module, it is really empty. If you open the `modules/modularcrm.ordering` in your file system, you can see the initial files:
+Similar to DDD module creation, you can choose the type of UI you want to support in your module or select *No UI* if you don't need a user interface. In this example, we'll select the *MVC* option and click *Next*. One difference is that, for a standard module, you can only choose one UI type.
-
+
-## Creating the Module Packages
+The same limitation applies to the database selection. You can only choose one database provider for a standard module. Select the *Entity Framework Core* option and click *Next*.
-In this section, we will create packages under the Ordering module. The Products module was well layered based on Domain Driven Design principles. This time, we will keep things very simple and will only create two packages for the Ordering module:
+
-* `ModularCrm.Ordering`: Contains all the module code without any layering. It will contain entities, database access code, services, controllers, UI pages and whatever we need to implement the *Ordering* module.
-* `ModularCrm.Ordering.Contracts`: Contains the services and objects we want to share with other modules. `ModularCrm.Ordering` uses (and implements) this package.
+You can uncheck the *Include Tests* option to keep the module simple. Click the *Create* button to create the module.
-> If your modules are relatively small and easy to maintain, they will only be used by your main application, and you don't care about layering, then you can create such simple module structures.
+
-We will create and configure everything from scratch. You have already learned the easy way in the previous parts, where we created the Products module. It is time to deepen your understanding of the details and learn how ABP Studio allows you to set up custom structures. Let's begin.
+Since we've created a standard module, it doesn't have multiple layers like the DDD module. If you open the `modules/modularcrm.ordering` in your file system, you can see the initial files:
-### Creating the `ModularCrm.Ordering.Contracts` Package
+
-Right-click the `ModularCrm.Ordering` module on the *Solution Explorer* and select the *Add* -> *Package* -> *New Package* command as shown in the following figure:
+Because only a single UI package can be chosen, the UI type doesnât matter. This is why the package name is changed to *ModularCrm.Ordering.UI*. Additionally, there are no *Domain*, *EntityFrameworkCore*, or *Http* layers like in the DDD module. We're going to use the `ModularCrm.Ordering` package for the domain business logic. You can open `ModularCrm.Ordering.sln` in your favorite IDE (e.g. Visual Studio):
-
-
-That command opens a new dialog to create a new package:
-
-
-
-With that dialog, you can build your module or application layer by layer. There are templates for any package. However, here we will go with the simplest one: *ABP Class Library*. ABP Class Library is an empty C# class library with the [core ABP package](https://www.nuget.org/packages/Volo.Abp.Core) dependency and a [module class](../../framework/architecture/modularity/basics.md).
-
-Type `ModularCrm.Ordering.Contracts` as the *Package name* and click the *Create* button. It will add the package under the `ModularCrm.Ordering` module:
-
-
-
-### Creating the `ModularCrm.Ordering` Package
-
-Right-click the `ModularCrm.Ordering` module on the *Solution Explorer* again and select the *Add* -> *Package* -> *New Package* command to create a second package:
-
-
-
-This time, we select the MVC UI template and set the Package name to `ModularCrm.Ordering`. Then, click the Create button to add the new package.
-
-### Add Package Reference
-
-After the package has been added, right-click the `ModularCrm.Ordering` package and select the *Add Package Reference* command:
-
-
-
-That command opens a dialog to select the package:
-
-
-
-In that dialog, you can add package references from various sources. Here, we will add a reference for the package in the current module. So, select the `ModularCrm.Ordering.Contracts` package in the *This module* tab and click the *OK* button. You can see the package reference under the *Projects* dependencies on the *Solution Explorer* panel:
-
-
-
-The initial module creation has been completed. Now, we have a new module with two packages. However, it is not related to other modules and applications in the solution yet.
+
## Installing into the Main Application
@@ -105,8 +70,8 @@ Select the `ModularCrm.Ordering` module and check the *Install this module* opti

-Select the `ModuleCrm.Ordering` package in the left area and the `ModularCrm.Domain` package in the middle area, as shown in the preceding figure, and click the *OK* button.
+Select the `ModuleCrm.Ordering` package from the left area and the `ModularCrm.Domain` package from the middle area. Then, select the `ModularCrm.Ordering.UI` package from the left area and the `ModularCrm.Web` package from the middle area, as shown in the preceding figure. Finally, click *OK*.
> Since the Ordering module is not layered, we didn't install its packages to the layers of our main application. We are installing it only to `ModularCrm.Domain`. In this way, we can use the Ordering module from any layer of our application since `ModularCrm.Domain` is one of the core packages of our application. If you build your modules as non-layered and you don't have much code in the main application's .NET solution, you can also consider creating a non-layered main application that composes these modules.
-In this part of the tutorial, we've created an empty module and added packages. This allows you to create modules or applications with a custom structure. In the next part, we will add functionality to the Ordering module.
+In this part of the tutorial, we've created a standard module. This allows you to create modules or applications with a different structure. In the next part, we will add functionality to the Ordering module.
diff --git a/docs/en/tutorials/modular-crm/part-05.md b/docs/en/tutorials/modular-crm/part-05.md
index 69a9223882..91e8b2cb37 100644
--- a/docs/en/tutorials/modular-crm/part-05.md
+++ b/docs/en/tutorials/modular-crm/part-05.md
@@ -14,7 +14,7 @@
}
````
-In the previous part, we created a custom Ordering module and installed it into the main application. However, the Ordering module has no functionality now. In this part, we will create an `Order` entity and add functionality to create and list the orders.
+In the previous part, we created Ordering module and installed it into the main application. However, the Ordering module has no functionality now. In this part, we will create an `Order` entity and add functionality to create and list the orders.
## Creating an `Order` Entity
@@ -22,37 +22,9 @@ Open the `ModularCrm.Ordering` .NET solution in your IDE.
> Tip: You can open the folder of a module's .NET solution by right-clicking the related module in ABP Studio and selecting the *Open with* -> *Explorer* command.
-The following figure shows the `ModularCrm.Ordering` module in the *Solution Explorer* panel of Visual Studio:
-
-
-
-### Adding `Volo.Abp.Ddd.Domain` Package Reference
-
-As you see in the preceding figure, the solution structure is very minimal. It also has a minimal ABP dependency. ABP Framework has [hundreds of NuGet packages](https://abp.io/packages), but the `ModularCrm.Ordering` project only has the [`Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared`](https://abp.io/package-detail/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared) package reference:
-
-
-
-We will create an [entity class](../../framework/architecture/domain-driven-design/entities.md). ABP defines base entity classes and other related infrastructure in the [`Volo.Abp.Ddd.Domain`](https://abp.io/package-detail/Volo.Abp.Ddd.Domain) package. So, we need to add a reference to that NuGet package.
-
-You can add that package and manually arrange the [module](../../framework/architecture/modularity/basics.md) class dependency. However, we will use ABP Studio as a more practical option.
-
-Return to ABP Studio, right-click the `ModularCrm.Ordering` package in the *Solution Explorer* and select the *Add Package Reference* command:
-
-
-
-That command opens a dialog to add a new package reference:
-
-
-
-Select the *NuGet* tab, type `Volo.Abp.Ddd.Domain` as the *Package name* and write the version of the package you want to install. Please be sure that you are installing the same version as the other ABP packages you are already using. ABP Studio will provide an easier way to select the package and its version in future ABP versions.
-
-Click the *OK* button. Now you can check the *Packages* under the `ModularCrm.Ordering` module *Dependencies* to see the `Volo.Abp.Ddd.Domain` package is installed:
-
-
-
### Adding an `Order` Class
-Now, you can return your IDE and add an `Order` class to the `ModularCrm.Ordering` project (open an `Entities` folder and place the `Order.cs` into that folder):
+Create an `Order` class to the `ModularCrm.Ordering` project (open an `Entities` folder and place the `Order.cs` into that folder):
````csharp
using System;
@@ -77,7 +49,7 @@ We allow users to place only a single product within an order. The `Order` entit
We used an `OrderState` enumeration that has not yet been defined. Open an `Enums` folder in the `ModularCrm.Ordering.Contracts` project and create an `OrderState.cs` file inside it:
````csharp
-namespace ModularCrm.Ordering.Contracts.Enums;
+namespace ModularCrm.Ordering.Enums;
public enum OrderState : byte
{
@@ -93,48 +65,64 @@ The final structure of the Ordering module should be similar to the following fi
## Configuring the Database Mapping
-The `Order` entity has been created. Now, we need to configure the database mapping for that entity. We will first install the Entity Framework Core package, define the database table mapping, create a database migration and update the database.
-
-### Installing the Entity Framework Core Package
+The `Order` entity has been created. Now, we need to configure the database mapping for that entity. We will first define the database table mapping, create a database migration and update the database.
-> In this section, we will install the [`Volo.Abp.EntityFrameworkCore`](https://abp.io/package-detail/Volo.Abp.EntityFrameworkCore) package to the Ordering module. That package is DBMS-independent and leaves the DBMS selection to the final application. If you want, you can install a DBMS-specific package instead. For example, you can install the [`Volo.Abp.EntityFrameworkCore.SqlServer`](https://abp.io/package-detail/Volo.Abp.EntityFrameworkCore.SqlServer) package if you are using SQL Server and want to make SQL Server specific configuration for your module's database.
-> You can search for other packages on the [abp.io/packages](https://abp.io/packages) page.
-
-Stop the web application if it is still running. Return to ABP Studio, right-click the `ModularCrm.Ordering` package on the *Solution Explorer* panel and select the *Add Package Reference* command:
-
-
+### Defining the Database Mappings
-Select the *NuGet* tab, type `Volo.Abp.EntityFrameworkCore` as the *Package name* and specify a *Version* that is compatible with the ABP version used by your solution:
+Entity Framework Core requires defining a `DbContext` class as the main object for the database mapping. We want to use the main application's `DbContext` object. That way, we can control the database migrations at a single point, ensure database transactions on multi-module operations, and establish relations between database tables of different modules. However, the Ordering module can not use the main application's `DbContext` object because it doesn't depend on the main application, and we don't want to establish such a dependency.
-
+As a solution, we will use `DbContext` interface in the Ordering module which is then implemented by the main module's `DbContext`.
-Once you click the *OK* button, the NuGet package reference is added.
+Open your IDE, in `Data` folder under the `ModularCrm.Ordering` project, and edit `IOrderingDbContext` interface as shown:
-### Defining the Database Mappings
+````csharp
+using Microsoft.EntityFrameworkCore;
+using ModularCrm.Ordering.Entities;
+using Volo.Abp.Data;
+using Volo.Abp.EntityFrameworkCore;
-Entity Framework Core requires defining a `DbContext` class as the main object for the database mapping. We want to use the main application's `DbContext` object. That way, we can control the database migrations at a single point, ensure database transactions on multi-module operations, and establish relations between database tables of different modules. However, the Ordering module can not use the main application's `DbContext` object because it doesn't depend on the main application, and we don't want to establish such a dependency.
+namespace ModularCrm.Ordering.Data;
-As a solution, we will define a `DbContext` interface in the Ordering module which is then implemented by the main module's `DbContext`.
+[ConnectionStringName(OrderingDbProperties.ConnectionStringName)]
+public interface IOrderingDbContext : IEfCoreDbContext
+{
+ DbSet Orders { get; set; }
+}
+````
-Open your IDE, create a `Data` folder under the `ModularCrm.Ordering` project, and create an `IOrderingDbContext` interface under that folder:
+Afterwards, create *Orders* `DbSet` for the `OrderingDbContext` class in the `Data` folder under the `ModularCrm.Ordering` project.
````csharp
using Microsoft.EntityFrameworkCore;
using ModularCrm.Ordering.Entities;
+using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
-namespace ModularCrm.Ordering.Data
+namespace ModularCrm.Ordering.Data;
+
+[ConnectionStringName(OrderingDbProperties.ConnectionStringName)]
+public class OrderingDbContext : AbpDbContext, IOrderingDbContext
{
- public interface IOrderingDbContext : IEfCoreDbContext
+ public DbSet Orders { get; set; }
+
+ public OrderingDbContext(DbContextOptions options) : base(options)
{
- DbSet Orders { get; set; }
+
+ }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ builder.ConfigureOrdering();
}
}
````
+
We can inject and use the `IOrderingDbContext` in the Ordering module. However, we will not usually directly use that interface. Instead, we will use ABP's [repositories](../../framework/architecture/domain-driven-design/repositories.md), which internally uses that interface.
-It is best to configure the database table mapping for the `Order` entity in the Ordering module. We will create an extension method that will be called by the main application later. Create a class named `OrderingDbContextModelCreatingExtensions` in the same `Data` folder:
+It is best to configure the database table mapping for the `Order` entity in the Ordering module. We will use the `OrderingDbContextModelCreatingExtensions` in the same `Data` folder:
````csharp
using Microsoft.EntityFrameworkCore;
@@ -142,26 +130,26 @@ using ModularCrm.Ordering.Entities;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
-namespace ModularCrm.Ordering.Data
+namespace ModularCrm.Ordering.Data;
+
+public static class OrderingDbContextModelCreatingExtensions
{
- public static class OrderingDbContextModelCreatingExtensions
+ public static void ConfigureOrdering(
+ this ModelBuilder builder)
{
- public static void ConfigureOrdering(this ModelBuilder builder)
- {
- Check.NotNull(builder, nameof(builder));
+ Check.NotNull(builder, nameof(builder));
- builder.Entity(b =>
- {
- //Configure table name
- b.ToTable("Orders");
+ builder.Entity(b =>
+ {
+ //Configure table name
+ b.ToTable("Orders");
- //Always call this method to set base entity properties
- b.ConfigureByConvention();
+ //Always call this method to set base entity properties
+ b.ConfigureByConvention();
- //Properties of the entity
- b.Property(q => q.CustomerName).IsRequired().HasMaxLength(120);
- });
- }
+ //Properties of the entity
+ b.Property(q => q.CustomerName).IsRequired().HasMaxLength(120);
+ });
}
}
````
@@ -204,7 +192,7 @@ protected override void OnModelCreating(ModelBuilder builder)
}
````
-In this way, the Ordering module can use' ModularCrmDbContext' over the `IProductsDbContext` interface. This part is only needed once for a module. Next time, you can add a new database migration, as explained in the next section.
+In this way, the Ordering module can use 'ModularCrmDbContext' over the `IProductsDbContext` interface. This part is only needed once for a module. Next time, you can add a new database migration, as explained in the next section.
#### Add a Database Migration
@@ -238,30 +226,14 @@ We will create an application service to manage the `Order` entities.
### Defining the Application Service Contract
-We're gonna create the `IOrderAppService` interface under the `ModularCrm.Ordering.Contracts` project but first, we need to add `Volo.Abp.Ddd.Application.Contracts` package reference.
-
-Right-click the `ModularCrm.Ordering.Contracts` project in the *Solution Explorer* panel and select the *Add Package Reference* command:
-
-
-
-This command opens a dialog to add a new package reference:
-
-
-
-Select the *NuGet* tab, type `Volo.Abp.Ddd.Application.Contracts` as the *Package name* and write the version of the package you want to install. Please be sure that you are installing the same version as the other ABP packages you are already using.
-
-Click the *Ok* button. Now you can check the *Packages* under the `ModularCrm.Ordering.Contracts` project *Dependencies* to see the `Volo.Abp.Ddd.Application.Contracts` package is installed:
-
-
-
-Return to your IDE, open the `ModularCrm.Ordering` module's .NET solution and create an `IOrderAppService` interface under the `Services` folder for `ModularCrm.Ordering.Contracts` project:
+We're gonna create the `IOrderAppService` interface under the `ModularCrm.Ordering.Contracts` project. Return to your IDE, open the `ModularCrm.Ordering` module's .NET solution and create an `IOrderAppService` interface under the `Services` folder for `ModularCrm.Ordering.Contracts` project:
````csharp
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
-namespace ModularCrm.Ordering.Contracts.Services;
+namespace ModularCrm.Ordering.Services;
public interface IOrderAppService : IApplicationService
{
@@ -297,9 +269,9 @@ Create a `OrderDto` class under the `ModularCrm.Ordering.Contracts` project:
````csharp
using System;
-using ModularCrm.Ordering.Contracts.Enums;
+using ModularCrm.Ordering.Enums;
-namespace ModularCrm.Ordering.Contracts.Services;
+namespace ModularCrm.Ordering.Services;
public class OrderDto
{
@@ -316,72 +288,43 @@ The new files under the `ModularCrm.Ordering.Contracts` project should be like t
### Implementing the Application Service
-Before creating the `OrderAppService` class, we need to add the `Volo.Abp.Ddd.Application` and `Volo.Abp.AutoMapper` packages to the Ordering module.
-
-Right-click the `ModularCrm.Ordering` package in the *Solution Explorer* panel and select the *Add Package Reference* command:
-
-
-
-This command opens a dialog to add a new package reference:
-
-
-
-Select the *NuGet* tab, enter `Volo.Abp.Ddd.Application` as the *Package name*, and specify the version of the package you wish to install. Afterward, you can add the `Volo.Abp.AutoMapper` package in the same dialog. Ensure that you install the same version as the other ABP packages you are already using.
-
-Click the *OK* button. Now we should configure the *AutoMapper* object to map the `Order` entity to the `OrderDto` object. We will create a class named `OrderingApplicationAutoMapperProfile` under the `ModularCrm.Ordering` project:
+Now we should configure the *AutoMapper* object to map the `Order` entity to the `OrderDto` object. We will use the `OrderingAutoMapperProfile` under the `ModularCrm.Ordering` project:
````csharp
using AutoMapper;
-using ModularCrm.Ordering.Contracts.Services;
using ModularCrm.Ordering.Entities;
+using ModularCrm.Ordering.Services;
namespace ModularCrm.Ordering;
-public class OrderingApplicationAutoMapperProfile : Profile
+public class OrderingAutoMapperProfile : Profile
{
- public OrderingApplicationAutoMapperProfile()
+ public OrderingAutoMapperProfile()
{
CreateMap();
}
}
````
-And configure the `OrderingWebModule` class to use the `OrderingApplicationAutoMapperProfile`:
-
-````csharp
-public override void ConfigureServices(ServiceConfigurationContext context)
-{
- //Add these lines
- context.Services.AddAutoMapperObjectMapper();
- Configure(options =>
- {
- options.AddMaps(validate: true);
- });
-}
-````
-
Now, we can implement the `IOrderAppService` interface. Create an `OrderAppService` class under the `Services` folder of the `ModularCrm.Ordering` project:
````csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
-using ModularCrm.Ordering.Contracts.Enums;
-using ModularCrm.Ordering.Contracts.Services;
+using ModularCrm.Ordering.Enums;
using ModularCrm.Ordering.Entities;
-using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace ModularCrm.Ordering.Services;
-public class OrderAppService : ApplicationService, IOrderAppService
+public class OrderAppService : OrderingAppService, IOrderAppService
{
private readonly IRepository _orderRepository;
public OrderAppService(IRepository orderRepository)
{
_orderRepository = orderRepository;
- ObjectMapperContext = typeof(OrderingWebModule);
}
public async Task> GetListAsync()
@@ -415,7 +358,7 @@ private void ConfigureAutoApiControllers()
options.ConventionalControllers.Create(typeof(ProductsApplicationModule).Assembly);
//ADD THE FOLLOWING LINE:
- options.ConventionalControllers.Create(typeof(OrderingWebModule).Assembly);
+ options.ConventionalControllers.Create(typeof(OrderingModule).Assembly);
});
}
````
@@ -442,32 +385,17 @@ If you check the database, you should see the entities created in the *Orders* t
## Creating the User Interface
-### Creating a `_ViewImports.cshtml` File
-
-Open the `ModularCrm.Ordering` .NET solution in your favorite IDE, locate the `ModularCrm.Ordering` project and create a `Pages` folder under that project. Then add a `_ViewImports.cshtml` file under that `Pages` folder with the following content:
-
-````csharp
-@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI
-@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bootstrap
-@addTagHelper *, Volo.Abp.AspNetCore.Mvc.UI.Bundling
-````
-
-That file imports some tag helpers from ASP.NET Core and ABP. The `Pages` folder should be like the following figure:
-
-
-
### Creating the Orders Page
-Create an `Orders` folder under the `Pages` folder and add an `Index.cshtml` Razor Page inside that new folder. Then replace the `Index.cshtml.cs` content with the following code block:
+Replace the `Index.cshtml.cs` content in the `Pages/Ordering` folder of the `ModularCrm.Ordering.UI` project with the following code block:
````csharp
-using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Threading.Tasks;
-using ModularCrm.Ordering.Contracts.Services;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using ModularCrm.Ordering.Services;
-namespace ModularCrm.Ordering.Pages.Orders
+namespace ModularCrm.Ordering.UI.Pages.Ordering
{
public class IndexModel : PageModel
{
@@ -488,11 +416,11 @@ namespace ModularCrm.Ordering.Pages.Orders
}
````
-Here, we are injecting a repository to query `Order` entities from the database to show on the page. Open the `Index.cshtml` file and replace the content with the following code block:
+Here, we are injecting `IOrderAppService` to query `Order` entities from the database to show on the page. Open the `Index.cshtml` file and replace the content with the following code block:
````html
@page
-@model ModularCrm.Ordering.Pages.Orders.IndexModel
+@model ModularCrm.Ordering.UI.Pages.Ordering.IndexModel
Orders
@@ -514,87 +442,65 @@ Here, we are injecting a repository to query `Order` entities from the database
This page shows a list of orders on the UI. We haven't created a UI to create new orders, and we will not do it to keep this tutorial simple. If you want to learn how to create advanced UIs with ABP, please follow the [Book Store tutorial](../book-store/index.md).
-### Building the Application
-
-Now, we will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm.Web` application, and select the *Build* -> *Graph Build* command:
-
-
-
-We've performed a graph build since we've made a change on a module, and more than building the main application is needed. *Graph Build* command also builds the depended modules if necessary. Alternatively, you could build the Ordering module first (on ABP Studio or your IDE), then right-click the `ModularCrm.Web` application and select the *Run* -> *Build & Start*. This approach can be faster if you have too many modules and you make a change in one of the modules.
-
-### Running the Application
-
-Run the main application on ABP Studio, manually type `/Orders` to the end of your application's URL to open the *Orders* page:
-
-
-
-Great! We can see the list of orders. However, there are two problems:
-
-1. The Order page has no menu item on the main menu. This is because we haven't configured the [navigation menu system](../../framework/ui/mvc-razor-pages/navigation-menu.md) yet.
-2. We see Product's GUID ID instead of its name. This is because the Ordering module has no integration with the Products module and doesn't have access to Product module's database to perform a JOIN query.
-
-We will solve the second problem in the [next part](part-06.md), but we can easily add a menu item for the Orders page now.
-
-### Adding a Menu Item
+### Editing the Menu Item
ABP provides a modular navigation [menu system](../../framework/ui/mvc-razor-pages/navigation-menu.md) where each module can contribute to the main menu dynamically.
-Open the `ModularCrm.Ordering` .NET solution in your IDE and add the following `OrderingMenuContributor` class into the `ModularCrm.Ordering` project:
+Edit the `OrderingMenuContributor` class into the `ModularCrm.Ordering.UI` project:
````csharp
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
-namespace ModularCrm.Ordering
+namespace ModularCrm.Ordering.UI.Menus;
+
+public class OrderingMenuContributor : IMenuContributor
{
- public class OrderingMenuContributor : IMenuContributor
+ public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
- public Task ConfigureMenuAsync(MenuConfigurationContext context)
+ if (context.Menu.Name == StandardMenus.Main)
{
- if (context.Menu.Name == StandardMenus.Main)
- {
- context.Menu.AddItem(
- new ApplicationMenuItem(
- "ModularCrm.Orders.Index", // Unique menu id
- "Orders", // Menu display text
- "~/Orders", // URL
- "fa-solid fa-basket-shopping" // Icon CSS class
- )
- );
- }
-
- return Task.CompletedTask;
+ await ConfigureMainMenuAsync(context);
}
}
+
+ private Task ConfigureMainMenuAsync(MenuConfigurationContext context)
+ {
+ context.Menu.AddItem(
+ new ApplicationMenuItem(
+ OrderingMenus.Prefix, // Unique menu id
+ "Orders", // Menu display text
+ "~/Ordering", // URL
+ "fa-solid fa-basket-shopping" // Icon CSS class
+ )
+ );
+
+ return Task.CompletedTask;
+ }
}
+
````
`OrderingMenuContributor` implements the `IMenuContributor` interface, which forces us to implement the `ConfigureMenuAsync` method. In that method, we can manipulate the menu items (add new menu items, remove existing menu items or change the properties of existing menu items). The `ConfigureMenuAsync` method is executed whenever the menu is rendered on the UI, so you can dynamically decide how to manipulate the menu items.
-After creating such a class, we should configure the `AbpNavigationOptions` to add that contributor. Open the `OrderingWebModule` class in the `ModularCrm.Ordering` project and add the following configuration code into the `ConfigureServices` method:
+> You can check the [menu documentation](../../framework/ui/mvc-razor-pages/navigation-menu.md) to learn more about manipulating menu items.
-````csharp
-public override void ConfigureServices(ServiceConfigurationContext context)
-{
- //... other configurations
+### Building the Application
- Configure(options =>
- {
- options.MenuContributors.Add(new OrderingMenuContributor());
- });
-}
-````
+Now, we will run the application to see the result. Please stop the application if it is already running. Then open the *Solution Runner* panel, right-click the `ModularCrm.Web` application, and select the *Build* -> *Graph Build* command:
+
+
-That's all. You can stop the main application (if it is already working), make a graph build on the main application, run it again on ABP Studio's *Solution Runner* panel and *Browse* it to see the result:
+We've performed a graph build since we've made a change on a module, and more than building the main application is needed. *Graph Build* command also builds the depended modules if necessary. Alternatively, you could build the Ordering module first (on ABP Studio or your IDE), then right-click the `ModularCrm.Web` application and select the *Run* -> *Build & Start*. This approach can be faster if you have too many modules and you make a change in one of the modules. Now you can run the application by right-clicking the `ModularCrm.Web` application and selecting the *Run* -> *Start* command.

-The *Orders* menu item is added under the *Products* menu item.
+Great! We can see the list of orders. However, there is a problem:
-> You can check the [menu documentation](../../framework/ui/mvc-razor-pages/navigation-menu.md) to learn more about manipulating menu items.
+1. We see Product's GUID ID instead of its name. This is because the Ordering module has no integration with the Products module and doesn't have access to Product module's database to perform a JOIN query.
-## Summary
+We will solve this problem in the [next part](part-06.md).
-In this part of the *Modular CRM* tutorial, we've built the functionality inside the Ordering module we created in the [previous part](part-04.md). Since we've created the Ordering module from scratch (with the *Empty Module* template), we had to implement many aspects manually, add ABP packages, create some configuration classes, etc. It is good to do all these manually for one time to learn the things, but it is better to use the other module templates (that pre-configure the fundamentals for us) for a more comfortable development experience.
+## Summary
-In the next part, we will work on establishing communication between the Orders module and the Products module.
+In this part of the *Modular CRM* tutorial, we've built the functionality inside the Ordering module we created in the [previous part](part-04.md). In the next part, we will work on establishing communication between the Orders module and the Products module.
diff --git a/docs/en/tutorials/modular-crm/part-06.md b/docs/en/tutorials/modular-crm/part-06.md
index 55e04259bb..36e4f22a64 100644
--- a/docs/en/tutorials/modular-crm/part-06.md
+++ b/docs/en/tutorials/modular-crm/part-06.md
@@ -26,9 +26,9 @@ Let's begin from the first one: The Integration Services.
## The Need for the Integration Services
-Remember from the [previous part](part-05.md), the Orders page shows products' identities instead of their names:
+Remember from the [previous part](part-05.md), the Orders page shows product's identities instead of their names:
-
+
That is because the Orders module has no access to the product data, so it can not perform a JOIN query to get the names of products from the `Products` table. That is a natural result of the modular design. However, we also don't want to show a product's identity on the UI, which is not a good user experience.
@@ -152,8 +152,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using ModularCrm.Ordering.Contracts.Enums;
-using ModularCrm.Ordering.Contracts.Services;
+using ModularCrm.Ordering.Enums;
using ModularCrm.Ordering.Entities;
using ModularCrm.Products.Integration;
using Volo.Abp.Application.Services;
@@ -172,7 +171,6 @@ public class OrderAppService : ApplicationService, IOrderAppService
{
_orderRepository = orderRepository;
_productIntegrationService = productIntegrationService;
- ObjectMapperContext = typeof(OrderingWebModule);
}
public async Task> GetListAsync()
@@ -182,7 +180,7 @@ public class OrderAppService : ApplicationService, IOrderAppService
// Prepare a list of products we need
var productIds = orders.Select(o => o.ProductId).Distinct().ToList();
var products = (await _productIntegrationService
- .GetProductsByIdsAsync(productIds))
+ .GetProductsByIdsAsync(productIds))
.ToDictionary(p => p.Id, p => p.Name);
var orderDtos = ObjectMapper.Map, List>(orders);
@@ -213,9 +211,9 @@ And also, open the `OrderDto` class (the `OrderDto.cs` file under the `Services`
````csharp
using System;
-using ModularCrm.Ordering.Contracts.Enums;
+using ModularCrm.Ordering.Enums;
-namespace ModularCrm.Ordering.Contracts.Services;
+namespace ModularCrm.Ordering.Services;
public class OrderDto
{
@@ -227,11 +225,11 @@ public class OrderDto
}
````
-Lastly, open the `OrderingApplicationAutoMapperProfile` class (the `OrderingApplicationAutoMapperProfile.cs` file under the `Services` folder of the `ModularCrm.Ordering` project of the `ModularCrm.Ordering` .NET solution) and ignore the `ProductName` property in the mapping configuration:
+Lastly, open the `OrderingAutoMapperProfile` class (the `OrderingAutoMapperProfile.cs` file under the `Services` folder of the `ModularCrm.Ordering` project of the `ModularCrm.Ordering` .NET solution) and ignore the `ProductName` property in the mapping configuration:
````csharp
using AutoMapper;
-using ModularCrm.Ordering.Contracts.Services;
+using ModularCrm.Ordering.Services;
using ModularCrm.Ordering.Entities;
using Volo.Abp.AutoMapper;
@@ -262,7 +260,7 @@ Open the `Index.cshtml` file, and change the `@order.ProductId` part by `@Model.
````html
@page
-@model ModularCrm.Ordering.Pages.Orders.IndexModel
+@model ModularCrm.Ordering.UI.Pages.Ordering.IndexModel