Geeks With Blogs
.Nettuce Code Salad
public static class ArgumentParser<T> where T : classnew()
    {
        delegate bool TryParseFunc<TProperty>(string input, out TProperty output);
 
        public static T Parse(string[] args, params Expression<Func<T, object>>[] propertiesToSet)
        {
            var target = new T();
            var propertyList = propertiesToSet.ToList();
            for (var i = 0; i < args.Count(); i++)
            {
                var property = propertyList[i];
                var propertyName = PropertyName(property);
                var arg = args[i];
                var returnType = typeof(T).GetProperty(propertyName).PropertyType;
                var methodType = Nullable.GetUnderlyingType(returnType) ?? returnType;
                var stringParameter = Expression.Parameter(typeof(string));
                var outParameter = Expression.Parameter(methodType.MakeByRefType());
                var parseExpression = Expression.Call(methodType.GetMethods().Single(x => x.Name == "TryParse" && x.GetParameters().Count() == 2), stringParameter, outParameter);
                var tryParseFunc = typeof(ArgumentParser<T>).GetMethod("InvokeTryParseFunc"BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(methodType).Invoke(nullnew object[] { arg, parseExpression, stringParameter, outParameter }) as Tuple<boolobject>;
                if (!tryParseFunc.Item1)
                    throw new FormatException(string.Format("{0} is not valid for property {1}", arg, propertyName));
                var targetParameter = Expression.Parameter(typeof(T));
                var memberParameter = Expression.Parameter(returnType);
                var member = Expression.PropertyOrField(targetParameter, propertyName);
                var assign = Expression.Assign(member, memberParameter);
                Expression.Lambda(assign, targetParameter, memberParameter).Compile().DynamicInvoke(target, tryParseFunc.Item2);
            }
            return target;
        }
 
        static Tuple<boolobject> InvokeTryParseFunc<TProperty>(string arg, MethodCallExpression parseExpression, ParameterExpression stringParameter, ParameterExpression outParameter)
        {
            TProperty value;
            var result = Expression.Lambda<TryParseFunc<TProperty>>(parseExpression, stringParameter, outParameter).Compile().Invoke(arg, out value);
            return new Tuple<boolobject>(result, value);
        }
 
        static string PropertyName(LambdaExpression propertyExpression)
        {
            return (propertyExpression.Body is UnaryExpression ? (MemberExpression)((UnaryExpression)propertyExpression.Body).Operand : (MemberExpression)propertyExpression.Body).Member.Name;
        }
    }
Posted on Wednesday, February 20, 2013 2:34 PM | Back to top


Comments on this post: Arguments to DTO Parser for Console Applications

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Jon Canning | Powered by: GeeksWithBlogs.net