From dd47b1f87dd02fc71d80f1938b53aae911550449 Mon Sep 17 00:00:00 2001 From: EngincanV Date: Tue, 2 Sep 2025 12:05:36 +0300 Subject: [PATCH] Revise tutorials for mapperly migration --- docs/en/tutorials/book-store/part-01.md | 47 +++++++------- docs/en/tutorials/book-store/part-03.md | 46 ++++++-------- docs/en/tutorials/book-store/part-08.md | 14 +++-- docs/en/tutorials/book-store/part-09.md | 74 ++++++++++------------- docs/en/tutorials/book-store/part-10.md | 47 +++++++++++--- docs/en/tutorials/microservice/part-05.md | 17 +++--- docs/en/tutorials/microservice/part-06.md | 22 +++---- docs/en/tutorials/modular-crm/part-03.md | 22 +++---- docs/en/tutorials/modular-crm/part-05.md | 20 +++--- docs/en/tutorials/modular-crm/part-06.md | 20 +++--- 10 files changed, 166 insertions(+), 163 deletions(-) diff --git a/docs/en/tutorials/book-store/part-01.md b/docs/en/tutorials/book-store/part-01.md index 6b856d9687..4634a68c67 100644 --- a/docs/en/tutorials/book-store/part-01.md +++ b/docs/en/tutorials/book-store/part-01.md @@ -291,22 +291,17 @@ public class BookDto : AuditedEntityDto * The `BookDto` is used to transfer the book data to the presentation layer in order to show the book information on the UI. * The `BookDto` is derived from the `AuditedEntityDto` which has audit properties just like the `Book` entity defined above. -It will be needed to map the `Book` entities to the `BookDto` objects while returning books to the presentation layer. [AutoMapper](https://automapper.org) library can automate this conversion when you define the proper mapping. The startup template comes with AutoMapper pre-configured. So, you can just define the mapping in the `BookStoreApplicationAutoMapperProfile` class in the `Acme.BookStore.Application` project: +It will be needed to map the `Book` entities to the `BookDto` objects while returning books to the presentation layer. [Mapperly](https://mapperly.riok.app/) library can automate this conversion when you define the proper mapping. The startup template comes with Mapperly pre-configured. So, you can just define the mapping in the `BookStoreApplicationMappers` class in the `Acme.BookStore.Application` project: -````csharp -using Acme.BookStore.Books; -using AutoMapper; - -namespace Acme.BookStore; - -public class BookStoreApplicationAutoMapperProfile : Profile +```csharp +[Mapper] +public partial class BookToBookDtoMapper : MapperBase { - public BookStoreApplicationAutoMapperProfile() - { - CreateMap(); - } + public override partial BookDto Map(Book source); + + public override partial void Map(Book source, BookDto destination); } -```` +``` > See the [object to object mapping](../../framework/infrastructure/object-to-object-mapping.md) document for details. @@ -343,21 +338,23 @@ public class CreateUpdateBookDto As done to the `BookDto` above, we should define the mapping from the `CreateUpdateBookDto` object to the `Book` entity. The final class will be as shown below: -````csharp -using Acme.BookStore.Books; -using AutoMapper; +```csharp +[Mapper] +public partial class BookToBookDtoMapper : MapperBase +{ + public override partial BookDto Map(Book source); -namespace Acme.BookStore; + public override partial void Map(Book source, BookDto destination); +} -public class BookStoreApplicationAutoMapperProfile : Profile +[Mapper] +public partial class CreateUpdateBookDtoToBookMapper : MapperBase { - public BookStoreApplicationAutoMapperProfile() - { - CreateMap(); - CreateMap(); - } + public override partial Book Map(CreateUpdateBookDto source); + + public override partial void Map(CreateUpdateBookDto source, Book destination); } -```` +``` ### IBookAppService @@ -416,7 +413,7 @@ public class BookAppService : * `BookAppService` is derived from `CrudAppService<...>` which implements all the CRUD (create, read, update, delete) methods defined by the `ICrudAppService`. * `BookAppService` injects `IRepository` which is the default repository for the `Book` entity. ABP automatically creates default repositories for each aggregate root (or entity). See the [repository document](../../framework/architecture/domain-driven-design/repositories.md). -* `BookAppService` uses `IObjectMapper` service ([see](../../framework/infrastructure/object-to-object-mapping.md)) to map the `Book` objects to the `BookDto` objects and `CreateUpdateBookDto` objects to the `Book` objects. The Startup template uses the [AutoMapper](http://automapper.org/) library as the object mapping provider. We have defined the mappings before, so it will work as expected. +* `BookAppService` uses `IObjectMapper` service ([see](../../framework/infrastructure/object-to-object-mapping.md)) to map the `Book` objects to the `BookDto` objects and `CreateUpdateBookDto` objects to the `Book` objects. The Startup template uses the [Mapperly](https://mapperly.riok.app/) library as the object mapping provider. We have defined the mappings before, so it will work as expected. ## Auto API Controllers diff --git a/docs/en/tutorials/book-store/part-03.md b/docs/en/tutorials/book-store/part-03.md index 45444ee76f..e67353b1fa 100644 --- a/docs/en/tutorials/book-store/part-03.md +++ b/docs/en/tutorials/book-store/part-03.md @@ -298,23 +298,17 @@ public class EditModalModel : BookStorePageModel ### Mapping from BookDto to CreateUpdateBookDto -To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebAutoMapperProfile.cs` file in the `Acme.BookStore.Web` project and change it as shown below: +To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebMappers.cs` file in the `Acme.BookStore.Web` project and change it as shown below: -````csharp -using AutoMapper; - -namespace Acme.BookStore.Web; - -public class BookStoreWebAutoMapperProfile : Profile +```csharp +[Mapper] +public partial class BookDtoToCreateUpdateBookDtoMapper : MapperBase { - public BookStoreWebAutoMapperProfile() - { - CreateMap(); - } -} -```` + public override partial CreateUpdateBookDto Map(BookDto source); -* We have just added `CreateMap();` to define this mapping. + public override partial void Map(BookDto source, CreateUpdateBookDto destination); +} +``` > Notice that we do the mapping definition in the web layer as a best practice since it is only needed in this layer. @@ -1288,28 +1282,26 @@ We can now define a modal to edit the book. Add the following code to the end of ```` -### AutoMapper Configuration +### Mapperly Configuration The base `AbpCrudPageBase` uses the [object to object mapping](../../framework/infrastructure/object-to-object-mapping.md) system to convert an incoming `BookDto` object to a `CreateUpdateBookDto` object. So, we need to define the mapping. -Open the `BookStoreBlazorAutoMapperProfile` inside the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor` {{ else if UI == "MAUIBlazor" }}`Acme.BookStore.MauiBlazor` {{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and change the content as the following: +Open the `BookStoreBlazorMappers` inside the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor` {{ else if UI == "MAUIBlazor" }}`Acme.BookStore.MauiBlazor` {{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and change the content as the following: -````csharp -using Acme.BookStore.Books; -using AutoMapper; +```csharp +using Riok.Mapperly.Abstractions; +using Volo.Abp.Mapperly; {{ if UI == "BlazorServer" }}namespace Acme.BookStore.Blazor; {{ else if UI == "MAUIBlazor" }}namespace Acme.BookStore.MauiBlazor; {{ else }}namespace Acme.BookStore.Blazor.Client;{{ end }} -public class BookStoreBlazorAutoMapperProfile : Profile +[Mapper] +public partial class BookDtoToCreateUpdateBookDtoMapper : MapperBase { - public BookStoreBlazorAutoMapperProfile() - { - CreateMap(); - } -} -```` + public override partial CreateUpdateBookDto Map(BookDto source); -* We've just added the `CreateMap();` line to define the mapping. + public override partial void Map(BookDto source, CreateUpdateBookDto destination); +} +``` ### Test the Editing Modal diff --git a/docs/en/tutorials/book-store/part-08.md b/docs/en/tutorials/book-store/part-08.md index a7d73f0209..ac49c6aee4 100644 --- a/docs/en/tutorials/book-store/part-08.md +++ b/docs/en/tutorials/book-store/part-08.md @@ -193,7 +193,7 @@ public async Task GetAsync(Guid id) } ```` -This method simply gets the `Author` entity by its `Id`, converts to the `AuthorDto` using the [object to object mapper](../../framework/infrastructure/object-to-object-mapping.md). This requires to configure the AutoMapper, which will be explained later. +This method simply gets the `Author` entity by its `Id`, converts to the `AuthorDto` using the [object to object mapper](../../framework/infrastructure/object-to-object-mapping.md). This requires to configure the Mapperly, which will be explained later. ### GetListAsync @@ -350,12 +350,18 @@ Finally, add the following entries to the `Localization/BookStore/en.json` insid ## Object to Object Mapping -`AuthorAppService` is using the `ObjectMapper` to convert the `Author` objects to `AuthorDto` objects. So, we need to define this mapping in the AutoMapper configuration. +`AuthorAppService` is using the `ObjectMapper` to convert the `Author` objects to `AuthorDto` objects. So, we need to define this mapping in the Mapperly configuration. -Open the `BookStoreApplicationAutoMapperProfile` class inside the `Acme.BookStore.Application` project and add the following line to the constructor: +Open the `BookStoreApplicationMappers` class inside the `Acme.BookStore.Application` project and define the following mapping class: ````csharp -CreateMap(); +[Mapper] +public partial class AuthorToAuthorDtoMapper : MapperBase +{ + public override partial AuthorDto Map(Author source); + + public override partial void Map(Author source, AuthorDto destination); +} ```` ## Data Seeder diff --git a/docs/en/tutorials/book-store/part-09.md b/docs/en/tutorials/book-store/part-09.md index 06db5f37d9..18ecd2726d 100644 --- a/docs/en/tutorials/book-store/part-09.md +++ b/docs/en/tutorials/book-store/part-09.md @@ -335,27 +335,16 @@ The main reason of this decision was to show you how to use a different model cl * Added `[DataType(DataType.Date)]` attribute to the `BirthDate` which shows a date picker on the UI for this property. * Added `[TextArea]` attribute to the `ShortBio` which shows a multi-line text area instead of a standard textbox. -In this way, you can specialize the view model class based on your UI requirements without touching to the DTO. As a result of this decision, we have used `ObjectMapper` to map `CreateAuthorViewModel` to `CreateAuthorDto`. To be able to do that, you need to add a new mapping code to the `BookStoreWebAutoMapperProfile` constructor: +In this way, you can specialize the view model class based on your UI requirements without touching to the DTO. As a result of this decision, we have used `ObjectMapper` to map `CreateAuthorViewModel` to `CreateAuthorDto`. To be able to do that, you need to define a new mapping configuration in the `BookStoreWebMappers` class: -````csharp -using Acme.BookStore.Authors; // ADDED NAMESPACE IMPORT -using Acme.BookStore.Books; -using AutoMapper; - -namespace Acme.BookStore.Web; - -public class BookStoreWebAutoMapperProfile : Profile +```csharp +[Mapper] +public partial class CreateAuthorViewModelToCreateAuthorDtoMapper : MapperBase { - public BookStoreWebAutoMapperProfile() - { - CreateMap(); - - // ADD a NEW MAPPING - CreateMap(); - } + public override partial CreateAuthorDto Map(Pages.Authors.CreateModalModel.CreateAuthorViewModel source); + public override partial void Map(Pages.Authors.CreateModalModel.CreateAuthorViewModel source, CreateAuthorDto destination); } -```` +``` "New author" button will work as expected and open a new model when you run the application again: @@ -456,29 +445,22 @@ This class is similar to the `CreateModal.cshtml.cs` while there are some main d * Uses the `IAuthorAppService.GetAsync(...)` method to get the editing author from the application layer. * `EditAuthorViewModel` has an additional `Id` property which is marked with the `[HiddenInput]` attribute that creates a hidden input for this property. -This class requires to add two object mapping declarations to the `BookStoreWebAutoMapperProfile` class: +This class requires to add two object mapping declarations, so open the `BookStoreWebMappers` class and add the following mappings: ```csharp -using Acme.BookStore.Authors; -using Acme.BookStore.Books; -using AutoMapper; - -namespace Acme.BookStore.Web; - -public class BookStoreWebAutoMapperProfile : Profile +[Mapper] +public partial class AuthorDtoToEditAuthorViewModelMapper : MapperBase { - public BookStoreWebAutoMapperProfile() - { - CreateMap(); + public override partial EditAuthorViewModel Map(AuthorDto source); - CreateMap(); + public override partial void Map(AuthorDto source, EditAuthorViewModel destination); +} - // ADD THESE NEW MAPPINGS - CreateMap(); - CreateMap(); - } +[Mapper] +public partial class EditAuthorViewModelToUpdateAuthorDtoMapper : MapperBase +{ + public override partial UpdateAuthorDto Map(Pages.Authors.EditModalModel.EditAuthorViewModel source); + public override partial void Map(Pages.Authors.EditModalModel.EditAuthorViewModel source, UpdateAuthorDto destination); } ``` @@ -1220,13 +1202,23 @@ This class typically defines the properties and methods used by the `Authors.raz `Authors` class uses the `IObjectMapper` in the `OpenEditAuthorModal` method. So, we need to define this mapping. -Open the `BookStoreBlazorAutoMapperProfile.cs` in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else if UI == "MAUIBlazor" }}`Acme.BookStore.MauiBlazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following mapping code in the constructor: +Open the `BookStoreBlazorMappers.cs` in the {{ if UI == "BlazorServer" }}`Acme.BookStore.Blazor`{{ else if UI == "MAUIBlazor" }}`Acme.BookStore.MauiBlazor`{{ else }}`Acme.BookStore.Blazor.Client`{{ end }} project and add the following mappings in the class: -````csharp -CreateMap(); -```` +```csharp +using Riok.Mapperly.Abstractions; +using Volo.Abp.Mapperly; +using Acme.BookStore.Authors; + +//... + +[Mapper] +public partial class AuthorDtoToUpdateAuthorDtoMapper : MapperBase +{ + public override partial UpdateAuthorDto Map(AuthorDto source); -You will need to declare a `using Acme.BookStore.Authors;` statement to the beginning of the file. + public override partial void Map(AuthorDto source, UpdateAuthorDto destination); +} +``` ### Add to the Main Menu diff --git a/docs/en/tutorials/book-store/part-10.md b/docs/en/tutorials/book-store/part-10.md index d4137e3681..02d1f81aba 100644 --- a/docs/en/tutorials/book-store/part-10.md +++ b/docs/en/tutorials/book-store/part-10.md @@ -578,11 +578,17 @@ Let's see the changes we've done: ### Object to Object Mapping Configuration -Introduced the `AuthorLookupDto` class and used object mapping inside the `GetAuthorLookupAsync` method. So, we need to add a new mapping definition inside the `BookStoreApplicationAutoMapperProfile.cs` file of the `Acme.BookStore.Application` project: +Introduced the `AuthorLookupDto` class and used object mapping inside the `GetAuthorLookupAsync` method. So, we need to add a new mapping definition inside the `BookStoreApplicationMappers.cs` file of the `Acme.BookStore.Application` project: -````csharp -CreateMap(); -```` +```csharp +[Mapper] +public partial class AuthorToAuthorLookupDtoMapper : MapperBase +{ + public override partial AuthorLookupDto Map(Author source); + + public override partial void Map(Author source, AuthorLookupDto destination); +} +``` ## Unit Tests @@ -898,12 +904,37 @@ These changes require a small change in the `EditModal.cshtml`. Remove the `(); -CreateMap(); -CreateMap(); +using Riok.Mapperly.Abstractions; +using Volo.Abp.Mapperly; + +//... + +[Mapper] +public partial class CreateBookViewModelToCreateUpdateBookDtoMapper : MapperBase +{ + public override partial CreateUpdateBookDto Map(Pages.Books.CreateModalModel.CreateBookViewModel source); + + public override partial void Map(Pages.Books.CreateModalModel.CreateBookViewModel source, CreateUpdateBookDto destination); +} + +[Mapper] +public partial class BookDtoToEditBookViewModelMapper : MapperBase +{ + public override partial Pages.Books.EditModalModel.EditBookViewModel Map(BookDto source); + + public override partial void Map(BookDto source, Pages.Books.EditModalModel.EditBookViewModel destination); +} + +[Mapper] +public partial class EditBookViewModelToCreateUpdateBookDtoMapper : MapperBase +{ + public override partial CreateUpdateBookDto Map(Pages.Books.EditModalModel.EditBookViewModel source); + + public override partial void Map(Pages.Books.EditModalModel.EditBookViewModel source, CreateUpdateBookDto destination); +} ``` You can run the application and try to create a new book or update an existing book. You will see a drop down list on the create/update form to select the author of the book: diff --git a/docs/en/tutorials/microservice/part-05.md b/docs/en/tutorials/microservice/part-05.md index 9c037617a1..e72e94fc66 100644 --- a/docs/en/tutorials/microservice/part-05.md +++ b/docs/en/tutorials/microservice/part-05.md @@ -255,21 +255,20 @@ public class OrderAppService : ApplicationService, IOrderAppService In this code snippet, we inject the `IRepository` into the `OrderAppService` class. We use this repository to interact with the `Order` entity. The `GetListAsync` method retrieves a list of orders from the database and maps them to the `OrderDto` class. The `CreateAsync` method creates a new order entity and inserts it into the database. -Afterward, we need to configure the *AutoMapper* object to map the `Order` entity to the `OrderDto` class. Open the `OrderingServiceApplicationAutoMapperProfile` class in the `CloudCrm.OrderingService` project, located in the `ObjectMapping` folder, and add the following code: +Afterward, we need to configure the *Mapperly* object to map the `Order` entity to the `OrderDto` class. Open the `OrderingServiceApplicationMappers` class in the `CloudCrm.OrderingService` project, located in the `ObjectMapping` folder, and add the following code: ```csharp -using AutoMapper; -using CloudCrm.OrderingService.Entities; -using CloudCrm.OrderingService.Services; +using Riok.Mapperly.Abstractions; +using Volo.Abp.Mapperly; namespace CloudCrm.OrderingService.ObjectMapping; -public class OrderingServiceApplicationAutoMapperProfile : Profile +[Mapper] +public partial class OrderingServiceApplicationMappers : MapperBase { - public OrderingServiceApplicationAutoMapperProfile() - { - CreateMap(); - } + public override partial OrderDto Map(Order source); + + public override partial void Map(Order source, OrderDto destination); } ``` diff --git a/docs/en/tutorials/microservice/part-06.md b/docs/en/tutorials/microservice/part-06.md index e5a8f53fe5..f268ba6fff 100644 --- a/docs/en/tutorials/microservice/part-06.md +++ b/docs/en/tutorials/microservice/part-06.md @@ -216,25 +216,25 @@ public class OrderDto } ``` -Lastly, open the `OrderingServiceApplicationAutoMapperProfile` class (the `OrderingServiceApplicationAutoMapperProfile.cs` file under the `ObjectMapping` folder of the `CloudCrm.OrderingService` project of the `CloudCrm.OrderingService` .NET solution) and ignore the `ProductName` property in the mapping configuration: +Lastly, open the `OrderingServiceApplicationMappers` class (the `OrderingServiceApplicationMappers.cs` file under the `ObjectMapping` folder of the `CloudCrm.OrderingService` project of the `CloudCrm.OrderingService` .NET solution) and ignore the `ProductName` property in the mapping configuration: ```csharp -using AutoMapper; -using CloudCrm.OrderingService.Entities; -using CloudCrm.OrderingService.Services; -using Volo.Abp.AutoMapper; +using Riok.Mapperly.Abstractions; +using Volo.Abp.Mapperly; namespace CloudCrm.OrderingService.ObjectMapping; -public class OrderingServiceApplicationAutoMapperProfile : Profile +[Mapper] +public partial class OrderingServiceApplicationMappers : MapperBase { - public OrderingServiceApplicationAutoMapperProfile() - { - CreateMap() - .Ignore(x => x.ProductName); // New line - } + [MapperIgnoreTarget(nameof(OrderDto.ProductName))] + public override partial OrderDto Map(Order source); + + [MapperIgnoreTarget(nameof(OrderDto.ProductName))] + public override partial void Map(Order source, OrderDto destination); } ``` + Let's explain the changes we made: - We added a new property named `ProductName` to the `OrderDto` class. This property will hold the product name. diff --git a/docs/en/tutorials/modular-crm/part-03.md b/docs/en/tutorials/modular-crm/part-03.md index fb19277895..bbb0339b50 100644 --- a/docs/en/tutorials/modular-crm/part-03.md +++ b/docs/en/tutorials/modular-crm/part-03.md @@ -323,23 +323,17 @@ Notice that `ProductAppService` class implements the `IProductAppService` and al #### Object Mapping -`ProductAppService.GetListAsync` method uses the `ObjectMapper` service to convert `Product` entities to `ProductDto` objects. The mapping should be configured. Open the `CatalogAutoMapperProfile` class in the `ModularCrm.Catalog` project and change it to the following code block: +`ProductAppService.GetListAsync` method uses the `ObjectMapper` service to convert `Product` entities to `ProductDto` objects. The mapping should be configured. So, create a new mapping class in the `ModularCrm.Catalog` project that implements the `MapperBase` class with the `[Mapper]` attribute as follows: -````csharp -using AutoMapper; - -namespace ModularCrm.Catalog; - -public class CatalogAutoMapperProfile : Profile +```csharp +[Mapper] +public partial class ProductToProductDtoMapper : MapperBase { - public CatalogAutoMapperProfile() - { - CreateMap(); - } -} -```` + public override partial ProductDto Map(Product source); -We've added the `CreateMap();` line to define the mapping. + public override partial void Map(Product source, ProductDto destination); +} +``` ### Exposing Application Services as HTTP API Controllers diff --git a/docs/en/tutorials/modular-crm/part-05.md b/docs/en/tutorials/modular-crm/part-05.md index d2082667aa..46a693a963 100644 --- a/docs/en/tutorials/modular-crm/part-05.md +++ b/docs/en/tutorials/modular-crm/part-05.md @@ -283,21 +283,17 @@ The new files under the `ModularCrm.Ordering.Contracts` project should be like t ### Implementing the Application Service -First we configure the *AutoMapper* to map the `Order` entity to the `OrderDto` object, because we will need it later. Open the `OrderingAutoMapperProfile` under the `ModularCrm.Ordering` project: +First, create a new mapping class (under the `ModularCrm.Ordering` project) that implements the `MapperBase` class with the `[Mapper]` attribute to map `Order` entities to `OrderDto` objects as follows, because we will need it later: -````csharp -using AutoMapper; - -namespace ModularCrm.Ordering; - -public class OrderingAutoMapperProfile : Profile +```csharp +[Mapper] +public partial class OrderToOrderDtoMapper : MapperBase { - public OrderingAutoMapperProfile() - { - CreateMap(); - } + public override partial OrderDto Map(Order source); + + public override partial void Map(Order source, OrderDto destination); } -```` +``` Now, you can implement the `IOrderAppService` interface. Create an `OrderAppService` class under the `ModularCrm.Ordering` project: diff --git a/docs/en/tutorials/modular-crm/part-06.md b/docs/en/tutorials/modular-crm/part-06.md index b685d72960..1c04cd56d1 100644 --- a/docs/en/tutorials/modular-crm/part-06.md +++ b/docs/en/tutorials/modular-crm/part-06.md @@ -217,21 +217,17 @@ public class OrderDto } ```` -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: +Lastly, open the `OrderingApplicationMappers` class (the `OrderingApplicationMappers.cs` file under the `Services` folder of the `ModularCrm.Ordering` project of the `ModularCrm.Ordering` .NET solution) and add the following mapping class: ````csharp -using AutoMapper; -using Volo.Abp.AutoMapper; - -namespace ModularCrm.Ordering; - -public class OrderingApplicationAutoMapperProfile : Profile +[Mapper] +public partial class OrderToOrderDtoMapper : MapperBase { - public OrderingApplicationAutoMapperProfile() - { - CreateMap() - .Ignore(x => x.ProductName); // New line - } + [MapperIgnoreTarget(nameof(OrderDto.ProductName))] + public override partial OrderDto Map(Order source); + + [MapperIgnoreTarget(nameof(OrderDto.ProductName))] + public override partial void Map(Order source, OrderDto destination); } ````