From a4b5ddfc53a510266a5b7a9fd9bef28fd943ef28 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Wed, 30 Nov 2022 17:07:48 +0300 Subject: [PATCH 1/6] docs: Add distributed entity caching --- docs/en/Caching.md | 11 +- docs/en/Deployment/Clustered-Environment.md | 2 +- docs/en/Entities.md | 8 + docs/en/Entity-Cache.md | 183 ++++++++++++++++++++ docs/en/docs-nav.json | 4 + 5 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 docs/en/Entity-Cache.md diff --git a/docs/en/Caching.md b/docs/en/Caching.md index 8fafd725be..50e8ed0e4e 100644 --- a/docs/en/Caching.md +++ b/docs/en/Caching.md @@ -10,7 +10,7 @@ ABP Framework extends the [ASP.NET Core distributed cache](https://docs.microsof [Volo.Abp.Caching](https://www.nuget.org/packages/Volo.Abp.Caching) is the main package of the caching system. You can install it a project using the add-package command of the [ABP CLI](CLI.md): -``` +```bash abp add-package Volo.Abp.Caching ``` @@ -252,6 +252,14 @@ ABP's distributed cache interfaces provide methods to perform batch methods thos > 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). +## Caching Entities + +ABP Framework provides a [Distributed Entity Cache System](Entity-Cache.md) for caching entities. It is useful if you want to use caching for quicker access to the entity rather than repeatedly querying it from the database. + +It's designed as read-only and automatically invalidates a cached entity if the entity is updated or deleted. + +> See [Entity Cache](Entity-Cache.md) documentation for more information. + ## Advanced Topics ### Unit Of Work Level Cache @@ -272,4 +280,5 @@ You can [replace](Dependency-Injection.md) this service by your own implementati ## See Also +* [Entity Cache](Entity-Cache.md) * [Redis Cache](Redis-Cache.md) \ No newline at end of file diff --git a/docs/en/Deployment/Clustered-Environment.md b/docs/en/Deployment/Clustered-Environment.md index 2dace9a7f7..e3294b3469 100644 --- a/docs/en/Deployment/Clustered-Environment.md +++ b/docs/en/Deployment/Clustered-Environment.md @@ -63,7 +63,7 @@ The [Database BLOB provider](../Blob-Storing-Database) is the easiest way since > [ABP Commercial](https://commercial.abp.io/) startup solution templates come with the database BLOB provider as pre-installed, and stores BLOBs in the application's database. -Check the [BLOB Storing](../Blob-Storing.md) document to see all the available BLOG storage providers. +Check the [BLOB Storing](../Blob-Storing.md) document to see all the available BLOB storage providers. ## Configuring Background Jobs diff --git a/docs/en/Entities.md b/docs/en/Entities.md index ef8f52a04f..3eac4b2164 100644 --- a/docs/en/Entities.md +++ b/docs/en/Entities.md @@ -316,6 +316,14 @@ All these base classes also have non-generic versions to take `AuditedEntity` an All these base classes also have `...WithUser` pairs, like `FullAuditedAggregateRootWithUser` and `FullAuditedAggregateRootWithUser`. This makes possible to add a navigation property to your user entity. However, it is not a good practice to add navigation properties between aggregate roots, so this usage is not suggested (unless you are using an ORM, like EF Core, that well supports this scenario and you really need it - otherwise remember that this approach doesn't work for NoSQL databases like MongoDB where you must truly implement the aggregate pattern). Also, if you add navigation properties to the AppUser class that comes with the startup template, consider to handle (ignore/map) it on the migration dbcontext (see [the EF Core migration document](Entity-Framework-Core-Migrations.md)). +## Caching Entities + +ABP Framework provides a [Distributed Entity Cache System](Entity-Cache.md) for caching entities. It is useful if you want to use caching for quicker access to the entity rather than repeatedly querying it from the database. + +It's designed as read-only and automatically invalidates a cached entity if the entity is updated or deleted. + +> See [Entity Cache](Entity-Cache.md) documentation for more information. + ## Extra Properties ABP defines the `IHasExtraProperties` interface that can be implemented by an entity to be able to dynamically set and get properties for the entity. `AggregateRoot` base class already implements the `IHasExtraProperties` interface. If you've derived from this class (or one of the related audit class defined above), you can directly use the API. diff --git a/docs/en/Entity-Cache.md b/docs/en/Entity-Cache.md new file mode 100644 index 0000000000..e285ff8039 --- /dev/null +++ b/docs/en/Entity-Cache.md @@ -0,0 +1,183 @@ +# Entity Cache + +ABP Framework provides **Distributed Entity Caching System** for caching entities. + +You can use this caching mechanism if you want to cache your entity objects automatically and retrieve them from a cache instead of querying it from a database repeatedly. + +## How Distributed Entity Caching System Works? + +ABP's Entity Caching System does the following operations on behalf of you: + +* It gets the entity from the database (by using the [Repositories](Repositories.md)) in its first call and then gets from the cache in subsequent calls. +* It automatically invalidates the cached entity if the entity is updated or deleted. Thus, it will be retrieved from the database in the next call and will be re-cached. +* It uses the cache class's **FullName** as a cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. + +## Installation + +[Volo.Abp.Caching](https://www.nuget.org/packages/Volo.Abp.Caching) is the main package for the ABP's caching system and it's already installed in [the application startup template](Startup-Templates/Index.md). So, you don't need to install it manually. + +## Usage + +`IEntityCache` is a simple service provided by the ABP Framework for caching entities. It's designed as read-only and contains two methods: `FindAsync` and `GetAsync`. + +### Caching Entities + +**Example: `Product` entity** + +```csharp +[CacheName("Products")] +public class Product : AggregateRoot +{ + public string Name { get; set; } + public string Description { get; set; } + public float Price { get; set; } + public int StockCount { get; set; } +} +``` + +* This example uses the `CacheName` attribute for the `Product` class to set the cache name. By default, the cache class's **FullName** is used for the cache name. + +If you want to cache this entity, first you should configure the [dependency injection](Dependency-Injection.md) to register the `IEntityCache` service in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): + +```csharp +context.Services.AddEntityCache(); +``` + +Then configure the [object mapper](https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping) (for `Product` to `ProductDto` mapping): + +```csharp +public class MyProjectNameAutoMapperProfile : Profile +{ + public MyProjectNameAutoMapperProfile() + { + //other mappings... + + CreateMap(); + } +} +``` + +Now you can inject the `IEntityCache` service wherever you need: + +```csharp +public class ProductAppService : ApplicationService, IProductAppService +{ + private readonly IEntityCache _productCache; + + public ProductAppService(IEntityCache productCache) + { + _productCache = productCache; + } + + public async Task GetAsync(Guid id) + { + var product = await _productCache.GetAsync(id); + return ObjectMapper.Map(product); + } +} +``` + +* Here, we've directly cached the `Product` entity. In that case, the `Product` class must be serializable. Sometimes this might not be possible and you may want to use another class to store the cache data. For example, we may want to use the `ProductDto` class instead of the `Product` class for the cached object if the `Product` entity is not serializable. + +### Caching Cache Item Classes + +`IEntityCache` service can be used for caching other cache item classes if the entity is not serializable. + +**Example: `ProductDto` class** + +```csharp +public class ProductDto : EntityDto +{ + public string Name { get; set; } + public string Description { get; set; } + public float Price { get; set; } + public int StockCount { get; set; } +} +``` + +Register the entity cache services to [dependency injection](Dependency-Injection.md) in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): + +```csharp +context.Services.AddEntityCache(); +``` + +Configure the [object mapper](https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping) (for `Product` to `ProductDto` mapping): + +```csharp +public class MyProjectNameAutoMapperProfile : Profile +{ + public MyProjectNameAutoMapperProfile() + { + //other mappings... + + CreateMap(); + } +} +``` + +Then, you can inject the `IEntityCache` service wherever you want: + +```csharp +public class ProductAppService : ApplicationService, IProductAppService +{ + private readonly IEntityCache _productCache; + + public ProductAppService(IEntityCache productCache) + { + _productCache = productCache; + } + + public async Task GetAsync(Guid id) + { + return await _productCache.GetAsync(id); + } +} +``` + +## Configurations + +### Registering the Entity Cache Services + +You can use one of the `AddEntityCache` methods to register entity cache services to the [Dependency Injection](Dependency-Injection.md) system. + +```csharp +public override void ConfigureServices(ServiceConfigurationContext context) +{ + var configuration = context.Services.GetConfiguration(); + + //other configurations... + + //directly cache the entity object (Basket) + context.Services.AddEntityCache(); + + //cache the ProductDto class + context.Services.AddEntityCache(); +} +``` + +* You can register entity cache by using the `context.Services.AddEntityCache()` method for directly cache the entity object. +* Or alternatively, you can use the `context.Services.AddEntityCache()` method to configure entities that are mapped to a cache item. + +### Caching Options + +All of the `context.Services.AddEntityCache()` methods get an optional `DistributedCacheEntryOptions` parameter where you can easily configure the caching options: + +```csharp +context.Services.AddEntityCache( + new DistributedCacheEntryOptions + { + SlidingExpiration = TimeSpan.FromMinutes(30) + } +); +``` + +> The default cache duration is **2 minutes** with the `AbsoluteExpirationRelativeToNow` configuration and by configuring the `DistributedCacheEntryOptions` you can change it easily. + +## Additonal Notes + +* Entity classes should be serializable/deserializable to/from JSON to be cached (because it's serialized to JSON when saving in the [Distributed Cache](Caching.md)). If your entity class is not serializable, you can consider using a cache-item/DTO class instead, as mentioned in the *Usage* section above. +* Entity Caching System is designed as **read-only**. So, you shouldn't make changes to the same entity when you use the entity cache. Instead, you should always read it from the database to ensure transactional consistency. + +## See Also + +* [Caching](Caching.md) \ No newline at end of file diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index ef6b0cad07..a0a50766f7 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -193,6 +193,10 @@ "text": "Caching", "path": "Caching.md", "items": [ + { + "text": "Entity Cache", + "path": "Entity-Cache.md" + }, { "text": "Redis Cache", "path": "Redis-Cache.md" From 811e21ba73e3de1cd61441404ec66600868ebe01 Mon Sep 17 00:00:00 2001 From: Engincan VESKE <43685404+EngincanV@users.noreply.github.com> Date: Wed, 30 Nov 2022 19:13:19 +0300 Subject: [PATCH 2/6] Update Entity-Cache.md --- docs/en/Entity-Cache.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Entity-Cache.md b/docs/en/Entity-Cache.md index e285ff8039..4ab83c9a01 100644 --- a/docs/en/Entity-Cache.md +++ b/docs/en/Entity-Cache.md @@ -10,7 +10,6 @@ ABP's Entity Caching System does the following operations on behalf of you: * It gets the entity from the database (by using the [Repositories](Repositories.md)) in its first call and then gets from the cache in subsequent calls. * It automatically invalidates the cached entity if the entity is updated or deleted. Thus, it will be retrieved from the database in the next call and will be re-cached. -* It uses the cache class's **FullName** as a cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. ## Installation @@ -177,6 +176,7 @@ context.Services.AddEntityCache( * Entity classes should be serializable/deserializable to/from JSON to be cached (because it's serialized to JSON when saving in the [Distributed Cache](Caching.md)). If your entity class is not serializable, you can consider using a cache-item/DTO class instead, as mentioned in the *Usage* section above. * Entity Caching System is designed as **read-only**. So, you shouldn't make changes to the same entity when you use the entity cache. Instead, you should always read it from the database to ensure transactional consistency. +* Entity Caching System uses the cache class's **FullName** as the cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. ## See Also From 13f14fd1aba79993e3903ff76c1c05087de769bf Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Thu, 1 Dec 2022 10:23:45 +0300 Subject: [PATCH 3/6] tiny fix --- docs/en/Caching.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/Caching.md b/docs/en/Caching.md index 50e8ed0e4e..e39e0ead24 100644 --- a/docs/en/Caching.md +++ b/docs/en/Caching.md @@ -258,7 +258,7 @@ ABP Framework provides a [Distributed Entity Cache System](Entity-Cache.md) for It's designed as read-only and automatically invalidates a cached entity if the entity is updated or deleted. -> See [Entity Cache](Entity-Cache.md) documentation for more information. +> See the [Entity Cache](Entity-Cache.md) documentation for more information. ## Advanced Topics @@ -281,4 +281,4 @@ You can [replace](Dependency-Injection.md) this service by your own implementati ## See Also * [Entity Cache](Entity-Cache.md) -* [Redis Cache](Redis-Cache.md) \ No newline at end of file +* [Redis Cache](Redis-Cache.md) From f09271c830b969947a5805f32970a8a7f97a43a9 Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Thu, 1 Dec 2022 10:24:52 +0300 Subject: [PATCH 4/6] tiny fix --- docs/en/Entities.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/Entities.md b/docs/en/Entities.md index 3eac4b2164..a1558a73ae 100644 --- a/docs/en/Entities.md +++ b/docs/en/Entities.md @@ -322,7 +322,7 @@ ABP Framework provides a [Distributed Entity Cache System](Entity-Cache.md) for It's designed as read-only and automatically invalidates a cached entity if the entity is updated or deleted. -> See [Entity Cache](Entity-Cache.md) documentation for more information. +> See the [Entity Cache](Entity-Cache.md) documentation for more information. ## Extra Properties From 3b090918652cb9e1061006736017497201c13ef7 Mon Sep 17 00:00:00 2001 From: Hamza Albreem <94292623+braim23@users.noreply.github.com> Date: Thu, 1 Dec 2022 10:39:35 +0300 Subject: [PATCH 5/6] quick fix --- docs/en/Entity-Cache.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/en/Entity-Cache.md b/docs/en/Entity-Cache.md index 4ab83c9a01..d0e5fcc06b 100644 --- a/docs/en/Entity-Cache.md +++ b/docs/en/Entity-Cache.md @@ -1,19 +1,19 @@ # Entity Cache -ABP Framework provides **Distributed Entity Caching System** for caching entities. +ABP Framework provides a **Distributed Entity Caching System** for caching entities. You can use this caching mechanism if you want to cache your entity objects automatically and retrieve them from a cache instead of querying it from a database repeatedly. -## How Distributed Entity Caching System Works? +## How Does the Distributed Entity Caching System Work? ABP's Entity Caching System does the following operations on behalf of you: -* It gets the entity from the database (by using the [Repositories](Repositories.md)) in its first call and then gets from the cache in subsequent calls. +* It gets the entity from the database (by using the [Repositories](Repositories.md)) in its first call and then gets it from the cache in subsequent calls. * It automatically invalidates the cached entity if the entity is updated or deleted. Thus, it will be retrieved from the database in the next call and will be re-cached. ## Installation -[Volo.Abp.Caching](https://www.nuget.org/packages/Volo.Abp.Caching) is the main package for the ABP's caching system and it's already installed in [the application startup template](Startup-Templates/Index.md). So, you don't need to install it manually. +[Volo.Abp.Caching](https://www.nuget.org/packages/Volo.Abp.Caching) is the main package for ABP's caching system and it's already installed in [the application startup template](Startup-Templates/Index.md). So, you don't need to install it manually. ## Usage @@ -36,7 +36,7 @@ public class Product : AggregateRoot * This example uses the `CacheName` attribute for the `Product` class to set the cache name. By default, the cache class's **FullName** is used for the cache name. -If you want to cache this entity, first you should configure the [dependency injection](Dependency-Injection.md) to register the `IEntityCache` service in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): +If you want to cache this entity, you should first configure the [dependency injection](Dependency-Injection.md) to register the `IEntityCache` service in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): ```csharp context.Services.AddEntityCache(); @@ -78,9 +78,9 @@ public class ProductAppService : ApplicationService, IProductAppService * Here, we've directly cached the `Product` entity. In that case, the `Product` class must be serializable. Sometimes this might not be possible and you may want to use another class to store the cache data. For example, we may want to use the `ProductDto` class instead of the `Product` class for the cached object if the `Product` entity is not serializable. -### Caching Cache Item Classes +### Caching the Cache Item Classes -`IEntityCache` service can be used for caching other cache item classes if the entity is not serializable. +The `IEntityCache` service can be used for caching other cache item classes if the entity is not serializable. **Example: `ProductDto` class** @@ -154,7 +154,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) } ``` -* You can register entity cache by using the `context.Services.AddEntityCache()` method for directly cache the entity object. +* You can register the entity cache by using the `context.Services.AddEntityCache()` method to directly cache the entity object. * Or alternatively, you can use the `context.Services.AddEntityCache()` method to configure entities that are mapped to a cache item. ### Caching Options @@ -176,8 +176,8 @@ context.Services.AddEntityCache( * Entity classes should be serializable/deserializable to/from JSON to be cached (because it's serialized to JSON when saving in the [Distributed Cache](Caching.md)). If your entity class is not serializable, you can consider using a cache-item/DTO class instead, as mentioned in the *Usage* section above. * Entity Caching System is designed as **read-only**. So, you shouldn't make changes to the same entity when you use the entity cache. Instead, you should always read it from the database to ensure transactional consistency. -* Entity Caching System uses the cache class's **FullName** as the cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. +* The Entity Caching System uses the cache class's **FullName** as the cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. ## See Also -* [Caching](Caching.md) \ No newline at end of file +* [Caching](Caching.md) From acc74b3ac208c7f465a92acee809161edda8c372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 8 Dec 2022 10:02:51 +0300 Subject: [PATCH 6/6] Update Entity-Cache.md --- docs/en/Entity-Cache.md | 104 ++++++++++------------------------------ 1 file changed, 26 insertions(+), 78 deletions(-) diff --git a/docs/en/Entity-Cache.md b/docs/en/Entity-Cache.md index d0e5fcc06b..834a0d5313 100644 --- a/docs/en/Entity-Cache.md +++ b/docs/en/Entity-Cache.md @@ -1,30 +1,15 @@ # Entity Cache -ABP Framework provides a **Distributed Entity Caching System** for caching entities. +ABP Framework provides an entity caching system that works on top of the [distributed caching](Caching.md) system. It does the following operations on behalf of you: -You can use this caching mechanism if you want to cache your entity objects automatically and retrieve them from a cache instead of querying it from a database repeatedly. +* Gets the entity from the database (by using the [repositories](Repositories.md)) in its first call and then gets it from the cache in subsequent calls. +* Automatically invalidates the cached entity if the entity is updated or deleted. Thus, it will be retrieved from the database in the next call and will be re-cached. -## How Does the Distributed Entity Caching System Work? +## Caching Entity Objects -ABP's Entity Caching System does the following operations on behalf of you: - -* It gets the entity from the database (by using the [Repositories](Repositories.md)) in its first call and then gets it from the cache in subsequent calls. -* It automatically invalidates the cached entity if the entity is updated or deleted. Thus, it will be retrieved from the database in the next call and will be re-cached. - -## Installation - -[Volo.Abp.Caching](https://www.nuget.org/packages/Volo.Abp.Caching) is the main package for ABP's caching system and it's already installed in [the application startup template](Startup-Templates/Index.md). So, you don't need to install it manually. - -## Usage - -`IEntityCache` is a simple service provided by the ABP Framework for caching entities. It's designed as read-only and contains two methods: `FindAsync` and `GetAsync`. - -### Caching Entities - -**Example: `Product` entity** +`IEntityCache` is a simple service provided by the ABP Framework for caching entities. Assume that you have a `Product` entity as shown below: ```csharp -[CacheName("Products")] public class Product : AggregateRoot { public string Name { get; set; } @@ -34,28 +19,12 @@ public class Product : AggregateRoot } ``` -* This example uses the `CacheName` attribute for the `Product` class to set the cache name. By default, the cache class's **FullName** is used for the cache name. - -If you want to cache this entity, you should first configure the [dependency injection](Dependency-Injection.md) to register the `IEntityCache` service in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): +If you want to cache this entity, you should first configure the [dependency injection](Dependency-Injection.md) system to register the `IEntityCache` service in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): ```csharp context.Services.AddEntityCache(); ``` -Then configure the [object mapper](https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping) (for `Product` to `ProductDto` mapping): - -```csharp -public class MyProjectNameAutoMapperProfile : Profile -{ - public MyProjectNameAutoMapperProfile() - { - //other mappings... - - CreateMap(); - } -} -``` - Now you can inject the `IEntityCache` service wherever you need: ```csharp @@ -76,13 +45,15 @@ public class ProductAppService : ApplicationService, IProductAppService } ``` -* Here, we've directly cached the `Product` entity. In that case, the `Product` class must be serializable. Sometimes this might not be possible and you may want to use another class to store the cache data. For example, we may want to use the `ProductDto` class instead of the `Product` class for the cached object if the `Product` entity is not serializable. +> Note that we've used the `ObjectMapper` service to map from `Product` to `ProductDto`. You should configure that [object mapping](Object-To-Object-Mapping.md) to make that example service properly works. -### Caching the Cache Item Classes +That's all. The cache name (in the distributed cache server) will be full name (with namespace) of the `Product` class. You can use the `[CacheName]` attribute to change it. Please refer to the [caching document](Caching.md) for details. -The `IEntityCache` service can be used for caching other cache item classes if the entity is not serializable. +## Using a Cache Item Class -**Example: `ProductDto` class** +In the previous section, we've directly cached the `Product` entity. In that case, the `Product` class must be serializable to JSON (and deserializable from JSON). Sometimes that might not be possible or you may want to use another class to store the cache data. For example, we may want to use the `ProductDto` class instead of the `Product` class for the cached object if the `Product` entity. + +Assume that we've created a `ProductDto` class as shown below: ```csharp public class ProductDto : EntityDto @@ -94,27 +65,25 @@ public class ProductDto : EntityDto } ``` -Register the entity cache services to [dependency injection](Dependency-Injection.md) in the `ConfigureServices` method of your [module class](Module-Development-Basics.md): +Now, we can register the entity cache services to [dependency injection](Dependency-Injection.md) in the `ConfigureServices` method of your [module class](Module-Development-Basics.md) with three generic parameters, as shown below: ```csharp context.Services.AddEntityCache(); ``` -Configure the [object mapper](https://docs.abp.io/en/abp/latest/Object-To-Object-Mapping) (for `Product` to `ProductDto` mapping): +Since the entity cache system will perform the [object mapping](Object-To-Object-Mapping.md) (from `Product` to `ProductDto`), we should configure the object map. Here, an example configuration with [AutoMapper](https://automapper.org/): ```csharp -public class MyProjectNameAutoMapperProfile : Profile +public class MyMapperProfile : Profile { - public MyProjectNameAutoMapperProfile() + public MyMapperProfile() { - //other mappings... - CreateMap(); } } ``` -Then, you can inject the `IEntityCache` service wherever you want: +Now, you can inject the `IEntityCache` service wherever you want: ```csharp public class ProductAppService : ApplicationService, IProductAppService @@ -133,31 +102,9 @@ public class ProductAppService : ApplicationService, IProductAppService } ``` -## Configurations - -### Registering the Entity Cache Services - -You can use one of the `AddEntityCache` methods to register entity cache services to the [Dependency Injection](Dependency-Injection.md) system. - -```csharp -public override void ConfigureServices(ServiceConfigurationContext context) -{ - var configuration = context.Services.GetConfiguration(); - - //other configurations... - - //directly cache the entity object (Basket) - context.Services.AddEntityCache(); - - //cache the ProductDto class - context.Services.AddEntityCache(); -} -``` - -* You can register the entity cache by using the `context.Services.AddEntityCache()` method to directly cache the entity object. -* Or alternatively, you can use the `context.Services.AddEntityCache()` method to configure entities that are mapped to a cache item. +Notice that the `_productCache.GetAsync` method already returns a `ProductDto` object, so we could directly return it from out application service. -### Caching Options +## Configuration All of the `context.Services.AddEntityCache()` methods get an optional `DistributedCacheEntryOptions` parameter where you can easily configure the caching options: @@ -170,14 +117,15 @@ context.Services.AddEntityCache( ); ``` -> The default cache duration is **2 minutes** with the `AbsoluteExpirationRelativeToNow` configuration and by configuring the `DistributedCacheEntryOptions` you can change it easily. +> The default cache duration is **2 minutes** with the `AbsoluteExpirationRelativeToNow` configuration. -## Additonal Notes +## Additional Notes -* Entity classes should be serializable/deserializable to/from JSON to be cached (because it's serialized to JSON when saving in the [Distributed Cache](Caching.md)). If your entity class is not serializable, you can consider using a cache-item/DTO class instead, as mentioned in the *Usage* section above. -* Entity Caching System is designed as **read-only**. So, you shouldn't make changes to the same entity when you use the entity cache. Instead, you should always read it from the database to ensure transactional consistency. -* The Entity Caching System uses the cache class's **FullName** as the cache name by default. You can use the `CacheName` attribute on the cache item class to set the cache name. +* Entity classes should be serializable/deserializable to/from JSON to be cached (because it's serialized to JSON when saving in the [Distributed Cache](Caching.md)). If your entity class is not serializable, you can consider using a cache-item/DTO class instead, as explained before. +* Entity Caching System is designed as **read-only**. You should use the standard [repository](Repositories.md) methods to manipulate the entity if you need. If you need to manipulate (update) the entity, do not get it from the entity cache. Instead, read it from the repository, change it and update using the repository. ## See Also -* [Caching](Caching.md) +* [Distributed caching](Caching.md) +* [Entities](Entities.md) +* [Repositories](Repositories.md)