diff --git a/README.md b/README.md
index dde6dc5..0f21dd8 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,11 @@
# MapTo
-![Nuget](https://img.shields.io/nuget/v/mapto?logo=nuget)
+[![Nuget](https://img.shields.io/nuget/v/mapto?logo=nuget)](https://www.nuget.org/packages/MapTo/)
![Publish Packages](https://github.com/mrtaikandi/MapTo/workflows/Publish%20Packages/badge.svg)
A convention based object to object mapper using [Roslyn source generator](https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.md).
-MapTo creates mappings during compile-time, which eliminates the need for using reflection to create the mappings. This makes it super simple to use and way faster than other libraries.
+MapTo is a library to programmatically generate the necessary code to map one object to another during compile-time. It creates mappings during compile-time, eliminating the need to use reflection to map one object to another and make it simpler to use faster than other libraries at runtime.
+
## Installation
```
@@ -12,7 +13,7 @@ dotnet add package MapTo --prerelease
```
## Usage
-To generate the mappings, simply declare the destination class as `partial` and annotate it with `MapFrom` attribute.
+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.
```c#
using MapTo;
@@ -32,71 +33,59 @@ namespace App.ViewModels
}
```
-## Generated Source
-In the above example, if `App.Data.Models.User` class is defined as:
-
-```c#
-namespace App.Data.Models
-{
- public class User
- {
- public User(int id) => Id = id;
-
- public int Id { get; }
-
- public string FirstName { get; set; }
-
- public string LastName { get; set; }
-
- public string FullName => $"{FirstName} {LastName}";
- }
-}
-```
-
-It will generate the following code:
-
-```c#
-//
-using System;
-
-namespace App.ViewModels
-{
- public partial class UserViewModel
- {
- public UserViewModel(App.Data.Models.User user)
- {
- if (user == null) throw new ArgumentNullException(nameof(user));
-
- FirstName = user.FirstName;
- LastName = user.LastName;
- }
-
- public static UserViewModel From(App.Data.Models.User user)
- {
- return user == null ? null : new UserViewModel(user);
- }
- }
-
- public static partial class UserToUserViewModelExtensions
- {
- public static UserViewModel ToUserViewModel(this App.Data.Models.User user)
- {
- return user == null ? null : new UserViewModel(user);
- }
- }
-}
-```
-
-Which makes it possible to get an instance of `UserViewModel` from one of the following ways:
+To get an instance of `UserViewModel` from the `User` class, you can use any of the following methods:
```c#
var user = new User(id: 10) { FirstName = "John", LastName = "Doe" };
-var vm = user.ToUserViewModel();
+var vm = user.ToUserViewModel(); // A generated extension method for User class.
// OR
-vm = new UserViewModel(user);
+vm = new UserViewModel(user); // A generated contructor.
// OR
-vm = UserViewModel.From(user);
+vm = UserViewModel.From(user); // A generated factory method.
+```
+
+> Please refer to [sample console app](https://github.com/mrtaikandi/MapTo/tree/master/test/TestConsoleApp) for a more complete example.
+
+## 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.
+```c#
+[IgnoreProperty]
+public string FullName { get; set; }
+```
+
+### 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.
+
+```c#
+[MapProperty(SourcePropertyName = "Id")]
+public int Key { get; set; }
+```
+
+### 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.
+
+This attribute will accept a type that implements `ITypeConverter` interface.
+
+```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; }
+
+ private class IdConverter : ITypeConverter
+ {
+ public string Convert(int source, object[] converterParameters) => $"{source:X}";
+ }
+}
```
\ No newline at end of file