MapTo/README.md

91 lines
3.2 KiB
Markdown
Raw Permalink Normal View History

2020-12-21 19:34:53 +03:00
# MapTo
2021-02-21 11:18:42 +03:00
[![Nuget](https://img.shields.io/nuget/v/mapto?logo=nuget)](https://www.nuget.org/packages/MapTo/)
2020-12-24 15:42:28 +03:00
![Publish Packages](https://github.com/mrtaikandi/MapTo/workflows/Publish%20Packages/badge.svg)
2020-12-27 10:34:27 +03:00
A convention based object to object mapper using [Roslyn source generator](https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md).
2020-12-24 23:28:34 +03:00
2021-04-09 09:48:23 +03:00
MapTo is a library to programmatically generate the necessary code to map one object to another during compile-time, eliminating the need to use reflection to map objects and make it much faster in runtime. It provides compile-time safety checks and ease of use by leveraging extension methods.
2021-02-21 11:18:42 +03:00
2020-12-22 11:20:49 +03:00
## Installation
```
2020-12-24 15:42:28 +03:00
dotnet add package MapTo --prerelease
2020-12-22 11:20:49 +03:00
```
## Usage
2021-02-21 11:18:42 +03:00
MapTo relies on a set of attributes to instruct it on how to generate the mappings. To start, declare the destination class as `partial` and annotate it with `MapFrom` attribute. As its name implies, `MapFrom` attribute tells the library what the source class you want to map from is.
2020-12-22 11:20:49 +03:00
```c#
2020-12-24 23:28:34 +03:00
using MapTo;
2020-12-22 11:20:49 +03:00
2020-12-24 23:28:34 +03:00
namespace App.ViewModels
{
[MapFrom(typeof(App.Data.Models.User))]
public partial class UserViewModel
{
public string FirstName { get; }
2020-12-24 15:45:31 +03:00
2020-12-24 23:28:34 +03:00
public string LastName { get; }
[IgnoreProperty]
public string FullName { get; set; }
}
2020-12-22 11:20:49 +03:00
}
```
2021-02-21 11:18:42 +03:00
To get an instance of `UserViewModel` from the `User` class, you can use any of the following methods:
2020-12-22 11:20:49 +03:00
```c#
2021-02-21 11:18:42 +03:00
var user = new User(id: 10) { FirstName = "John", LastName = "Doe" };
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
var vm = user.ToUserViewModel(); // A generated extension method for User class.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
// OR
vm = new UserViewModel(user); // A generated contructor.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
// OR
vm = UserViewModel.From(user); // A generated factory method.
2020-12-22 11:20:49 +03:00
```
2021-02-21 11:18:42 +03:00
> Please refer to [sample console app](https://github.com/mrtaikandi/MapTo/tree/master/test/TestConsoleApp) for a more complete example.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
## Available Attributes
### IgnoreProperty
By default, MapTo will include all properties with the same name (case-sensitive), whether read-only or not, in the mapping unless annotating them with the `IgnoreProperty` attribute.
2020-12-22 11:20:49 +03:00
```c#
2021-02-21 11:18:42 +03:00
[IgnoreProperty]
public string FullName { get; set; }
```
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
### MapProperty
This attribute gives you more control over the way the annotated property should get mapped. For instance, if the annotated property should use a property in the source class with a different name.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
```c#
[MapProperty(SourcePropertyName = "Id")]
public int Key { get; set; }
2020-12-22 11:20:49 +03:00
```
2021-02-21 11:18:42 +03:00
### MapTypeConverter
A compilation error gets raised by default if the source and destination properties types are not implicitly convertible, but to convert the incompatible source type to the desired destination type, `MapTypeConverter` can be used.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
This attribute will accept a type that implements `ITypeConverter<in TSource, out TDestination>` interface.
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
```c#
[MapFrom(typeof(User))]
public partial class UserViewModel
{
public DateTimeOffset RegisteredAt { get; set; }
[IgnoreProperty]
public ProfileViewModel Profile { get; set; }
[MapTypeConverter(typeof(IdConverter))]
[MapProperty(SourcePropertyName = nameof(User.Id))]
public string Key { get; }
2020-12-22 11:20:49 +03:00
2021-02-21 11:18:42 +03:00
private class IdConverter : ITypeConverter<int, string>
{
public string Convert(int source, object[] converterParameters) => $"{source:X}";
}
}
2020-12-22 11:20:49 +03:00
```