/// <summary> /// Fluent syntax for defining a property mapping. Use in the constructor. /// </summary> /// <typeparam name="TProperty">The type of the property.</typeparam> /// <param name="propertyExpression">The property expression.</param> /// <returns>mapping to configure.</returns> public FluentPropertyMapping <TEntity, TProperty> Property <TProperty>(Expression <Func <TEntity, TProperty> > propertyExpression) { var propertyInfo = propertyExpression.GetPropertyInfo(); if (_mappings.ContainsKey(propertyInfo.Name)) { return(new FluentPropertyMapping <TEntity, TProperty>((PropertyMapping <TEntity>)_mappings[propertyInfo.Name])); } var setter = BuildSetter(typeof(TEntity), propertyInfo); var getter = BuildGetter(typeof(TEntity), propertyInfo); var mapping = new PropertyMapping <TEntity>(propertyInfo.Name, setter, getter) { PropertyType = propertyInfo.PropertyType }; _mappings.Add(propertyInfo.Name, mapping); return(new FluentPropertyMapping <TEntity, TProperty>(mapping)); }
private void MapProperties(Type type) { var properties = typeof(TEntity).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var property in properties) { var method = property.GetSetMethod(true); Action <TEntity, object> setter; if (method == null) { var field = type.GetField("_" + char.ToLower(property.Name[0]) + property.Name.Substring(1), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (field == null) { continue; } var instance = Expression.Parameter(typeof(TEntity), "instance"); var value = Expression.Parameter(typeof(object), "value"); var result = Expression.Lambda <Action <TEntity, object> >( Expression.Assign( Expression.Field(instance, field), Expression.Convert(value, field.FieldType)), instance, value).Compile(); setter = result; } else { var instance = Expression.Parameter(typeof(TEntity), "i"); var argument = Expression.Parameter(typeof(object), "a"); var setterCall = Expression.Call( instance, method, Expression.Convert(argument, property.PropertyType)); var result = (Action <TEntity, object>)Expression.Lambda(setterCall, instance, argument) .Compile(); //var m = method; //setter = (instance, value) => m.Invoke(instance, new[] { value }); setter = result; } method = property.GetGetMethod(true); Func <TEntity, object> getter; if (method == null) { var field = type.GetField("_" + char.ToLower(property.Name[0]) + property.Name.Substring(1), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (field == null) { continue; } //getter = field.GetValue; var paramExpression = Expression.Parameter(typeof(TEntity), "instance"); Expression fieldGetter = Expression.Field(paramExpression, field.Name); if (field.FieldType.IsPrimitive) { fieldGetter = Expression.Convert(fieldGetter, typeof(object)); } var result = Expression.Lambda <Func <TEntity, object> >(fieldGetter, paramExpression).Compile(); getter = result; } else { //var m = method; //getter = (instance) => m.Invoke(instance, null); var instance = Expression.Parameter(typeof(TEntity), "i"); var prop = Expression.Property(instance, property); var convert = Expression.TypeAs(prop, typeof(object)); var result = (Func <TEntity, object>)Expression.Lambda(convert, instance).Compile(); getter = result; } var mapping = new PropertyMapping <TEntity>(property.Name, setter, getter); _mappings.Add(property.Name, mapping); } }