117 lines
4.3 KiB
C#
117 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using Unosquare.Swan.Abstractions;
|
|
|
|
namespace Unosquare.Swan.Components {
|
|
/// <summary>
|
|
/// Represents an object map.
|
|
/// </summary>
|
|
/// <typeparam name="TSource">The type of the source.</typeparam>
|
|
/// <typeparam name="TDestination">The type of the destination.</typeparam>
|
|
/// <seealso cref="Unosquare.Swan.Abstractions.IObjectMap" />
|
|
public class ObjectMap<TSource, TDestination> : IObjectMap {
|
|
internal ObjectMap(IEnumerable<PropertyInfo> intersect) {
|
|
this.SourceType = typeof(TSource);
|
|
this.DestinationType = typeof(TDestination);
|
|
this.Map = intersect.ToDictionary(
|
|
property => this.DestinationType.GetProperty(property.Name),
|
|
property => new List<PropertyInfo> { this.SourceType.GetProperty(property.Name) });
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public Dictionary<PropertyInfo, List<PropertyInfo>> Map {
|
|
get;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public Type SourceType {
|
|
get;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public Type DestinationType {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maps the property.
|
|
/// </summary>
|
|
/// <typeparam name="TDestinationProperty">The type of the destination property.</typeparam>
|
|
/// <typeparam name="TSourceProperty">The type of the source property.</typeparam>
|
|
/// <param name="destinationProperty">The destination property.</param>
|
|
/// <param name="sourceProperty">The source property.</param>
|
|
/// <returns>
|
|
/// An object map representation of type of the destination property
|
|
/// and type of the source property.
|
|
/// </returns>
|
|
public ObjectMap<TSource, TDestination> MapProperty
|
|
<TDestinationProperty, TSourceProperty>(
|
|
Expression<Func<TDestination, TDestinationProperty>> destinationProperty,
|
|
Expression<Func<TSource, TSourceProperty>> sourceProperty) {
|
|
PropertyInfo propertyDestinationInfo = (destinationProperty.Body as MemberExpression)?.Member as PropertyInfo;
|
|
|
|
if(propertyDestinationInfo == null) {
|
|
throw new ArgumentException("Invalid destination expression", nameof(destinationProperty));
|
|
}
|
|
|
|
List<PropertyInfo> sourceMembers = GetSourceMembers(sourceProperty);
|
|
|
|
if(sourceMembers.Any() == false) {
|
|
throw new ArgumentException("Invalid source expression", nameof(sourceProperty));
|
|
}
|
|
|
|
// reverse order
|
|
sourceMembers.Reverse();
|
|
this.Map[propertyDestinationInfo] = sourceMembers;
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes the map property.
|
|
/// </summary>
|
|
/// <typeparam name="TDestinationProperty">The type of the destination property.</typeparam>
|
|
/// <param name="destinationProperty">The destination property.</param>
|
|
/// <returns>
|
|
/// An object map representation of type of the destination property
|
|
/// and type of the source property.
|
|
/// </returns>
|
|
/// <exception cref="System.Exception">Invalid destination expression.</exception>
|
|
public ObjectMap<TSource, TDestination> RemoveMapProperty<TDestinationProperty>(
|
|
Expression<Func<TDestination, TDestinationProperty>> destinationProperty) {
|
|
PropertyInfo propertyDestinationInfo = (destinationProperty.Body as MemberExpression)?.Member as PropertyInfo;
|
|
|
|
if(propertyDestinationInfo == null) {
|
|
throw new ArgumentException("Invalid destination expression", nameof(destinationProperty));
|
|
}
|
|
|
|
if(this.Map.ContainsKey(propertyDestinationInfo)) {
|
|
_ = this.Map.Remove(propertyDestinationInfo);
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
private static List<PropertyInfo> GetSourceMembers<TSourceProperty>(Expression<Func<TSource, TSourceProperty>> sourceProperty) {
|
|
List<PropertyInfo> sourceMembers = new List<PropertyInfo>();
|
|
MemberExpression initialExpression = sourceProperty.Body as MemberExpression;
|
|
|
|
while(true) {
|
|
PropertyInfo propertySourceInfo = initialExpression?.Member as PropertyInfo;
|
|
|
|
if(propertySourceInfo == null) {
|
|
break;
|
|
}
|
|
|
|
sourceMembers.Add(propertySourceInfo);
|
|
initialExpression = initialExpression.Expression as MemberExpression;
|
|
}
|
|
|
|
return sourceMembers;
|
|
}
|
|
}
|
|
}
|