Skip to content

Instantly share code, notes, and snippets.

@mouadcherkaoui
Created July 26, 2018 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mouadcherkaoui/bef4fe22943b360ae92b0fb84425c8fb to your computer and use it in GitHub Desktop.
Save mouadcherkaoui/bef4fe22943b360ae92b0fb84425c8fb to your computer and use it in GitHub Desktop.
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; }
}
}
}
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