Created
July 26, 2018 18:26
-
-
Save mouadcherkaoui/bef4fe22943b360ae92b0fb84425c8fb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace PresenterMapperDto.Attributes | |
{ | |
[System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] | |
public sealed class MapToEntityAttribute : Attribute | |
{ | |
readonly Type entityType; | |
public MapToEntityAttribute(Type entityType) | |
{ | |
this.entityType = entityType; | |
throw new NotImplementedException(); | |
} | |
public Type EntityType | |
{ | |
get { return entityType; } | |
} | |
} | |
[System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = true)] | |
public sealed class MapToPropertyAttribute : Attribute | |
{ | |
readonly string _propertyName; | |
public MapToPropertyAttribute(string propertyName) | |
{ | |
this._propertyName = propertyName; | |
} | |
public string PropertyName | |
{ | |
get { return _propertyName; } | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel.DataAnnotations; | |
using System.ComponentModel.DataAnnotations.Schema; | |
using System.Linq; | |
using System.Reflection; | |
using System.Runtime.CompilerServices; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace Extensions | |
{ | |
public class PresenterMapper<TModel>: IValidatableObject | |
where TModel : class, new() | |
{ | |
[JsonIgnore] | |
public Action PreAction { get; set; } | |
[JsonIgnore] | |
public Action PostAction { get; set; } | |
[JsonIgnore] | |
public Dictionary<string, Func<object, bool>> Validators { get; set; } | |
protected void SetProperty<T>(T value, [CallerMemberName]string propertyName = ""){ | |
this.SetPropertyValue(propertyName, value); | |
} | |
public void SetEntity(TModel source) | |
{ | |
var result = source | |
.PipeTo(SetPropertiesValues); | |
} | |
private bool SetPropertiesValues(TModel source) | |
{ | |
var entity = new TModel(); | |
var modelType = typeof(TModel); | |
var type = this.GetType(); | |
foreach (var property in type.GetProperties() | |
.Where(p => p.CustomAttributes | |
.Any(a => a.AttributeType == typeof(MapToPropertyAttribute) || a.AttributeType == typeof(ComposeFromAttribute)))) | |
{ | |
var hasComposeFromAttribute = property.GetCustomAttributes<ComposeFromAttribute>().Any(); | |
if (hasComposeFromAttribute) | |
{ | |
((ComposeFromAttribute)property.GetCustomAttribute(typeof(ComposeFromAttribute))) | |
.PipeTo(attr => | |
{ | |
var left = type.GetProperty(attr.left).GetValue(this); | |
var right = type.GetProperty(attr.right).GetValue(this); | |
var separator = attr.separator; | |
var value = $"{left}{separator}{right}"; | |
value.PipeTo(v => | |
{ | |
if (v == null) return false; | |
this.ChangeTypeSetPropertyValue(property.Name, v); | |
return true; | |
}); | |
return true; | |
}); | |
} | |
var hasMappingAttribute = property.GetCustomAttributes().Any(a => a.GetType() == typeof(MapToPropertyAttribute)); | |
if (hasMappingAttribute) | |
{ | |
((MapToPropertyAttribute)property.GetCustomAttribute(typeof(MapToPropertyAttribute)))?.PropertyName | |
.PipeTo(n => | |
{ | |
modelType.GetProperty(n).GetValue(source) | |
.PipeTo(v => | |
{ | |
if (v == null) return false; | |
this.ChangeTypeSetPropertyValue(property.Name, v); | |
return true; | |
}); | |
return true; | |
}); | |
} | |
} | |
return true; | |
} | |
public TModel GetEntity() | |
{ | |
return GetType() | |
.PipeTo(SetDestinationProperties); | |
} | |
private TModel SetDestinationProperties(Type t) | |
{ | |
var entity = new TModel(); | |
var type = typeof(TModel); | |
foreach (var property in t.GetProperties()) | |
{ | |
var hasMappingAttribute = property.GetCustomAttributes().Any(a => a.GetType() == typeof(MapToPropertyAttribute)); | |
if (hasMappingAttribute) | |
{ | |
((MapToPropertyAttribute)property.GetCustomAttribute(typeof(MapToPropertyAttribute)))?.PropertyName | |
.PipeTo(n => | |
{ | |
this.GetType().GetProperty(property.Name).GetValue(this) | |
.PipeTo(v => | |
{ | |
if (v == null) return false; | |
var value = Convert.ChangeType(v, type.GetProperty(n).PropertyType); | |
type.GetProperty(n).SetValue(entity, value); | |
return true; | |
}); | |
return true; | |
}); | |
} | |
} | |
return entity; | |
} | |
public IEnumerable<ValidationResult> Validate() | |
{ | |
var validationContext = new ValidationContext(this); | |
var results = this.Validate(validationContext); | |
return results; | |
} | |
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) | |
{ | |
List<ValidationResult> results = new List<ValidationResult>(); | |
foreach(var current in validationContext.Items) | |
{ | |
var key = current.Key; | |
var value = current.Value; | |
} | |
foreach (var current in this.GetType() | |
.GetProperties() | |
.Where(p => p.GetCustomAttributes().Any(a => a.GetType() == typeof(MapToPropertyAttribute)))) | |
{ | |
if(Validators.Keys.Contains(current.Name) && !Validators[current.Name](current.GetValue(this))) | |
results.Add(new ValidationResult(current.Name)); | |
} | |
return results; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment