@ -105,3 +105,7 @@ ABP is a community-driven open source project. See [the contribution guide](http
## Support the ABP Framework
Love ABP Framework? **Please give a star** to this repository :star:
## ABP Commercial
See also [ABP Commercial](https://commercial.abp.io/) if you are looking for pre-built application modules, professional themes, code generation tooling and premium support for the ABP Framework.
"SeeCliDocumentForMoreInformation":"Weitere Optionen finden Sie im <a href=\"{0}\">ABP CLI-Dokument</a> oder wählen Sie oben die Registerkarte \"Direkter Download\".",
"Optional":"Optional",
"LocalFrameworkRef":"Behalten Sie die lokale Projektreferenz für die Framework-Pakete bei.",
"SelectLanguage":"Sprache auswählen"
"SelectLanguage":"Sprache auswählen",
"LatestArticleOnCommunity":"Neuester Artikel zur ABP Community",
"MultipleUIOptionsExplanation":"The core framework is designed as UI independent and can work with any type of UI system, while there are multiple pre-built and integrated options are provided out of the box.",
"MultipleDBOptionsExplanation":"The framework can work with any data source, while the following providers are officially developed and supported:",
"SelectLanguage":"Select language"
"SelectLanguage":"Select language",
"LatestArticleOnCommunity":"Latest Article on ABP Community"
"MultipleUIOptionsExplanation":"The core framework is designed as UI independent and can work with any type of UI system, while there are multiple pre-built and integrated options are provided out of the box.",
"MultipleDBOptionsExplanation":"The framework can work with any data source, while the following providers are officially developed and supported;",
"SelectLanguage":"Select language"
"SelectLanguage":"Select language",
"LatestArticleOnCommunity":"Latest Article on ABP Community",
"SeeCliDocumentForMoreInformation":"Ver el <a href=\"{0}\">documento ABP CLI </a> para más opciones o selecciona la \"Direct Download\" pestaña de arriba.",
"Optional":"Opcional",
"LocalFrameworkRef":"Mantén la referencia al proyecto local para los paquetes del framework.",
"SelectLanguage":"Vali keel"
"SelectLanguage":"Vali keel",
"LatestArticleOnCommunity":"Último artículo sobre la comunidad ABP",
@ -242,12 +242,15 @@ In addition, all of the `IDistributedCache<TCacheItem>` (and `IDistributedCache<
## Batch Operations
ABP's distributed cache interfaces provide methods to perform batch get/set methods those improves the performance when you want to get or set multiple cache items in a single method call.
ABP's distributed cache interfaces provide methods to perform batch methods those improves the performance when you want to batch operation multiple cache items in a single method call.
* `SetManyAsync` and `SetMany` methods can be used to set multiple values to the cache.
* `GetManyAsync` and `GetMany` methods can be used to retrieve multiple values from the cache.
* `GetOrAddManyAsync` and `GetOrAddMany` methods can be used to retrieve multiple values and set missing values from the cache
* `RefreshManyAsync` and `RefreshMany` methods can be used to resets the sliding expiration timeout of multiple values from the cache
* `RemoveManyAsync` and `RemoveMany` methods can be used to remove multiple values from the cache
> These are not standard methods of the ASP.NET Core caching. So, some providers may not support them. They are supported by the [ABP Redis Cache integration package](Redis-Cache.md). If the provider doesn't support, it fallbacks to `SetAsync` and `GetAsync` methods (called once for each item).
> These are not standard methods of the ASP.NET Core caching. So, some providers may not support them. They are supported by the [ABP Redis Cache integration package](Redis-Cache.md). If the provider doesn't support, it fallbacks to `SetAsync` and `GetAsync`... methods (called once for each item).
This template can be used to create a **reusable [application module](../Modules/Index.md)** based on the [module development best practices & conventions](../Best-Practices/Index.md). It is also suitable for creating **microservices** (with or without UI).
@ -20,6 +20,20 @@ abp new Acme.IssueManagement -t module
- `Acme.IssueManagement` is the solution name, like *YourCompany.YourProduct*. You can use single level, two-levels or three-levels naming.
### Specify the UI Framework
This template provides multiple UI frameworks:
* `mvc`: ASP.NET Core MVC UI with Razor Pages (default)
* `blazor`: Blazor UI
* `angular`: Angular UI
Use `-u` or `--ui` option to specify the UI framework:
````bash
abp new Acme.IssueManagement -t module -u angular
````
### Without User Interface
The template comes with an MVC UI by default. You can use `--no-ui` option to not include the UI layer.
@ -160,3 +174,91 @@ You should run the application with the given order:
- First, run the `.IdentityServer` since other applications depends on it.
- Then run the `.HttpApi.Host` since it is used by the `.Web.Host` application.
- Finally, you can run the `.Web.Host` project and login to the application using `admin` as the username and `1q2w3E*` as the password.
## UI
### Angular UI
If you choose `Angular` as the UI framework (using the `-u angular` option), the solution will have a folder called `angular` in it. This is where the client-side code is located. When you open that folder in an IDE, the folder structure will look like below:

* _angular/projects/issue-management_ folder contains the Angular module project.
* _angular/projects/dev-app_ folder contains a development application that runs your module.
The server-side is similar to the solution described above. `*.HttpApi.Host` project serves the API and the `Angular` demo application consumes it. You will not need to run the `.Web.Host` project though.
#### How to Run the Angular Development App
For module development, you will need the `dev-app` project up and running. So, here is how we can start the development server.
First, we need to install dependencies:
1. Open your terminal at the root folder, i.e. `angular`.
2. Run `yarn` or `npm install`.
The dependencies will be installed and some of them are ABP modules published as NPM packages. To see all ABP packages, you can run the following command in the `angular` folder:
```bash
yarn list --pattern abp
```
> There is no equivalent of this command in npm.
The module you will develop depends on two of these ABP packages: _@abp/ng.core_ and _@abp/ng.theme.shared_. Rest of the ABP modules are included in _package.json_ because of the `dev-app` project.
Once all dependencies are installed, follow the steps below to serve your development app:
1. Make sure `.IdentityServer` and `*.HttpApi.Host` projects are up and running.
2. Open your terminal at the root folder, i.e. `angular`.
The issue management page is empty in the beginning. You may change the content in `IssueManagementComponent` at the _angular/projects/issue-management/src/lib/issue-management.component.ts_ path and observe that the view changes accordingly.
Now, let's have a closer look at some key elements of your project.
#### Main Module
`IssueManagementModule` at the _angular/projects/issue-management/src/lib/issue-management.module.ts_ path is the main module of your module project. There are a few things worth mentioning in it:
- Essential ABP modules, i.e. `CoreModule` and `ThemeSharedModule`, are imported.
- `IssueManagementRoutingModule` is imported.
- `IssueManagementComponent` is declared.
- It is prepared for configurability. The `forLazy` static method enables [a configuration to be passed to the module when it is loaded by the router](https://volosoft.com/blog/how-to-configure-angular-modules-loaded-by-the-router).
#### Main Routing Module
`IssueManagementRoutingModule` at the _angular/projects/issue-management/src/lib/issue-management-routing.module.ts_ path is the main routing module of your module project. It currently does two things:
- Loads `DynamicLayoutComponent` at base path it is given.
- Loads `IssueManagementComponent` as child to the layout, again at the given base path.
You can rearrange this module to load more than one component at different routes, but you need to update the route provider at _angular/projects/issue-management/config/src/providers/route.provider.ts_ to match the new routing structure with the routes in the menu. Please check [Modifying the Menu](../UI/Angular/Modifying-the-Menu.md) to see how route providers work.
#### Config Module
There is a config module at the _angular/projects/issue-management/config/src/issue-management-config.module.ts_ path. The static `forRoot` method of this module is supposed to be called at the route level. So, you may assume the following will take place:
```js
@NgModule({
imports: [
/* other imports */
IssueManagementConfigModule.forRoot(),
],
/* rest of the module meta data */
})
export class AppModule {}
```
You can use this static method to configure an application that uses your module project. An example of such configuration is already implemented and the `ISSUE_MANAGEMENT_ROUTE_PROVIDERS` token is provided here. The method can take options which enables further configuration possibilities.
The difference between the `forRoot` method of the config module and the `forLazy` method of the main module is that, for smallest bundle size, the former should only be used when you have to configure an app before your module is even loaded.
#### Testing Angular UI
Please see the [testing document](../UI/Angular/Testing.md).
> If you get an error like "*Your startup project ... doesn't reference Microsoft.EntityFrameworkCore.Design. This package is required for the Entity Framework Core Tools to work*", right click to the `Acme.BookStore.EntityFrameworkCore.DbMigrations` project and **Set as the Startup Project** and try again.
This will create a new migration class inside the `Migrations` folder of the `Acme.BookStore.EntityFrameworkCore.DbMigrations` project.
Before updating the database, read the section below to learn how to seed some initial data to the database.
@ -70,7 +70,7 @@ This is just like done for the `Book` entity before, so no need to explain again
## Create a new Database Migration
Open the **Package Manager Console** on Visual Studio and ensure that the **Default project** is `Acme.BookStore.EntityFrameworkCore.DbMigrations` in the Package Manager Console, as shown on the picture below. Also, set the `Acme.BookStore.Web` (or `Acme.BookStore.HttpApi.Host`, depending on your solution) as the **startup project** (right click it on the solution explorer and click to "Set as Startup Project").
Open the **Package Manager Console** on Visual Studio and ensure that the **Default project** is `Acme.BookStore.EntityFrameworkCore.DbMigrations` in the Package Manager Console, as shown on the picture below. Also, set this project as the **startup project** (right click it on the solution explorer and click to "Set as Startup Project").
Run the following command to create a new database migration:
/// Represents a distributed cache of <typeparamref name="TCacheItem" /> type.
/// Uses a generic cache key type of <typeparamref name="TCacheKey" /> type.
@ -128,6 +128,44 @@ namespace Volo.Abp.Caching
CancellationTokentoken=default
);
/// <summary>
/// Gets or Adds multiple cache items with the given keys. If any cache items not found for the given keys then adds cache items
/// provided by <paramref name="factory" /> delegate and returns the provided cache items.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="factory">The factory delegate is used to provide the cache items when no cache items are found for the given <paramref name="keys" />.</param>
/// <param name="optionsFactory">The cache options for the factory delegate.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// Gets or Adds multiple cache items with the given keys. If any cache items not found for the given keys then adds cache items
/// provided by <paramref name="factory" /> delegate and returns the provided cache items.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="factory">The factory delegate is used to provide the cache items when no cache items are found for the given <paramref name="keys" />.</param>
/// <param name="optionsFactory">The cache options for the factory delegate.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// Sets the cache item value for the provided key.
/// </summary>
@ -219,6 +257,29 @@ namespace Volo.Abp.Caching
CancellationTokentoken=default
);
/// <summary>
/// Refreshes the cache value of the given keys, and resets their sliding expiration timeout.
/// Based on the implementation, this can be more efficient than setting multiple items individually.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
voidRefreshMany(
IEnumerable<TCacheKey>keys,
bool?hideErrors=null);
/// <summary>
/// Refreshes the cache value of the given keys, and resets their sliding expiration timeout.
/// Based on the implementation, this can be more efficient than setting multiple items individually.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> indicating that the operation is asynchronous.</returns>
TaskRefreshManyAsync(
IEnumerable<TCacheKey>keys,
bool?hideErrors=null,
CancellationTokentoken=default);
/// <summary>
/// Removes the cache item for given key from cache.
/// </summary>
@ -245,5 +306,32 @@ namespace Volo.Abp.Caching
boolconsiderUow=false,
CancellationTokentoken=default
);
/// <summary>
/// Removes the cache items for given keys from cache.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
voidRemoveMany(
IEnumerable<TCacheKey>keys,
bool?hideErrors=null,
boolconsiderUow=false
);
/// <summary>
/// Removes the cache items for given keys from cache.
/// </summary>
/// <param name="keys">The keys of cached items to be retrieved from the cache.</param>
/// <param name="hideErrors">Indicates to throw or hide the exceptions for the distributed cache.</param>
/// <param name="considerUow">This will store the cache in the current unit of work until the end of the current unit of work does not really affect the cache.</param>
/// <param name="token">The <see cref="T:System.Threading.CancellationToken" /> for the task.</param>
/// <returns>The <see cref="T:System.Threading.Tasks.Task" /> indicating that the operation is asynchronous.</returns>