Autconverter is library for automatic mapping based on Roslyn Code Generators and Dependency Injection.
This package is under development and from that reason it is in pre-release stage. Public API of this package could be changed any time. The package can also contains some untested features and bugs.
- Provide compile time safe mapping (if mapping is incorrect, code won't compile)
- Create mappers with native code performance
The package is currently in pre-release stage, so use prerelease
flag or similar option in your nuget client.
dotnet add package Paukertj.Autoconverter.Generator --prerelease
Composition file is the place, that allows you
public static partial class DiCompositorAutomapping
{
public static IServiceCollection AddAutomapping(this IServiceCollection serviceCollection)
{
serviceCollection.AddAutoconverter(); // Register autoconverter service
serviceCollection.AddAutomappingInternal(); // Register generated services
return serviceCollection;
}
[AutoconverterWiringEntrypoint] // This attribute will notify Autoconverter
static partial void AddAutomappingInternal(this IServiceCollection serviceCollection);
}
Now you can register Autoconverter by your composition file in Dependency Injection container:
using IHost host = Host.CreateDefaultBuilder(args)
.ConfigureServices((_, services) =>
services
.AddAutomapping()) // This is the extension method from your composition file
.Build();
To start using Autconverter just inject IConvertingService
. This service provides Convert<TFrom, TTo>
method, that provides conversion for you. You don't have to create maps, only thing that you have to do is to define source and target type.
public class MyDependencyInjectedService : IMyDependencyInjectedService
{
private readonly IConvertingService _convertingService;
public MyDependencyInjectedService(IConvertingService convertingService)
{
_convertingService = convertingService;
}
public SomeObjectDto GetDto(SomeObject someObject)
{
// Here the conversion happens
return _convertingService.Convert<SomeObject, SomeObjectDto>(someObject);
}
}
public record SomeObjectDto
{
public Guid Id { get; init; }
public string Name { get; init; }
}
public record SomeObject
{
public Guid Id { get; init; }
public string Name { get; init; }
}
To use this API, your objects have to be mappable, that means that you have to be able map all properties from TFrom
or you have to be able to map all properties from TTo
. So for example:
public record From
{
public Guid Id { get; init; }
}
public record To
{
public Guid Id { get; init; }
public string Name { get; init; }
}
This you can automatically map, because you can fill all properties from From
record. This example:
public record From
{
public Guid Id { get; init; }
public string Name { get; init; }
}
public record To
{
public string Name { get; init; }
}
Will also work, because you can map all properties in To
record but situation like this:
public record From
{
public Guid FromId { get; init; }
}
public record To
{
public Guid ToId { get; init; }
}
Will throw AM0002
exception during compilation, because it is not possible to automatically decide, what exactly you want to map.
For situation, where you can not use automatic conversion, you can implement custom converter using IConverter<TFrom, TTo>
interface:
internal sealed class MyCustomConverter : IConverter<From, To>
{
public To Convert(From from)
{
return new To
{
ToId = from.FromId
};
}
}
public record From
{
public Guid FromId { get; init; }
}
public record To
{
public Guid ToId { get; init; }
}
You do not have to register this converter anywhere. Autoconverter analyze your project during compilation and will collect your custom converters. The converter definition works globaly, so Autoconverter will know that it is possible to use your converter in the case of all conversions. It is good to know, that each converter (including the generated converters) is dependency injected service. So you can use them independently if you wish:
public class MyDependencyInjectedService : IMyDependencyInjectedService
{
private readonly IConverter<From, To> _myCustomConverter;
public MyDependencyInjectedService(IConverter<From, To> myCustomConverter)
{
_myCustomConverter = myCustomConverter;
}
}
But you can also access them using IConvertingService which is recommended.
Dictionary
support ❌- Better support for
IList
and similar structures ❌ - Support for cross type conversion (from
int
tostring
etc.) ❌ - Support for nullable types ✔️
- Support for basic 1:1 conversion ✔️
- Better API for ignoring properties ❌
- API for trageting mapping (be able to map Property1 to Property2 without custom converter) ❌
- Support for nested types ✔️
- 100% test coverage ❌
- 100% documentation coverage ❌