Skip to content

Commit c24a0e3

Browse files
committed
Keep checking the authorization policies while projecting
* The projection only replaces the DTO creation, the filters and the policies still apply
1 parent 7ac1bc6 commit c24a0e3

3 files changed

Lines changed: 47 additions & 1 deletion

File tree

docs/en/framework/architecture/domain-driven-design/application-services.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,14 @@ and the provider has to be able to translate the join. The one row per entity ru
521521
that's why the example uses a left join. A joined column can not be used for the sorting and the paging,
522522
since they are already applied to the entity query before this method is called.
523523

524-
> The projection replaces the entity based extension points. `GetAsync` doesn't use `GetEntityByIdAsync` and `MapToGetOutputDtoAsync`, `GetListAsync` doesn't use `MapToGetListOutputDtosAsync` anymore. Projectors are resolved by the `(entity, DTO)` type pair, so registering one enables the projection for every application service using that pair. If an application service needs to keep using the entity based extension points, override the `GetOutputDtoQueryProjector` or `GetListOutputDtoQueryProjector` property and return `null`:
524+
A projector is resolved by the `(entity, DTO)` type pair, just like an `IObjectMapper<TSource, TDestination>`, so registering one enables the projection for every application service using that pair. The projection only replaces the way the DTOs are created:
525+
526+
* `GetAsync` doesn't use `GetEntityByIdAsync` and `MapToGetOutputDtoAsync` anymore.
527+
* `GetListAsync` doesn't use `MapToGetListOutputDtosAsync` anymore.
528+
529+
Everything else is untouched. The authorization policies are still checked, `CreateFilteredQueryAsync`, `ApplySorting` and `ApplyPaging` are still used, the data filters (like soft delete and multi-tenancy) are still applied, and the create, update and delete methods still use the [IObjectMapper](../../infrastructure/object-to-object-mapping.md).
530+
531+
> If an application service needs to keep using the entity based extension points, override the `GetOutputDtoQueryProjector` or `GetListOutputDtoQueryProjector` property and return `null`:
525532
526533
````csharp
527534
public class BookAppService : CrudAppService<Book, BookDto, Guid>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Volo.Abp.Domain.Repositories;
4+
5+
namespace Volo.Abp.Application.Services.QueryProjection;
6+
7+
public class BookPolicyCheckedException : Exception
8+
{
9+
10+
}
11+
12+
public class BookPolicyCheckedAppService : CrudAppService<Book, BookDto, Guid>
13+
{
14+
public BookPolicyCheckedAppService(IRepository<Book, Guid> repository)
15+
: base(repository)
16+
{
17+
18+
}
19+
20+
protected override Task CheckGetPolicyAsync()
21+
{
22+
throw new BookPolicyCheckedException();
23+
}
24+
25+
protected override Task CheckGetListPolicyAsync()
26+
{
27+
throw new BookPolicyCheckedException();
28+
}
29+
}

framework/test/Volo.Abp.Ddd.Application.Tests/Volo/Abp/Application/Services/QueryProjection/QueryProjection_Tests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,14 @@ public async Task Should_Project_A_Single_Entity_From_An_AbstractKey_Application
178178

179179
(await appService.GetAsync(_bookId)).Name.ShouldEndWith(BookProjector.Marker);
180180
}
181+
182+
[Fact]
183+
public async Task Should_Check_The_Policies_While_Projecting()
184+
{
185+
var appService = GetRequiredService<BookPolicyCheckedAppService>();
186+
187+
await Should.ThrowAsync<BookPolicyCheckedException>(async () => await appService.GetAsync(_bookId));
188+
await Should.ThrowAsync<BookPolicyCheckedException>(async () =>
189+
await appService.GetListAsync(new PagedAndSortedResultRequestDto()));
190+
}
181191
}

0 commit comments

Comments
 (0)