/// <summary>Attribute testing</summary> private static void AttributeTest() { Console.Write("AttributeTest:"); Options opts = new Options("testing", "someclass"); opts.AddAssembly("System.Runtime.Serialization.dll"); opts.AddPropertyAttributes("test", new List<string>() { "[DataMember]" }); opts.AddClassAttribute("[DataContract]"); opts.AddNamespace("System.Runtime.Serialization"); var result = ObjectWrapper.CreateFrom(new { test = "abc" }, opts).Instance; foreach (var attr in result.GetType().GetCustomAttributes(false)) { if (attr.ToString() != "System.Runtime.Serialization.DataContractAttribute") { Console.WriteLine(attr.ToString()); Console.WriteLine(Fail); return; } } foreach (var prop in result.GetType().GetProperties()) { if (prop.Name == "test") { foreach (var attr in prop.GetCustomAttributes(false)) { if (attr.ToString() != "System.Runtime.Serialization.DataMemberAttribute") { Console.WriteLine(attr.ToString()); Console.WriteLine(Fail); return; } } } } Console.WriteLine(Pass); }
/// <summary>Invalid class definition</summary> private static void InvalidClassTest() { Console.Write("InvalidClassTest:"); try { Options opts = new Options("test", "abc"); opts.AddNamespace("INVALID"); ObjectWrapper.CreateFrom(new { name = "test" }, opts); } catch (InvalidOperationException error) { if (!error.Message.StartsWith("Invalid syntax or usage")) { Console.WriteLine(error); Console.WriteLine(Fail); return; } } Console.WriteLine(Pass); }
/// <summary>Type mapping test</summary> private static void TypeMapTest() { Console.Write("TypeMapTest:"); var obj = ObjectWrapper.CreateFrom(new { abc = "1" }, new Options("test", "testclass")); if (obj.GetField("abc").GetType().Name != "String") { Console.WriteLine(obj.GetField("abc").GetType().Name); Console.WriteLine(Fail); return; } Options opts = new Options("test", "test_class"); opts.AddPropertyType("abc", "System.Int32"); opts.AddConverter("abc", x => { return Convert.ToInt32(x); }); obj = ObjectWrapper.CreateFrom(new { abc = "1" }, opts); if (obj.GetField("abc").GetType().Name != "Int32") { Console.WriteLine(obj.GetField("abc").GetType().Name); Console.WriteLine(Fail); return; } var serialized = Serializer.Serialize(obj.Instance); if (serialized != @"{""abc"":1}") { Console.WriteLine(serialized); Console.WriteLine(Fail); return; } Console.WriteLine(Pass); }
/// <summary>Adding a namespace</summary> private static void NamespaceTest() { Console.Write("NamespaceTest:"); Options opts = new Options("test", "testclass"); opts.AddNamespace("System.Text"); ObjectWrapper.CreateFrom(new { abc = new System.Text.StringBuilder() }, opts); Console.WriteLine(Pass); }
/// <summary>Testing option input arguments</summary> private static void OptionTestArgs() { Console.Write("OptionTestArgs:"); Options opt = null; try { new Options(null, "test_class"); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("namespaceName")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt = new Options("test", null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("className")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } opt = new Options("test", "test_class"); try { opt.AddNamespace(null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("name")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddPropertyType(null, null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("property")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddPropertyType("abc", null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("typeName")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddConverter(null, null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("property")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddConverter("test", null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("function")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddClassAttribute(null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("attribute")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddAssembly(null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("assemblyName")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddPropertyAttributes(null, null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("propertyName")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } try { opt.AddPropertyAttributes("test", null); Console.WriteLine(Fail); return; } catch (ArgumentNullException ex) { if (!ex.Message.Contains("attributes")) { Console.WriteLine(ex); Console.WriteLine(Fail); return; } } Console.WriteLine(Pass); }
/// <summary>Option creation testing</summary> private static void OptionTest() { Console.Write("OptionTest:"); Options opt = new Options("test", "test_class"); opt.AddAssembly("System.Data.dll"); opt.AddClassAttribute("[DataContract]"); opt.AddPropertyAttributes("Something", new List<string>() { "[DataMember]" }); opt.AddPropertyType("abc", "System.String"); opt.AddConverter("abc", x => { return 1; }); opt.AddNamespace("system.namespace"); var props = opt.GetPropertyAttributes("someTHING"); if (props.Count == 1 && props[0] == "[DataMember]") { } else { Console.WriteLine("Invalid property attributes"); Console.WriteLine(Fail); return; } props = opt.GetPropertyAttributes("OTHER"); if (props.Count != 0) { Console.WriteLine("Invalid property attributes, should be empty"); Console.WriteLine(Fail); return; } var classAttributes = opt.GetClassAttributes(); if (classAttributes.Count == 1 && classAttributes[0] == "[DataContract]") { } else { Console.WriteLine("Invalid class attributes"); Console.WriteLine(Fail); return; } var assemblies = opt.GetAssemblies(); if (assemblies.Count == 1 && assemblies[0] == "System.Data.dll") { } else { Console.WriteLine("Invalid assembly set"); Console.WriteLine(Fail); return; } if (opt.GetPropertyType("abc") != "System.String") { Console.WriteLine("Incorrect type"); Console.WriteLine(Fail); return; } if (opt.GetPropertyType("xyz") != null) { Console.WriteLine("Type shouldn't be set"); Console.WriteLine(Fail); return; } if (opt.GetConverter("abc") == null) { Console.WriteLine("Incorrect converter"); Console.WriteLine(Fail); return; } if (opt.GetConverter("xyz") != null) { Console.WriteLine("Converter shouldn't be set"); Console.WriteLine(Fail); return; } var names = opt.GetNamespaces(); if (names.Length != 1 || names[0] != "system.namespace") { Console.WriteLine("Incorrect namespace set"); Console.WriteLine(Fail); return; } Console.WriteLine(Pass); }
/// <summary> /// Create an object wrapper from the given object /// </summary> /// <param name="objs">Object list to create from</param> /// <param name="options">Creation options</param> /// <returns>Object wrapper set from all the objects in the set</returns> public static IEnumerable<ObjectWrapper> CreateFromEnumerable(IEnumerable<object> objs, Options options) { if (objs == null) { throw new ArgumentNullException("objs"); } if (options == null) { throw new ArgumentNullException("options"); } if (objs.Any()) { Type type = objs.First().GetType(); Assembly assembly = null; if (!cached.TryGetValue(options.FullClass, out assembly)) { // Only allow anonymous types (why else would you call this?) // http://stackoverflow.com/questions/1650681/determining-whether-a-type-is-an-anonymous-type bool hasCompilerGeneratedAttribute = type.GetCustomAttributes(typeof(CompilerGeneratedAttribute), false).Count() > 0; bool nameContainsAnonymousType = type.FullName.Contains(AnonymousType) || type.FullName.Contains(AnonType); bool anonymousType = hasCompilerGeneratedAttribute && nameContainsAnonymousType; if (!anonymousType) { throw new InvalidOperationException("Class must be of anonymous type"); } // Build the class file StringBuilder classBuilder = new StringBuilder(); classBuilder.AppendLine(" using System; "); foreach (var name in options.GetNamespaces()) { classBuilder.AppendFormat(" using {0}; ", name); classBuilder.AppendLine(); } classBuilder.AppendFormat("namespace {0} ", options.Namespace); classBuilder.AppendLine("{"); foreach (var classAttribute in options.GetClassAttributes()) { classBuilder.AppendFormat(" {0} ", classAttribute); } classBuilder.AppendFormat("public class {0}", options.ClassName); classBuilder.AppendLine("{"); foreach (var property in type.GetProperties()) { var typeName = property.PropertyType.Name; var typeValue = options.GetPropertyType(property.Name); if (typeValue != null) { typeName = typeValue; } foreach (var propertyAttribute in options.GetPropertyAttributes(property.Name)) { classBuilder.AppendFormat(" {0} ", propertyAttribute); } classBuilder.AppendFormat(" public {0} {1} ", typeName, property.Name); classBuilder.AppendLine(" { get; set; } "); } classBuilder.Append("}"); classBuilder.Append("}"); // Compile it // http://stackoverflow.com/questions/9414008/c-sharp-use-reflection-to-build-a-class-to-build-a-dynamic-filehelper-class CompilerParameters parameters = new CompilerParameters(); parameters.GenerateExecutable = false; parameters.GenerateInMemory = true; parameters.IncludeDebugInformation = false; foreach (var assemblyName in options.GetAssemblies()) { parameters.ReferencedAssemblies.Add(assemblyName); } CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp"); CompilerResults compiledResults = compiler.CompileAssemblyFromSource(parameters, classBuilder.ToString()); if (compiledResults.Errors.HasErrors) { StringBuilder outputErrors = new StringBuilder(); for (int index = 0; index < compiledResults.Errors.Count; index++) { outputErrors.AppendLine(compiledResults.Errors[index].ErrorText); } outputErrors.AppendLine(classBuilder.ToString()); throw new InvalidOperationException("Invalid syntax or usage: " + outputErrors.ToString()); } assembly = compiledResults.CompiledAssembly; assembly = cached.GetOrAdd(options.FullClass, assembly); } foreach (var obj in objs) { var instance = assembly.CreateInstance(options.FullClass); var wrapper = new ObjectWrapper(instance); foreach (var property in type.GetProperties()) { var value = property.GetValue(obj, null); var converter = options.GetConverter(property.Name); if (converter != null) { value = converter(value); } wrapper.SetField(property.Name, value); } yield return wrapper; } } }
/// <summary> /// Create an object wrapper from the given object /// </summary> /// <param name="obj">Object to create from</param> /// <param name="options">Creation options</param> /// <returns>Object wrapper</returns> public static ObjectWrapper CreateFrom(object obj, Options options) { if (obj == null) { throw new ArgumentNullException("obj"); } return CreateFromEnumerable(new object[] { obj }, options).First(); }