When trying to map Foo
to TrackedFoo
, since they have the same property names, everything will be fine at first. The problem occurs when AutoMapper tries to convert the Name property ( string
) of your Foo
to the aa property Name ( TrackedProperty<string,DateTime>
) of your TrackedFoo
.
Since AutoMapper does not know how to convert natevely between string
and TrackedProperty<,>
, it will not work.
Although, you can teach AutoMapper how to convert between these types. To do this, you will need Custom Type Converter :
public class TrackedPropertyConverter<TValue, TVersion> : ITypeConverter<TrackedProperty<TValue, TVersion>, TValue> { public TValue Convert(TrackedProperty<TValue, TVersion> source, TValue destination, ResolutionContext context) { return source.First().Value; } }
Then you configure it like this:
Mapper.Initialize( cfg => { cfg.CreateMap<TrackedFoo, Foo>(); cfg.CreateMap<TrackedProperty<string, DateTime>, string>().ConvertUsing<TrackedPropertyConverter<string,DateTime>>(); cfg.CreateMap<TrackedProperty<int, DateTime>, int>().ConvertUsing<TrackedPropertyConverter<int, DateTime>>(); cfg.CreateMap<TrackedProperty<double, DateTime>, double>().ConvertUsing<TrackedPropertyConverter<double, DateTime>>(); } ); Mapper.AssertConfigurationIsValid();
And here is a usage example:
var tracked = new TrackedFoo { Id = "SomeGuid", Name = new TrackedProperty<string, DateTime> { new PropertyVersion<string, DateTime> { Value = "FooBar", Version = new DateTime(2017, 2, 28) } }, Value = new TrackedProperty<int, DateTime> { new PropertyVersion<int, DateTime> { Value = 456, Version = new DateTime(2017, 2, 28) } } }; var foo = Mapper.Map<Foo>(tracked); Console.WriteLine("Id: {0} | Name: {1} | Value: {2}", foo.Id, foo.Name, foo.Value); Console.ReadLine();
This is a common way for AutoMapper to learn how to convert between types, regardless of which objects with these types are converted (for example, Foo to TrackedFoo / Bar to TrackedBar / Person to TrackedPerson).
You must explicitly configure each type (string, int, double), as an example on your page, but you just do it once, you do not need to do this for all possible classes using tracked properties.
In addition, your repository is responsible for accepting the version value as a parameter (e.g. DateTime
) and getting TrackedProperty
with the only value you requested for this version, since you cannot have multiple values for the same version.