Пример #1
0
        public static void StartAutoCompile()
        {
            // 1. 查找所有的数据实体类型
            TypesAndReferences findResult = FindEntityTypes();

            // 2. 批量编译数据实体
            BatchCompile(findResult);
        }
Пример #2
0
        public void DoWork(object obj)
        {
            TypesAndReferences threadParam = (TypesAndReferences)obj;

            try
            {
                // 1. 生成代码
                //string code = GeneratorCode(threadParam);

                //// 2. 编译生成的代码
                //Assembly assembly = CompilerCode(code, threadParam.ReferencedAssemblies);

                // 3. 创建委托,供后续代码调用
                //CreateDelegate(threadParam.EntityTypes, assembly);
            }
            catch (System.Exception ex)
            {
                BuildManager.AddException(ex);
            }
        }
Пример #3
0
        private static TypesAndReferences FindEntityTypes()
        {
            string runtimeFolder = BinDirectory;

            List <Assembly> assemblies   = new List <Assembly>();
            List <string>   assemblyList = new List <string>();

            // 只搜索所有以【EntityAssembly】结尾的程序集
            foreach (string file in Directory.GetFiles(runtimeFolder, EntityAssembly, SearchOption.TopDirectoryOnly))
            {
                //MemoryStream memStream;
                //using (FileStream stream = new FileStream(file, FileMode.Open))
                //{
                //    using (memStream = new MemoryStream())
                //    {
                //        int res;
                //        byte[] b = new byte[4096];
                //        while ((res = stream.Read(b, 0, b.Length)) > 0)
                //        {
                //            memStream.Write(b, 0, b.Length);
                //        }
                //    }
                //}
                //assemblies.Add(Assembly.Load(memStream.ToArray()));
                assemblies.Add(Assembly.Load(File.ReadAllBytes(file)));
                // 保存程序集的引用
                assemblyList.Add(file);
            }


            List <Type> types = new List <Type>();

            Type typeBaseEntity    = typeof(BaseEntity);
            Type typeBaseEntityOfT = typeof(BaseEntity <>);

            foreach (Assembly assembly in assemblies)
            {
                foreach (Type type in assembly.GetExportedTypes())
                {
                    // 查找所有 BaseEntity 的继承类,并且【排除嵌套类型】。
                    if (type.IsSubclassOf(typeBaseEntity) || type.IsSubclassOf(typeBaseEntityOfT))
                    {
                        if (type.IsNested == false)
                        {
                            // 数据实体类型要求提供【无参构造函数】。
                            if (type.GetConstructor(Type.EmptyTypes) == null)
                            {
                                throw new InvalidProgramException(string.Format("类型 {0} 没有定义无参的构造函数 。", type));
                            }

                            // 保留符合所有条件的数据实体类型,它将被编译
                            types.Add(type);
                        }
                    }
                }
            }

            // 添加必要的其它引用程序集,供编译使用
            assemblyList.Add("System.dll");
            assemblyList.Add("System.Xml.dll");
            assemblyList.Add("System.Web.dll");
            assemblyList.Add("System.Data.dll");
            //assemblyList.Add("Oracle.DataAccess.dll");
            assemblyList.Add(typeof(BuildManager).Assembly.Location);
            //添加Oracle.DataAccess.dll
            assemblyList.Add(typeof(Oracle.ManagedDataAccess.Client.OracleCommand).Assembly.Location);

            // 构造返回结果
            TypesAndReferences result = new TypesAndReferences();

            result.EntityTypes          = types;
            result.ReferencedAssemblies = assemblyList.ToArray();
            return(result);
        }
Пример #4
0
        private static void BatchCompile(TypesAndReferences findResult)
        {
            //findResult.EntityTypes = findResult.EntityTypes.Take(200).ToList();

            int typeCount = findResult.EntityTypes.Count;

            //如果小于或等于容器大小.则无需开启线程编译
            if (typeCount <= Number200)
            {
                CodeDomCompiler compiler = new CodeDomCompiler();
                compiler.DoWork(findResult);
            }
            else
            {
                // 计算编译线程数量
                int threadCount = typeCount % Number200 == 0 ? typeCount / Number200 : typeCount / Number200 + 1;
                if (threadCount > MaxThreadCount)
                {
                    threadCount = MaxThreadCount;
                }


                int threadPqgeSize = (typeCount / threadCount) + 1;
                int typeSum        = 0;

                // 为每个线程准备调用参数
                TypesAndReferences[] parameters = new TypesAndReferences[threadCount];
                for (int i = 0; i < threadCount; i++)
                {
                    parameters[i] = new TypesAndReferences();
                    parameters[i].ReferencedAssemblies = (from s in findResult.ReferencedAssemblies select s).ToArray();
                    parameters[i].EntityTypes          = findResult.EntityTypes.Skip(typeSum).Take(threadPqgeSize).ToList();
                    typeSum += parameters[i].EntityTypes.Count;
                }

                // 创建编译线程
                List <Thread> threads = new List <Thread>(threadCount);
                for (int i = 1; i < threadCount; i++)
                {
                    CodeDomCompiler compiler = new CodeDomCompiler();
                    Thread          thread   = new Thread(compiler.DoWork);
                    thread.IsBackground = true;
                    thread.Name         = "CompilerThread #" + i.ToString();
                    threads.Add(thread);
                    thread.Start(parameters[i]);
                }

                // 重用当前线程:为当前线程指派编译任务。
                CodeDomCompiler compiler2 = new CodeDomCompiler();
                compiler2.DoWork(parameters[0]);


                // 等待所有的编译线程执行线束。
                foreach (Thread thread in threads)
                {
                    thread.Join();
                }
            }

            // 如果在编译期间发生了异常,则抛出所有收集到的异常。
            if (s_buildException.Count > 0)
            {
                //把第一个异常放入InnerException
                System.Exception innerException = s_buildException[0];

                BuildException buildException = new BuildException("初始化过程中编译异常。", innerException)
                {
                    BuildExceptions = new List <System.Exception>(s_buildException)
                };

                throw buildException;
            }
        }