Last active
September 7, 2023 19:47
-
-
Save MMF/4acd8f638b42c34a25bc27756b941b0b to your computer and use it in GitHub Desktop.
MappingExtensions For C#
This file contains hidden or 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.Linq.Expressions; | |
namespace Utilities.Extentions; | |
public static class ObjectExtensions | |
{ | |
/// <summary> | |
/// dynamically set the value of an object's property using property name. | |
/// </summary> | |
/// <param name="obj"></param> | |
/// <param name="propertyName"></param> | |
/// <param name="propertyValue"></param> | |
public static void SetPropertyValue(this Object obj, string propertyName, string propertyValue) | |
{ | |
// get property by name | |
var property = obj.GetType().GetProperties().FirstOrDefault(p => p.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)); | |
if (property != null) | |
{ | |
// get curren property type | |
Type propertyType = property.PropertyType; | |
// if type? is nullable | |
Type typeOfProp = Nullable.GetUnderlyingType(propertyType) ?? propertyType; | |
// get value | |
var convertedValue = Convert.ChangeType(propertyValue, typeOfProp); | |
// set value | |
property.SetValue(obj, convertedValue); | |
} | |
} | |
/// <summary> | |
/// Maps an object to another object. | |
/// Assign values of similar properties from source object to targetObject. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="obj">the source object</param> | |
/// <param name="targetObject">The target object that you are going to map to.</param> | |
/// <param name="ignoreList">string array of properties to be ignored </param> | |
/// <returns></returns> | |
public static T MapTo<T>(this object obj, T targetObject, string[]? ignoreList = null) where T : class | |
{ | |
var sourceProperities = obj.GetType().GetProperties().ToList(); | |
var targetProperities = targetObject.GetType().GetProperties().ToList(); | |
foreach (var sourceProp in sourceProperities) | |
{ | |
var targetProp = targetProperities.Where(t => t.Name.Equals(sourceProp.Name, StringComparison.InvariantCultureIgnoreCase) && | |
sourceProp.PropertyType.Equals(t.PropertyType) && | |
t.CanWrite && sourceProp.CanRead).FirstOrDefault(); | |
if (ignoreList != null && ignoreList.Contains(sourceProp.Name)) | |
continue; | |
if (targetProp != null) | |
targetProp.SetValue(targetObject, sourceProp.GetValue(obj)); | |
} | |
return targetObject; | |
} | |
/// <summary> | |
/// Maps an object to a new object of another Type T | |
/// First it create an object from type T, then it assigns similar properities from source object. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="obj"></param> | |
/// <returns></returns> | |
public static T MapTo<T>(this object obj) where T : class, new() | |
{ | |
var targetObject = new T(); | |
return obj.MapTo(targetObject); | |
} | |
/// <summary> | |
/// Maps an object from another object with similar properities | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="targetObj"></param> | |
/// <param name="sourceObj"></param> | |
public static void MapFrom<T>(this object targetObj, T sourceObj) where T : class | |
{ | |
sourceObj.MapTo(targetObj); | |
} | |
/// <summary> | |
/// Maps an object to another object. | |
/// Assign values of similar properties from source object to targetObject. | |
/// Allows ignoring properities. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
/// <param name="obj"></param> | |
/// <param name="targetObject"></param> | |
/// <param name="ignoreAction"></param> | |
/// <returns></returns> | |
public static T MapTo<T>(this object obj, T targetObject, Action<MappingOptions<T>> ignoreAction) where T : class | |
{ | |
var mappingOptions = new MappingOptions<T>(); | |
ignoreAction.Invoke(mappingOptions); | |
return obj.MapTo(targetObject, mappingOptions.ignoreList.ToArray()); | |
} | |
} | |
public class MappingOptions<T> | |
{ | |
public List<string> ignoreList = new(); | |
public void Ignore(Expression<Func<T, object>> ignoreColumn) | |
{ | |
string? propertyName; | |
if (ignoreColumn.Body is MemberExpression expression) | |
{ | |
propertyName = expression.Member.Name; | |
} | |
else | |
{ | |
var operand = ((UnaryExpression)ignoreColumn.Body).Operand; | |
propertyName = ((MemberExpression)operand).Member.Name; | |
} | |
ignoreList.Add(propertyName); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment