Skip to content

Commit

Permalink
docs: add sample (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
CommonGuy authored Jan 12, 2023
1 parent 282a3d3 commit 82c7844
Show file tree
Hide file tree
Showing 11 changed files with 257 additions and 4 deletions.
9 changes: 9 additions & 0 deletions Riok.Mapperly.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Riok.Mapperly.Tests", "test
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Riok.Mapperly.Abstractions.Tests", "test\Riok.Mapperly.Abstractions.Tests\Riok.Mapperly.Abstractions.Tests.csproj", "{C3C40A0A-168F-4A66-B9F9-FC80D2F26306}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{0FBD6C81-7E7A-4915-90D2-896F11C89FF0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Riok.Mapperly.Sample", "samples\Riok.Mapperly.Sample\Riok.Mapperly.Sample.csproj", "{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -46,12 +50,17 @@ Global
{C3C40A0A-168F-4A66-B9F9-FC80D2F26306}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3C40A0A-168F-4A66-B9F9-FC80D2F26306}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3C40A0A-168F-4A66-B9F9-FC80D2F26306}.Release|Any CPU.Build.0 = Release|Any CPU
{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{CB991FD7-B9B7-47C0-A060-66EBE136DBDA} = {B65AF89A-4A3B-473C-83C8-5F0CB0EED30E}
{FDA97A46-DB21-4B72-9958-6D61C508B1CD} = {3598BE50-28D5-4BF4-BEA7-09E5FEA2910C}
{E45D5E6D-8CC9-4DAD-8E1C-723625475744} = {B65AF89A-4A3B-473C-83C8-5F0CB0EED30E}
{284E2122-CE48-4A5A-A045-3A3F941DA5C3} = {3598BE50-28D5-4BF4-BEA7-09E5FEA2910C}
{C3C40A0A-168F-4A66-B9F9-FC80D2F26306} = {3598BE50-28D5-4BF4-BEA7-09E5FEA2910C}
{43A2E8E0-5A2C-45E9-84EF-CF934EC946FA} = {0FBD6C81-7E7A-4915-90D2-896F11C89FF0}
EndGlobalSection
EndGlobal
35 changes: 35 additions & 0 deletions docs/docs/01-getting-started/03-generated-mapper-example.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import CodeBlock from '@theme/CodeBlock';
import CarSource from '!!raw-loader!../../src/data/generated/samples/Car.cs';
import CarDtoSource from '!!raw-loader!../../src/data/generated/samples/CarDto.cs';
import CarMapperSource from '!!raw-loader!../../src/data/generated/samples/CarMapper.cs';
import GeneratedCarMapperSource from '!!raw-loader!../../src/data/generated/samples/CarMapper.g.cs';

# Generated mapper example

This example will show you what kind of code Mapperly generates.
It is based on the [Mapperly sample](https://github.com/riok/mapperly/tree/main/samples/Riok.Mapperly.Sample).
To view the generated code of your own mapper, refer to the [generated source configuration](../02-configuration/13-generated-source.mdx).

## The source classes
In this example, we have a car class with some general information.

<CodeBlock language="csharp">{CarSource}</CodeBlock>

## The target classes
Our sample target classes are mostly the same as the source classes.
For demonstration purposes, we named the manufacturer property differently to show how Mapperly can handle this use case.

<CodeBlock language="csharp">{CarDtoSource}</CodeBlock>

## The mapper

The actual mapper is pretty simple. We use a static mapper class in this example.
As usual, we need to mark the mapper with the `[Mapper]` attribute, so that the source generator is able to recognize it.
Because the manufacturer/producer properties are named differently, we also need to configure that via an attribute.
In addition, because the `CarColor` and `CarColorDto` entries have different numeric values, we need to configure Mapperly to map them by their name.

<CodeBlock language="csharp">{CarMapperSource}</CodeBlock>

## The generated code

<CodeBlock language="csharp">{GeneratedCarMapperSource}</CodeBlock>
4 changes: 2 additions & 2 deletions docs/docs/02-configuration/13-generated-source.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import TabItem from '@theme/TabItem';

# Generated source

If you want to inspect the source code generated by Mapperly and your IDE doesn't easily allow this
or if you want to check in the generated source into source control you can emit the generated files.
Most IDEs allow you to view the source code generated by Mapperly. Usually you can jump to the implementation via the partial mapper method.
If your IDE doesn't easily allow this or if you want to check in the generated source into source control, you can emit the generated files.

To emit the generated files to disk set the `EmitCompilerGeneratedFiles` property:

Expand Down
58 changes: 58 additions & 0 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"clsx": "1.2.1",
"docusaurus-plugin-sass": "0.2.2",
"prism-react-renderer": "1.3.5",
"raw-loader": "4.0.2",
"react": "17.0.2",
"react-dom": "17.0.2"
},
Expand Down
25 changes: 23 additions & 2 deletions docs/prebuild.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const {exec} = require('child_process');
const {readFile, writeFile, mkdir, rmdir, readdir, rm} = require('fs').promises;
const {readFile, writeFile, copyFile, mkdir, rmdir, readdir, rm} = require('fs').promises;
const {join} = require('path');
const util = require('util');
const {marked} = require('marked');
Expand All @@ -9,7 +9,7 @@ const generatedDataDir = './src/data/generated';

async function clearGeneratedFiles() {
try {
await rmdir(generatedDataDir);
await rm(generatedDataDir, { recursive: true });
} catch {}

await mkdir(generatedDataDir, { recursive: true });
Expand Down Expand Up @@ -79,8 +79,29 @@ async function buildAnalyzerRulesData() {
await writeFile(targetFile, JSON.stringify(rules, undefined, ' '));
}

async function buildSamples() {
const targetDir = join(generatedDataDir, 'samples');
await mkdir(targetDir);

const sampleProject = '../samples/Riok.Mapperly.Sample';
const projectFilesToCopy = ['CarMapper.cs', 'Car.cs', 'CarDto.cs'];
const generatedMapperFile = join(sampleProject, 'obj/Debug/net7.0/generated/Riok.Mapperly/Riok.Mapperly.MapperGenerator/CarMapper.g.cs');

// clean target directory
await deleteFilesWithExtension(targetDir, '.cs');

// Copy generated mapper to target dir
await copyFile(generatedMapperFile, join(targetDir, 'CarMapper.g.cs'));

// Copy sample project files to target dir
for (const file of projectFilesToCopy) {
await copyFile(join(sampleProject, file), join(targetDir, file));
}
}

(async () => {
await clearGeneratedFiles();
await buildApiDocs();
await buildAnalyzerRulesData();
await buildSamples();
})();
39 changes: 39 additions & 0 deletions samples/Riok.Mapperly.Sample/Car.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Riok.Mapperly.Sample;

public class Car
{
public string Name { get; set; } = string.Empty;

public int NumberOfSeats { get; set; }

public CarColor Color { get; set; }

public Manufacturer? Manufacturer { get; set; }

public List<Tire> Tires { get; } = new List<Tire>();
}

public enum CarColor
{
Black = 1,
Blue = 2,
White = 3,
}

public class Manufacturer
{
public Manufacturer(int id, string name)
{
Id = id;
Name = name;
}

public int Id { get; }

public string Name { get; }
}

public class Tire
{
public string Description { get; set; } = string.Empty;
}
42 changes: 42 additions & 0 deletions samples/Riok.Mapperly.Sample/CarDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace Riok.Mapperly.Sample;

public class CarDto
{
public string Name { get; set; } = string.Empty;

public int NumberOfSeats { get; set; }

public CarColorDto Color { get; set; }

public ProducerDto? Producer { get; set; }

public List<TireDto>? Tires { get; set; }
}

// Intentionally use different numeric values for demonstration purposes
public enum CarColorDto
{
Yellow = 1,
Green = 2,
Black = 3,
Blue = 4,
}

// The manufacturer, but named differently for demonstration purposes
public class ProducerDto
{
public ProducerDto(int id, string name)
{
Id = id;
Name = name;
}

public int Id { get; }

public string Name { get; }
}

public class TireDto
{
public string Description { get; set; } = string.Empty;
}
11 changes: 11 additions & 0 deletions samples/Riok.Mapperly.Sample/CarMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Riok.Mapperly.Abstractions;

namespace Riok.Mapperly.Sample;

// Enums of source and target have different numeric values -> use ByName strategy to map them
[Mapper(EnumMappingStrategy = EnumMappingStrategy.ByName)]
public static partial class CarMapper
{
[MapProperty(nameof(Car.Manufacturer), nameof(CarDto.Producer))] // Map property with a different name in the target type
public static partial CarDto MapCarToDto(Car car);
}
22 changes: 22 additions & 0 deletions samples/Riok.Mapperly.Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Text.Json;
using Riok.Mapperly.Sample;

var car = new Car
{
Name = "my car",
NumberOfSeats = 5,
Color = CarColor.Blue,
Manufacturer = new Manufacturer(1, "best manufacturer"),
Tires =
{
new Tire { Description = "front left tire" },
new Tire { Description = "front right tire" },
new Tire { Description = "back left tire" },
new Tire { Description = "back right tire" },
},
};

var carDto = CarMapper.MapCarToDto(car);

Console.WriteLine("Mapped car to car DTO:");
Console.WriteLine(JsonSerializer.Serialize(carDto, new JsonSerializerOptions { WriteIndented = true }));
15 changes: 15 additions & 0 deletions samples/Riok.Mapperly.Sample/Riok.Mapperly.Sample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>

<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Riok.Mapperly\Riok.Mapperly.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
<ProjectReference Include="..\..\src\Riok.Mapperly.Abstractions\Riok.Mapperly.Abstractions.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="true" />
</ItemGroup>

</Project>

0 comments on commit 82c7844

Please sign in to comment.