From 810a2528c10acc09ae77b46e98f4cf3737d72ba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 23 Sep 2020 12:39:34 +0300 Subject: [PATCH] Added Disable the Multi-Tenancy Filter section. --- docs/en/Data-Filtering.md | 53 +++++++++++++++++++++++++++++++++++++-- docs/en/Multi-Tenancy.md | 53 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 3 deletions(-) diff --git a/docs/en/Data-Filtering.md b/docs/en/Data-Filtering.md index 62021452bd..626719b2fc 100644 --- a/docs/en/Data-Filtering.md +++ b/docs/en/Data-Filtering.md @@ -102,9 +102,58 @@ namespace Acme.BookStore ```` * [Inject](Dependency-Injection.md) the `IDataFilter` service to your class. -* Use the `Disable` method within a `using` statement to create a code block where the `ISoftDelete` filter is disabled inside it (Always use it inside a `using` block to guarantee that the filter is reset to its previous state). +* Use the `Disable` method within a `using` statement to create a code block where the `ISoftDelete` filter is disabled inside it. -`IDataFilter.Enable` method can be used to enable a filter. `Enable` and `Disable` methods can be used in a nested way to define inner scopes. +In addition to the `Disable()` method; + +* `IDataFilter.Enable()` method can be used to enable a filter. `Enable` and `Disable` methods can be used in a **nested** way to define inner scopes. + +* `IDataFilter.IsEnabled()` can be used to check whether a filter is currently enabled or not. + +> Always use the `Disable` and `Enable` methods it inside a `using` block to guarantee that the filter is reset to its previous state. + +### The Generic IDataFilter Service + +`IDataFilter` service has a generic version, `IDataFilter` that injects a more restricted and explicit data filter based on the filter type. + +````csharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; + +namespace Acme.BookStore +{ + public class MyBookService : ITransientDependency + { + private readonly IDataFilter _softDeleteFilter; + private readonly IRepository _bookRepository; + + public MyBookService( + IDataFilter softDeleteFilter, + IRepository bookRepository) + { + _softDeleteFilter = softDeleteFilter; + _bookRepository = bookRepository; + } + + public async Task> GetAllBooksIncludingDeletedAsync() + { + //Temporary disable the ISoftDelete filter + using (_softDeleteFilter.Disable()) + { + return await _bookRepository.GetListAsync(); + } + } + } +} +```` + +* This usage determines the filter type while injecting the `IDataFilter` service. +* In this case you can use the `Disable()` and `Enable()` methods without specifying the filter type. ## AbpDataFilterOptions diff --git a/docs/en/Multi-Tenancy.md b/docs/en/Multi-Tenancy.md index 8606e6e1e3..ee85177651 100644 --- a/docs/en/Multi-Tenancy.md +++ b/docs/en/Multi-Tenancy.md @@ -177,6 +177,51 @@ namespace MultiTenancyDemo.Products > Always use the `Change` method with a `using` statement like done in this example. +## Data Filtering: Disable the Multi-Tenancy Filter + +As mentioned before, ABP Framework handles data isolation between tenants using the [Data Filtering](Data-Filtering.md) system. In some cases, you may want to disable it and perform a query on all the data, without filtering for the current tenant. + +**Example: Get count of products in the database, including all the products of all the tenants.** + +````csharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Data; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Domain.Services; +using Volo.Abp.MultiTenancy; + +namespace MultiTenancyDemo.Products +{ + public class ProductManager : DomainService + { + private readonly IRepository _productRepository; + private readonly IDataFilter _dataFilter; + + public ProductManager( + IRepository productRepository, + IDataFilter dataFilter) + { + _productRepository = productRepository; + _dataFilter = dataFilter; + } + + public async Task GetProductCountAsync() + { + using (_dataFilter.Disable()) + { + return await _productRepository.GetCountAsync(); + } + } + } +} + +```` + +See the [Data Filtering document](Data-Filtering.md) for more. + +> Note that this approach won't work if your tenants have **separate databases** since there is no built-in way to query from multiple database in a single database query. You should handle it yourself if you need it. + ## Determining the Current Tenant The first thing for a multi-tenant application is to determine the current tenant on the runtime. @@ -273,7 +318,7 @@ Multi-Tenancy middleware is an ASP.NET Core request pipeline [middleware](https: Multi-Tenancy middleware is typically placed just under the [authentication](https://docs.microsoft.com/en-us/aspnet/core/security/authentication) middleware (`app.UseAuthentication()`): -````C# +````csharp app.UseMultiTenancy(); ```` @@ -311,6 +356,12 @@ The [tenant management module](Modules/Tenant-Management) is **included in the s > It is recommended to **use the Tenant Management module**, which is already pre-configured when you create a new application with the ABP startup templates. +## Other Multi-Tenancy Infrastructure + +ABP Framework was designed to respect to the multi-tenancy in every aspect and most of the times everything will work as expected. + +BLOB Storing, Caching, Data Filtering, Data Seeding, Authorization and all the other services are designed to properly work in a multi-tenant system. + ## See Also * [Features](Features.md) \ No newline at end of file