コード例 #1
0
ファイル: Program.cs プロジェクト: enckse/Anon.Compiler
        /// <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);
        }
コード例 #2
0
ファイル: ObjectWrapper.cs プロジェクト: enckse/Anon.Compiler
            /// <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;
                    }
                }
            }