Avoid reflections of mappers and let Mapster generate mappers for you


Problem

All we don’t want to write mappers boilerplated code, because it is boring. So smart developers use different mappers, such as AutoMapper, Mapster and so on. However, we suppose that these libraries have to use reflection to map our POCO to DTO and we know that reflection one of the most slowest thing. Fortunately, I have good news for you, because we can just generate mappers code, so we avoid reflection.

Onion

onion blazor On these to images you can see 2 situations:

  1. Usuall onion scheme shows that application layer can expose only DTOs, so we have IMapper abstraction on this layer and DTOs classes, which can also be generetated by Mapster (because apllcation layer knows about entites, so generator can base on them)
  2. If you use blazor, you can want to have shared DTOs library so all DTOs can be reused by frontend. In that case, such shared library does not know anyting about domain entities, so can’t be generated by mapster. However, we still can generate our IMappers

Let’s consider second variant.

Create project with layers

project

Get mapster

#skip this step if you already have dotnet-tools.json
dotnet new tool-manifest 

dotnet tool install Mapster.Tool

Add mapster to Application layer

PM> Install-Package Mapster

IMapper

All we need just use data attribute [Mapper] for our interface to tell mapster which mappers we want to generate

[Mapper]
public interface IEntityMapper
{
    //map from POCO to DTO
    EntityDto MapToDto(Entity entity);
}

Now, let’s add next lines to application.csproj

<Target Name="Mapster">
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet build" />
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool restore" />
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster model -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster extension -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
  <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet mapster mapper -a &quot;$(TargetDir)$(ProjectName).dll&quot;" />
</Target>

And last one, run dotnet msbuild -t:Mapster

Result

As a result, we can see generated mappers, which we can inject to our application

Conclusion

We can use mappers as the way we use to, but avoiding reflection cost. As always source code you can find on github

Buy Me A Coffee

Related Posts

Predict Bitcoin price with ML.net

Live time series coin price predictor with machine learning

Throw exceptions from backend to frontend with blazor

One of advantages of using same code language on both frontend and backend

How to avoid violating of SOLID principles while extending service behaviours

Step by step extending service behaviour with decorator pattern respecting SOLID

Blazor render optimization

Best practices

.Net 6 brings application state to blazor webassembly server prerender

It kills strange blinking on screen

Must have libraries for blazor

List of best nuget packages

Blazor virtualize component

Lazy loading of big lists. Rendering optimization.

Blazor grpc - comunication optimization

Smaller and faster requests to your backend from blazor wasm

Free database for your blazor app

Don't pay for the cloud

Blazor common error component

Single component for showing errors on any page and component