Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Reflection;
- namespace ObjectInitializerCodeGenerator
- {
- public class CodeGenerator
- {
- private CodeGenerator()
- {
- }
- public static string GetFriendlyTypeName(Type type)
- {
- if (type.IsGenericParameter) { return type.Name; }
- if (!type.IsGenericType) { return type.FullName; }
- var builder = new System.Text.StringBuilder();
- var name = type.Name;
- var index = name.IndexOf("`");
- builder.AppendFormat("{0}.{1}", type.Namespace, name.Substring(0, index)); builder.Append('<');
- var first = true;
- foreach (var arg in type.GetGenericArguments())
- {
- if (!first) { builder.Append(','); }
- builder.Append(GetFriendlyTypeName(arg)); first = false;
- }
- builder.Append('>');
- return builder.ToString();
- }
- private string GenerateCodeInternal(object input)
- {
- var variableType = input.GetType();
- var variableName = CreateVariableName(variableType);
- sb.Append("var ");
- sb.Append(variableName);
- //TODO: better check
- if (variableType.IsClass && variableType != typeof(string))
- {
- sb.Append(" = new ");
- sb.Append(GetFriendlyTypeName(variableType));
- sb.AppendLine("();");
- //if (variableType.GetInterfaces().Contains(typeof(System.Collections.IList)))
- var asList = input as System.Collections.IList;
- if (asList != null)
- {
- foreach (var element in asList)
- {
- var elementName = GenerateCodeInternal(element);
- sb.Append(variableName);
- sb.Append(".Add(");
- sb.Append(elementName);
- sb.AppendLine(");");
- }
- }
- else
- {
- foreach (PropertyInfo pi in variableType.GetProperties())
- {
- var propertyValue = pi.GetValue(input, null);
- if (pi.PropertyType.IsValueType)
- {
- //if not default
- if (!object.Equals(Activator.CreateInstance(pi.PropertyType), propertyValue))
- {
- sb.Append(variableName);
- sb.Append(".");
- sb.Append(pi.Name);
- sb.Append(" = ");
- sb.Append(propertyValue); //does not work for Decimal
- sb.AppendLine(";");
- }
- }
- else
- {
- if (propertyValue != null)
- {
- if (pi.PropertyType == typeof(String))
- {
- sb.Append(variableName);
- sb.Append(".");
- sb.Append(pi.Name);
- sb.Append(" = \"");
- sb.Append(propertyValue);
- sb.AppendLine("\";");
- }
- //collection
- else
- {
- //warn if no constructor
- if (pi.PropertyType.GetConstructor(System.Type.EmptyTypes) == null)
- sb.AppendLine("//Warning - no parameterless constructor. Will not compile");
- //recurse
- var objectName = GenerateCodeInternal(propertyValue);
- sb.Append(variableName);
- sb.Append(".");
- sb.Append(pi.Name);
- sb.Append(" = ");
- sb.Append(objectName);
- sb.AppendLine(";");
- }
- }
- }
- //
- //var propname = GenerateCodeInternal(pi.GetValue(input, null));
- }
- }
- }
- //else if (variableType.IsValueType)
- //{
- // sb.Append(" = ");
- // sb.Append(input);
- // sb.AppendLine(";");
- //}
- return variableName;
- }
- const string spaces = " ";
- private string GenerateObjectInitializerCodeInternal(object input, int indent = 0)
- {
- StringBuilder sb = new StringBuilder();
- var variableType = input.GetType();
- if (variableType.IsValueType)
- {
- sb.Append(input.ToString()); //does not work for Decimal
- }
- else if (variableType == typeof(String))
- {
- sb.Append("\"");
- sb.Append(input.ToString());
- sb.Append("\"");
- }
- else if (variableType.IsClass)
- {
- sb.Append("new ");
- sb.Append(GetFriendlyTypeName(variableType));
- //if (variableType.GetInterfaces().Contains(typeof(System.Collections.IList)))
- var list = input as System.Collections.IList;
- if (list != null)
- {
- sb.AppendLine("{");
- var listItems = new List<String>();
- foreach (object item in list)
- {
- listItems.Add(new String('\t', indent + 1) + GenerateObjectInitializerCodeInternal(item, indent + 1));
- }
- if (listItems.Count > 0)
- {
- sb.AppendLine(String.Join(", \n", listItems));
- }
- sb.Append(new String('\t', indent) + "}");
- }
- else
- {
- sb.Append("()");
- var props = new List<String>();
- foreach (PropertyInfo pi in variableType.GetProperties())
- {
- if (pi.PropertyType.IsValueType)
- {
- var propertyValue = pi.GetValue(input, null);
- //if not default
- if (!object.Equals(Activator.CreateInstance(pi.PropertyType), propertyValue))
- {
- props.Add(new String('\t', indent + 1) + pi.Name + " = " + GenerateObjectInitializerCodeInternal(propertyValue, indent + 1));
- }
- }
- else
- {
- var propertyValue = pi.GetValue(input, null);
- if (propertyValue != null)
- {
- props.Add(new String('\t', indent + 1) + pi.Name + " = " + GenerateObjectInitializerCodeInternal(propertyValue, indent + 1));
- }
- }
- }
- if (props.Count > 0)
- {
- sb.AppendLine(" { ");
- sb.AppendLine(String.Join(", \n", props));
- sb.Append(new String('\t', indent) + "}");
- }
- }
- }
- return sb.ToString();
- }
- StringBuilder sb = new StringBuilder();
- public static string GenerateCode<T>(T input) where T : new()
- {
- CodeGenerator cg = new CodeGenerator();
- cg.GenerateCodeInternal(input);
- return cg.sb.ToString();
- }
- public static string GenerateObjectInitializerCode<T>(T input) where T : new()
- {
- CodeGenerator cg = new CodeGenerator();
- return cg.GenerateObjectInitializerCodeInternal(input);
- }
- Dictionary<Type, int> variableNameCounter = new Dictionary<Type, int>();
- public string CreateVariableName(Type t)
- {
- if (!variableNameCounter.ContainsKey(t))
- {
- variableNameCounter.Add(t, 0);
- return t.Name.ToCamelCase() + "0";
- }
- else
- {
- var count = variableNameCounter[t]++;
- return t.Name.ToCamelCase() + count;
- }
- }
- }
- public static class Extentions
- {
- public static string ToCamelCase(this string input)
- {
- if (input == null) return null;
- if (input == String.Empty) return String.Empty;
- if (input.Length == 1) return input.ToLower();
- return Char.ToLower(input[0]).ToString() + input.Substring(1);
- }
- }
- public class Formatter : IFormatProvider
- {
- public object GetFormat(Type formatType)
- {
- throw new NotImplementedException();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement