diff --git a/ZeroLevel/Services/ObjectMapping/MapFieldInfo.cs b/ZeroLevel/Services/ObjectMapping/MapFieldInfo.cs index 9ec6bda..e75c762 100644 --- a/ZeroLevel/Services/ObjectMapping/MapFieldInfo.cs +++ b/ZeroLevel/Services/ObjectMapping/MapFieldInfo.cs @@ -55,7 +55,7 @@ namespace ZeroLevel.Services.ObjectMapping private static MapMemberInfo FromField(FieldInfo fieldInfo) { - var field = new MapMemberInfo(fieldInfo.BuildSetter(), fieldInfo.BuildGetter()) + var field = new MapMemberInfo(TypeGetterSetterBuilder.BuildSetter(fieldInfo), TypeGetterSetterBuilder.BuildGetter(fieldInfo)) { Name = fieldInfo.Name }; @@ -67,7 +67,7 @@ namespace ZeroLevel.Services.ObjectMapping private static IMemberInfo FromProperty(PropertyInfo propertyInfo) { - var field = new MapMemberInfo(propertyInfo.BuildSetter(), propertyInfo.BuildGetter()) + var field = new MapMemberInfo(TypeGetterSetterBuilder.BuildSetter(propertyInfo), TypeGetterSetterBuilder.BuildGetter(propertyInfo)) { Name = propertyInfo.Name }; diff --git a/ZeroLevel/Services/Reflection/ITypeFastAccessMethodBuilder.cs b/ZeroLevel/Services/Reflection/ITypeFastAccessMethodBuilder.cs deleted file mode 100644 index 51e6dff..0000000 --- a/ZeroLevel/Services/Reflection/ITypeFastAccessMethodBuilder.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Reflection; - -namespace ZeroLevel.Services.Reflection -{ - public interface ITypeFastAccessMethodBuilder - { - Func BuildGetter(PropertyInfo property); - - Func BuildGetter(FieldInfo field); - - Action BuildSetter(PropertyInfo property); - - Action BuildSetter(FieldInfo field); - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilder.cs b/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilder.cs deleted file mode 100644 index 72db0db..0000000 --- a/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilder.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Reflection; - -namespace ZeroLevel.Services.Reflection -{ - public static class TypeFastAccessMethodBuilder - { - private readonly static ITypeFastAccessMethodBuilder _builder; - - static TypeFastAccessMethodBuilder() - { - _builder = new TypeFastAccessMethodBuilderImpl(); - } - - public static Func BuildGetter(this FieldInfo field) - { - return _builder.BuildGetter(field); - } - - public static Func BuildGetter(this PropertyInfo property) - { - return _builder.BuildGetter(property); - } - - public static Action BuildSetter(this FieldInfo field) - { - return _builder.BuildSetter(field); - } - - public static Action BuildSetter(this PropertyInfo property) - { - return _builder.BuildSetter(property); - } - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilderImpl.cs b/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilderImpl.cs deleted file mode 100644 index a4c825c..0000000 --- a/ZeroLevel/Services/Reflection/TypeFastAccessMethodBuilderImpl.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Reflection; - -namespace ZeroLevel.Services.Reflection -{ - public class TypeFastAccessMethodBuilderImpl : ITypeFastAccessMethodBuilder - { - public Func BuildGetter(PropertyInfo property) - { - if (property == null) return null; - if (property.CanRead == false) return null; - var getterMethodInfo = property.GetGetMethod(); - var entity = Expression.Parameter(typeof(object), "o"); - var target = property.DeclaringType.IsValueType ? - Expression.Unbox(entity, property.DeclaringType) : - Expression.Convert(entity, property.DeclaringType); - var getterCall = Expression.Call(target, getterMethodInfo); - var castToObject = Expression.Convert(getterCall, typeof(object)); - var lambda = Expression.Lambda(castToObject, entity); - return (Func)lambda.Compile(); - } - - public Func BuildGetter(FieldInfo field) - { - if (field == null) return null; - var entity = Expression.Parameter(typeof(object), "o"); - var target = field.DeclaringType.IsValueType ? - Expression.Unbox(entity, field.DeclaringType) : - Expression.Convert(entity, field.DeclaringType); - var fieldExp = Expression.Field(target, field); - var castToObject = Expression.Convert(fieldExp, typeof(object)); - var lambda = Expression.Lambda(castToObject, entity); - return (Func)lambda.Compile(); - } - - /// - /// Creates a quick setter for a property - /// - public Action BuildSetter(PropertyInfo property) - { - if (property == null) return null; - if (property.CanWrite == false) return null; - var method = property.GetSetMethod(true); - var obj = Expression.Parameter(typeof(object), "o"); - var value = Expression.Parameter(typeof(object)); - var target = property.DeclaringType.IsValueType ? - Expression.Unbox(obj, method.DeclaringType) : - Expression.Convert(obj, method.DeclaringType); - var expr = Expression. - Lambda>(Expression.Call(target, method, - Expression.Convert(value, method.GetParameters()[0].ParameterType)), - obj, value); - return expr.Compile(); - } - - /// - /// Creates a quick setter for a field. - /// - public Action BuildSetter(FieldInfo field) - { - if (field == null) return null; - var targetExp = Expression.Parameter(field.DeclaringType, "target"); - var valueExp = Expression.Parameter(typeof(object), "value"); - - // Expression.Property can be used here as well - var obj = Expression.Parameter(typeof(object), "o"); - var target = field.DeclaringType.IsValueType ? - Expression.Unbox(obj, field.DeclaringType) : - Expression.Convert(obj, field.DeclaringType); - - var fieldExp = Expression.Field(target, field); - var assignExp = Expression.Assign(fieldExp, Expression.Convert(valueExp, field.FieldType)); - - return Expression.Lambda> - (assignExp, obj, valueExp).Compile(); - } - } -} \ No newline at end of file diff --git a/ZeroLevel/Services/Reflection/TypeGetterSetterBuilder.cs b/ZeroLevel/Services/Reflection/TypeGetterSetterBuilder.cs new file mode 100644 index 0000000..a2e807a --- /dev/null +++ b/ZeroLevel/Services/Reflection/TypeGetterSetterBuilder.cs @@ -0,0 +1,129 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace ZeroLevel.Services.Reflection +{ + public static class TypeGetterSetterBuilder + { + public static Func BuildGetter(FieldInfo field) + { + if (field == null) return null; + var entity = Expression.Parameter(typeof(object), "o"); + var target = field.DeclaringType.IsValueType ? + Expression.Unbox(entity, field.DeclaringType) : + Expression.Convert(entity, field.DeclaringType); + var fieldExp = Expression.Field(target, field); + var castToObject = Expression.Convert(fieldExp, typeof(object)); + var lambda = Expression.Lambda(castToObject, entity); + return (Func)lambda.Compile(); + } + + public static Func BuildGetter(PropertyInfo property) + { + if (property == null) return null; + if (property.CanRead == false) return null; + var getterMethodInfo = property.GetGetMethod(); + var entity = Expression.Parameter(typeof(object), "o"); + var target = property.DeclaringType.IsValueType ? + Expression.Unbox(entity, property.DeclaringType) : + Expression.Convert(entity, property.DeclaringType); + var getterCall = Expression.Call(target, getterMethodInfo); + var castToObject = Expression.Convert(getterCall, typeof(object)); + var lambda = Expression.Lambda(castToObject, entity); + return (Func)lambda.Compile(); + } + + /// + /// Creates a quick setter for a field. + /// + public static Action BuildSetter(FieldInfo field) + { + if (field == null) + { + return null; + } + var instance = Expression.Parameter(typeof(object), "target"); + var inputValue = Expression.Parameter(typeof(object), "value"); + var target = field.DeclaringType.IsValueType ? + Expression.Unbox(instance, field.DeclaringType) : + Expression.Convert(instance, field.DeclaringType); + var fieldExp = Expression.Field(target, field); + + var typeCode = Type.GetTypeCode(field.FieldType); + var changeTypeMethod = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(TypeCode) }); + var convertExpression = Expression.Call(changeTypeMethod, inputValue, Expression.Constant(typeCode)); + + var assignExp = Expression.Assign(fieldExp, field.FieldType.IsValueType ? + Expression.Convert(convertExpression, field.FieldType) : + Expression.TypeAs(convertExpression, field.FieldType)); + + return Expression.Lambda>(assignExp, instance, inputValue).Compile(); + } + + /// + /// Creates a quick setter for a property + /// + public static Action BuildSetter(PropertyInfo property) + { + if (property == null || property.CanWrite == false) + { + return null; + } + var instance = Expression.Parameter(typeof(object), "target"); + var inputValue = Expression.Parameter(typeof(object), "value"); + var target = property.DeclaringType.IsValueType ? + Expression.Unbox(instance, property.DeclaringType) : + Expression.Convert(instance, property.DeclaringType); + var method = property.GetSetMethod(true); + var typeCode = Type.GetTypeCode(property.PropertyType); + var changeTypeMethod = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(TypeCode) }); + var convertExpression = Expression.Call(changeTypeMethod, inputValue, Expression.Constant(typeCode)); + var setterCall = Expression.Call(target, method, Expression.Convert(convertExpression, property.PropertyType)); + var expr = Expression.Lambda>(setterCall, instance, inputValue); + return expr.Compile(); + } + + /// + /// Creates a quick setter for a field. + /// + public static Action BuildSetter(FieldInfo field) + { + if (field == null || typeof(T) != field.DeclaringType) + { + return null; + } + var targetExp = Expression.Parameter(typeof(T), "target"); + var inputValue = Expression.Parameter(typeof(object), "o"); + var fieldExp = Expression.Field(targetExp, field); + var typeCode = Type.GetTypeCode(field.FieldType); + var changeTypeMethod = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(TypeCode) }); + var convertExpression = Expression.Call(changeTypeMethod, inputValue, Expression.Constant(typeCode)); + var assignExp = Expression.Assign(fieldExp, Expression.Convert(convertExpression, field.FieldType)); + return Expression.Lambda>(assignExp, targetExp, inputValue).Compile(); + } + + /// + /// Creates a quick setter for a property + /// + public static Action BuildSetter(PropertyInfo property) + { + if (property == null || typeof(T) != property.DeclaringType || property.CanWrite == false) + { + return null; + } + var method = property.GetSetMethod(true); + var instance = Expression.Parameter(property.DeclaringType, "i"); + var target = property.DeclaringType.IsValueType ? + Expression.Unbox(instance, method.DeclaringType) : + Expression.Convert(instance, method.DeclaringType); + var value = Expression.Parameter(typeof(object), "v"); + var typeCode = Type.GetTypeCode(property.PropertyType); + var changeTypeMethod = typeof(Convert).GetMethod("ChangeType", new Type[] { typeof(object), typeof(TypeCode) }); + var convertExpression = Expression.Call(changeTypeMethod, value, Expression.Constant(typeCode)); + var setterCall = Expression.Call(target, method, Expression.Convert(convertExpression, property.PropertyType)); + var expr = Expression.Lambda>(setterCall, instance, value); + return expr.Compile(); + } + } +} \ No newline at end of file diff --git a/ZeroLevel/Services/Serialization/MessageSerializer.cs b/ZeroLevel/Services/Serialization/MessageSerializer.cs index 8d61cd3..fc425b1 100644 --- a/ZeroLevel/Services/Serialization/MessageSerializer.cs +++ b/ZeroLevel/Services/Serialization/MessageSerializer.cs @@ -254,7 +254,7 @@ namespace ZeroLevel.Services.Serialization { instance.Deserialize(reader); } - return TypeFastAccessMethodBuilder.BuildGetter(rt.GetProperty("Value"))(instance); + return TypeGetterSetterBuilder.BuildGetter(rt.GetProperty("Value"))(instance); } } } \ No newline at end of file diff --git a/ZeroLevel/ZeroLevel.csproj b/ZeroLevel/ZeroLevel.csproj index cf7daa7..db88542 100644 --- a/ZeroLevel/ZeroLevel.csproj +++ b/ZeroLevel/ZeroLevel.csproj @@ -279,12 +279,10 @@ - - - +