예제 #1
0
 /// <summary>
 /// Takes an expression which is expected to be a member access expression (e.g. x.Prop1.Field2.Prop3), and returns a setter for setting that member on that target.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="memberAccess"></param>
 /// <returns></returns>
 public static Action <T> CreateSetter <T>(Expression <Func <T> > memberAccess)
 {
     if (!(memberAccess.Body is MemberExpression))
     {
         throw IEDebug.Exception(null, "The topmost expression must be a simple member access expression.");
     }
     return(v => CreateSetter((MemberExpression)memberAccess.Body)(v));
 }
예제 #2
0
 public static Parser <UpdateConfiguration> BuildKeyValueParser <T>(
     string keyName,
     Parser <T> valueParser,
     Expression <Func <ConnectionConfiguration, T> > getter)
 {
     return
         (from key in Parse.CaseInsensitiveString(keyName).Token()
          from separator in Parse.Char('=')
          from value in valueParser
          select(Func <ConnectionConfiguration, ConnectionConfiguration>)(c =>
     {
         CreateSetter(getter)(c, value);
         return c;
     }));
 }
예제 #3
0
        private static UpdateConfiguration BuildKeyValueParser <T>(
            string keyName,
            Func <string, T> valueParser,
            Expression <Func <ConnectionConfiguration, T> > getter
            )
        {
            return((configuration, keyValues) =>
            {
                if (keyValues != null && keyValues.TryGetValue(keyName, out var keyValue))
                {
                    var parsedValue = valueParser(keyValue);
                    CreateSetter(getter)(configuration, parsedValue);
                }

                return configuration;
            });
        }
예제 #4
0
        private T CloneWithMembers <T>(T source, IReadOnlyCollection <Tuple <MemberInfo, MemberTypes, CloningMode> > members)
        {
            var copy = CreateInstance(source);

            _cloned.Add(source, copy);

            foreach (var member in members)
            {
                if (member.Item3 == CloningMode.Ignore)
                {
                    continue;
                }

                Func <object>           valueGetter;
                Action <object, object> valueSetter;
                Func <object>           structValueGetter;
                Action <object, object> structValueSetter;
                switch (member.Item2)
                {
                case MemberTypes.Property:
                    var property = member.Item1 as PropertyInfo;
                    valueGetter       = () => CreatePropGetter <T, object>(property)(source);
                    valueSetter       = (target, value) => CreatePropSetter <T, object>(property)((T)target, value);
                    structValueGetter = () => property.GetValue(source);
                    structValueSetter = (target, value) => property.SetValue(target, value);
                    break;

                case MemberTypes.Field:
                    var field = member.Item1 as FieldInfo;
                    valueGetter       = () => CreateGetter <T, object>(field)(source);
                    valueSetter       = (target, value) => CreateSetter <T, object>(field)((T)target, value);
                    structValueGetter = () => field.GetValue(source);
                    structValueSetter = (target, value) => field.SetValue(target, value);
                    break;

                default:
                    throw new ArgumentException("Only filed and property cloning supported.");
                }

                object sourceValue = null;
                if (_type.IsValueType)
                {
                    sourceValue = structValueGetter();
                }
                else
                {
                    sourceValue = valueGetter();
                }

                if (sourceValue == null)
                {
                    continue;
                }
                var clone = CloneMakerFactory.GetCloneMaker(sourceValue, member.Item3, _typeMembers, _cloned).Clone(sourceValue, member.Item3);
                if (_type.IsValueType)
                {
                    object boxed = copy;
                    structValueSetter(boxed, clone);
                    copy            = (T)boxed;
                    _cloned[source] = copy;
                }
                else
                {
                    valueSetter(copy, clone);
                }
            }
            return(copy);
        }