public static bool SetPropertyValue <T>(this object candidate, PropertyInfo property, T value)
        {
            if (candidate == null)
            {
                throw new ArgumentNullException("candidate");
            }

            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            if (property.PropertyType != typeof(T) && !property.PropertyType.IsSubclassOf(typeof(T)))
            {
                Type declaringType = property.DeclaringType;
                throw new ArgumentException(String.Format("Cannot set value of Type {0} on Property {1}.{2} of Type {3}", typeof(T), declaringType != null ? declaringType.Name : "", property.Name, property.PropertyType));
            }

            try
            {
                PropertyAccessor.Create(property).Set(candidate, value);
                return(true);
            }
            catch
            {
                return(false);
            }
        }
        public static void MergeInto <T>(this T source, T target)
        {
            Type type = typeof(T);

            IEnumerable <FieldInfo> fields = type.GetFields().Where(f => f.GetCustomAttribute <MergeFieldAttribute>() != null);

            foreach (FieldInfo field in fields)
            {
                object value       = field.GetValue(source);
                object targetValue = field.GetValue(target);
                value = GetLatestVersion(targetValue, value);
                field.SetValue(target, value);
            }

            IEnumerable <PropertyInfo> properties = type.GetProperties().Where(p => p.GetCustomAttribute <MergeFieldAttribute>() != null);

            foreach (PropertyInfo property in properties)
            {
                PropertyAccessor propertyAccessor = PropertyAccessor.Create(property);
                object           value            = propertyAccessor.Get(source);
                object           targetValue      = propertyAccessor.Get(target);
                value = GetLatestVersion(targetValue, value);
                propertyAccessor.Set(target, value);
            }
        }
        public static TOut TransposeExact <TIn, TOut>(this TIn input)
        {
            Type inType      = typeof(TIn);
            Type outType     = typeof(TOut);
            TOut returnValue = Activator.CreateInstance <TOut>();

            foreach (var property in inType.GetProperties())
            {
                var outProperty = outType.GetProperty(property.Name);
                var value       = property.GetValue(input, null);

                if (property.PropertyType.Name.Contains("Collection") || property.PropertyType.Name.Contains("List"))
                {
                    var collectionEntryType = property.PropertyType.GetGenericArguments().Single();

                    if (!collectionEntryType.IsValueType && collectionEntryType != typeof(string))
                    {
                        object collection     = PropertyAccessor.Create(property).Get(input);
                        object instance       = Activator.CreateInstance(outProperty.PropertyType);
                        IList  instanceAsList = (IList)instance;

                        foreach (object c in ((IList)collection))
                        {
                            object outc = InvokeTransposeExact(c, c.GetType(), outProperty.PropertyType.GetGenericArguments().Single());
                            instanceAsList.Add(outc);
                        }

                        PropertyAccessor.Create(outProperty).Set(returnValue, instance);
                        continue;
                    }

                    PropertyAccessor.Create(outProperty).Set(returnValue, value);
                    continue;
                }
                if (!property.PropertyType.IsValueType && property.PropertyType != typeof(string))
                {
                    value = InvokeTransposeExact(PropertyAccessor.Create(property).Get(input), property.PropertyType,
                                                 outProperty.PropertyType);
                }

                PropertyAccessor.Create(outProperty).Set(returnValue, value);
            }

            return(returnValue);
        }
 public static PropertyAccessor GetAccessor(this PropertyInfo propertyInfo)
 {
     return(PropertyAccessor.Create(propertyInfo));
 }
 public static PropertyAccessor GetPropertyAccessor(this Type candidate, string propertyName)
 {
     return(PropertyAccessor.Create(candidate.GetProperty(propertyName)));
 }
        public static TOut Transpose <TIn, TOut>(this TIn input)
        {
            Type outType = typeof(TOut);
            Type inType  = typeof(TIn);

            TOut result;

            if (!outType.IsValueType && outType.HasParameterlessConstructor())
            {
                result = Activator.CreateInstance <TOut>();
            }
            else
            {
                result = default(TOut);
            }

            FieldInfo[] fields = inType.GetFields();
            IEnumerable <Tuple <FieldInfo, FieldInfo> > fieldInfos = fields.Select(f => new Tuple <FieldInfo, FieldInfo>(f, outType.GetField(f.Name)));

            foreach (Tuple <FieldInfo, FieldInfo> tuple in fieldInfos.Where(t => t.Item2 != null))
            {
                FieldInfo sourceField = tuple.Item1;
                FieldInfo targetField = tuple.Item2;

                if (!sourceField.FieldType.IsValueType && sourceField.FieldType != typeof(string) &&
                    !sourceField.FieldType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose from field {0} of type {2} because it is of type {1} which is not a value type or ICloneable",
                                  sourceField.Name, sourceField.FieldType.Name, inType.Name));
                }

                if (!targetField.FieldType.IsValueType && targetField.FieldType != typeof(string) &&
                    !targetField.FieldType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose to field {0} of type {2} because it is of type {1} which is not a value type or ICloneable",
                                  targetField.Name, targetField.FieldType.Name, outType.Name));
                }

                if (sourceField.FieldType != targetField.FieldType)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose field {0} because in type {1} it is of type {2} and in type {3} it is of type {4}",
                                  sourceField.Name, inType.Name, sourceField.FieldType.Name, outType.Name,
                                  targetField.FieldType.Name));
                }

                object value = sourceField.GetValue(input);

                if (value is ICloneable)
                {
                    value = ((ICloneable)value).Clone();
                }

                targetField.SetValue(result, value);
            }

            PropertyInfo[] properties = inType.GetProperties();
            IEnumerable <Tuple <PropertyInfo, PropertyInfo> > propertyInfos =
                properties.Select(p => new Tuple <PropertyInfo, PropertyInfo>(p, outType.GetProperty(p.Name)));

            foreach (Tuple <PropertyInfo, PropertyInfo> tuple in propertyInfos.Where(t => t.Item2 != null && t.Item2.GetSetMethod() != null))
            {
                PropertyInfo sourceProperty = tuple.Item1;
                PropertyInfo targetProperty = tuple.Item2;

                if (!sourceProperty.PropertyType.IsValueType && sourceProperty.PropertyType != typeof(string) && !sourceProperty.PropertyType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(string.Format("Cannot transpose from property {0} of type {2} because it is of type {1} which is not a value type or ICloneable", sourceProperty.Name, sourceProperty.PropertyType.Name, inType.Name));
                }

                if (!targetProperty.PropertyType.IsValueType && targetProperty.PropertyType != typeof(string) && !targetProperty.PropertyType.GetInterfaces().Contains(typeof(ICloneable)))
                {
                    throw new InvalidOperationException(string.Format("Cannot transpose to property {0} of type {2} because it is of type {1} which is not a value type or ICloneable", targetProperty.Name, targetProperty.PropertyType.Name, outType.Name));
                }

                if (sourceProperty.PropertyType != targetProperty.PropertyType)
                {
                    throw new InvalidOperationException(
                              string.Format(
                                  "Cannot transpose property {0} because in type {1} it is of type {2} and in type {3} it is of type {4}",
                                  sourceProperty.Name, inType.Name, sourceProperty.PropertyType.Name, outType.Name,
                                  targetProperty.PropertyType.Name));
                }

                object value = sourceProperty.GetValue(input);

                if (value is ICloneable)
                {
                    value = ((ICloneable)value).Clone();
                }

                PropertyAccessor.Create(targetProperty).Set(result, value);
            }

            return(result);
        }
 public static object GetValue(this PropertyInfo propertyInfo, object obj)
 {
     return(PropertyAccessor.Create(propertyInfo).Get(obj));
 }
 public static void SetValue(this PropertyInfo propertyInfo, object obj, object value)
 {
     PropertyAccessor.Create(propertyInfo).Set(obj, value);
 }