Example #1
0
        private static Assembly Compile(String outputAssembly, IEnumerable<String> references, CodeDomProvider provider, CompilerErrorCollection errors, Template tmp)
        {
            //String key = outputAssembly;
            //if (String.IsNullOrEmpty(key)) key = Hash(String.Join(Environment.NewLine, sources));

            var sb = new StringBuilder();
            foreach (var item in tmp.Templates)
            {
                if (sb.Length > 0) sb.AppendLine();
                sb.Append(item.Source);
            }
            String key = Hash(sb.ToString());

            Assembly assembly = null;
            if (asmCache.TryGetValue(key, out assembly)) return assembly;
            lock (asmCache)
            {
                if (asmCache.TryGetValue(key, out assembly)) return assembly;
                foreach (var str in references)
                {
                    try
                    {
                        if (!String.IsNullOrEmpty(str) && File.Exists(str)) Assembly.LoadFrom(str);
                    }
                    catch { }
                }

                assembly = CompileInternal(outputAssembly, references, provider, errors, tmp);
                if (assembly != null) asmCache.Add(key, assembly);

                return assembly;
            }
        }
Example #2
0
        /// <summary>根据名称和模版创建模版实例,带缓存,避免重复编译</summary>
        /// <param name="templates">模版集合</param>
        /// <returns></returns>
        public static Template Create(IDictionary<String, String> templates)
        {
            if (templates == null || templates.Count < 1) throw new ArgumentNullException("templates");

            // 计算hash
            StringBuilder sb = new StringBuilder();
            foreach (KeyValuePair<String, String> item in templates)
            {
                sb.Append(Hash(item.Key));
                sb.Append(Hash(item.Value));
            }

            String hash = Hash(sb.ToString());

            return cache.GetItem<IDictionary<String, String>>(hash, templates, delegate(String key, IDictionary<String, String> contents)
            {
                Template entity = new Template();

                foreach (KeyValuePair<String, String> item in contents)
                {
                    entity.AddTemplateItem(item.Key, item.Value);
                }

                //entity.Process();
                //entity.Compile();
                return entity;
            });
        }
Example #3
0
        private static Assembly Compile(String outputAssembly, IEnumerable <String> references, CodeDomProvider provider, CompilerErrorCollection errors, Template tmp)
        {
            //String key = outputAssembly;
            //if (String.IsNullOrEmpty(key)) key = Hash(String.Join(Environment.NewLine, sources));

            var sb = new StringBuilder();

            foreach (var item in tmp.Templates)
            {
                if (item.Included)
                {
                    continue;
                }

                if (sb.Length > 0)
                {
                    sb.AppendLine();
                }
                sb.Append(item.Source);
            }
            var key = Hash(sb.ToString());

            Assembly assembly = null;

            if (asmCache.TryGetValue(key, out assembly))
            {
                return(assembly);
            }
            lock (asmCache)
            {
                if (asmCache.TryGetValue(key, out assembly))
                {
                    return(assembly);
                }
                foreach (var str in references)
                {
                    try
                    {
                        if (!String.IsNullOrEmpty(str) && File.Exists(str))
                        {
                            Assembly.LoadFrom(str);
                        }
                    }
                    catch { }
                }

                assembly = CompileInternal(outputAssembly, references, provider, errors, tmp);
                if (assembly != null)
                {
                    asmCache.Add(key, assembly);
                }

                return(assembly);
            }
        }
Example #4
0
        private static Assembly CompileInternal(String outputAssembly, IEnumerable<String> references, CodeDomProvider provider, CompilerErrorCollection Errors, Template tmp)
        {
            var options = new CompilerParameters();
            foreach (var str in references)
            {
                options.ReferencedAssemblies.Add(str);
            }
            options.WarningLevel = 4;

            CompilerResults results = null;
            if (Debug)
            {
                #region 调试状态,把生成的类文件和最终dll输出到XTemp目录下
                var tempPath = XTrace.TempPath;
                //if (!String.IsNullOrEmpty(outputAssembly)) tempPath = Path.Combine(tempPath, Path.GetFileNameWithoutExtension(outputAssembly));
                if (!String.IsNullOrEmpty(outputAssembly) && !outputAssembly.Equals(".dll")) tempPath = Path.Combine(tempPath, Path.GetFileNameWithoutExtension(outputAssembly));

                if (!String.IsNullOrEmpty(tempPath) && !Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);

                var files = new List<String>();
                foreach (var item in tmp.Templates)
                {
                    if (item.Included) continue;

                    String name = item.Name.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) ? item.Name : item.ClassName;
                    // 猜测后缀
                    Int32 p = name.LastIndexOf("_");
                    if (p > 0 && name.Length - p <= 5)
                        name = name.Substring(0, p) + "." + name.Substring(p + 1, name.Length - p - 1);
                    else if (!name.EndsWith(".cs", StringComparison.OrdinalIgnoreCase))
                        name += ".cs";

                    name = Path.Combine(tempPath, name);
                    File.WriteAllText(name, item.Source, Encoding.UTF8);

                    files.Add(name);
                }
                #endregion
                if (!String.IsNullOrEmpty(outputAssembly) && !outputAssembly.Equals(".dll"))
                {
                    options.TempFiles = new TempFileCollection(tempPath, false);
                    options.OutputAssembly = Path.Combine(tempPath, outputAssembly);
                    options.GenerateInMemory = true;
                    options.IncludeDebugInformation = true;
                }

                results = provider.CompileAssemblyFromFile(options, files.ToArray());
            }
            else
            {
                List<String> sources = new List<String>();
                foreach (var item in tmp.Templates)
                {
                    sources.Add(item.Source);
                }

                options.GenerateInMemory = true;

                results = provider.CompileAssemblyFromSource(options, sources.ToArray());
            }

            #region 编译错误处理
            if (results.Errors.Count > 0)
            {
                Errors.AddRange(results.Errors);

                var sb = new StringBuilder();
                CompilerError err = null;
                foreach (CompilerError error in results.Errors)
                {
                    error.ErrorText = error.ErrorText;
                    //if (String.IsNullOrEmpty(error.FileName)) error.FileName = inputFile;

                    if (!error.IsWarning)
                    {
                        String msg = error.ToString();
                        if (sb.Length < 1)
                        {
                            String code = null;
                            // 屏蔽因为计算错误行而导致的二次错误
                            try
                            {
                                code = tmp.FindBlockCode(error.FileName, error.Line);
                            }
                            catch { }
                            if (code != null)
                            {
                                msg += Environment.NewLine;
                                msg += code;
                            }
                            err = error;
                        }
                        else
                            sb.AppendLine();

                        sb.Append(msg);
                    }
                }
                if (sb.Length > 0)
                {
                    TemplateException ex = new TemplateException(sb.ToString());
                    ex.Error = err;
                    throw ex;
                }
            }
            else
            {
                try
                {
                    options.TempFiles.Delete();
                }
                catch { }
            }
            #endregion

            if (!results.Errors.HasErrors)
            {
                try
                {
                    return results.CompiledAssembly;
                }
                catch { }
            }
            return null;
        }
Example #5
0
        private static Assembly CompileInternal(String outputAssembly, IEnumerable <String> references, CodeDomProvider provider, CompilerErrorCollection Errors, Template tmp)
        {
            var options = new CompilerParameters();

            foreach (var str in references)
            {
                options.ReferencedAssemblies.Add(str);
            }
            options.WarningLevel = 4;

            CompilerResults results = null;

            if (Debug)
            {
                //var sb = new StringBuilder();

                #region 调试状态,把生成的类文件和最终dll输出到XTemp目录下
                var tempPath = XTrace.TempPath.GetFullPath().EnsureDirectory(false);
                //if (!String.IsNullOrEmpty(outputAssembly)) tempPath = Path.Combine(tempPath, Path.GetFileNameWithoutExtension(outputAssembly));
                if (!String.IsNullOrEmpty(outputAssembly) && !outputAssembly.EqualIgnoreCase(".dll"))
                {
                    tempPath = Path.Combine(tempPath, Path.GetFileNameWithoutExtension(outputAssembly));
                }

                //if (!String.IsNullOrEmpty(tempPath) && !Directory.Exists(tempPath)) Directory.CreateDirectory(tempPath);

                //var srcpath = tempPath.CombinePath("src").EnsureDirectory(false);

                var files = new List <String>();
                foreach (var item in tmp.Templates)
                {
                    // 输出模版内容,为了调试使用
                    File.WriteAllText(tempPath.CombinePath(item.Name).EnsureDirectory(true), item.Content);
                    if (item.Included)
                    {
                        continue;
                    }

                    var name = item.Name.EndsWithIgnoreCase(".cs") ? item.Name : item.ClassName;
                    // 猜测后缀
                    var p = name.LastIndexOf("_");
                    if (p > 0 && name.Length - p <= 5)
                    {
                        name = name.Substring(0, p) + "." + name.Substring(p + 1, name.Length - p - 1);
                    }
                    else if (!name.EndsWithIgnoreCase(".cs"))
                    {
                        name += ".cs";
                    }

                    //name = Path.Combine(tempPath, name);
                    //name = srcpath.CombinePath(name);
                    // 必须放在同一个目录,编译时会搜索源码所在目录
                    name = tempPath.CombinePath(Path.GetFileNameWithoutExtension(name) + "_src" + Path.GetExtension(name));
                    File.WriteAllText(name, item.Source);

                    //sb.AppendLine(item.Source);
                    files.Add(name);
                }
                #endregion

                if (!String.IsNullOrEmpty(outputAssembly) && !outputAssembly.EqualIgnoreCase(".dll"))
                {
                    options.TempFiles      = new TempFileCollection(tempPath, false);
                    options.OutputAssembly = Path.Combine(tempPath, outputAssembly);
                    //options.GenerateInMemory = true;
                    options.IncludeDebugInformation = true;
                }

                results = provider.CompileAssemblyFromFile(options, files.ToArray());
                // 必须从内存字符串编译,否则pdb会定向到最终源代码文件
                //results = provider.CompileAssemblyFromSource(options, new String[] { sb.ToString() });
            }
            else
            {
                options.GenerateInMemory = true;

                results = provider.CompileAssemblyFromSource(options, tmp.Templates.Where(e => !e.Included).Select(e => e.Source).ToArray());
            }

            #region 编译错误处理
            if (results.Errors.Count > 0)
            {
                Errors.AddRange(results.Errors);

                var           sb  = new StringBuilder();
                CompilerError err = null;
                foreach (CompilerError error in results.Errors)
                {
                    error.ErrorText = error.ErrorText;
                    //if (String.IsNullOrEmpty(error.FileName)) error.FileName = inputFile;

                    if (!error.IsWarning)
                    {
                        var msg = error.ToString();
                        if (sb.Length < 1)
                        {
                            String code = null;
                            // 屏蔽因为计算错误行而导致的二次错误
                            try
                            {
                                code = tmp.FindBlockCode(error.FileName, error.Line);
                            }
                            catch { }
                            if (code != null)
                            {
                                msg += Environment.NewLine;
                                msg += code;
                            }
                            err = error;
                        }
                        else
                        {
                            sb.AppendLine();
                        }

                        sb.Append(msg);
                    }
                }
                if (sb.Length > 0)
                {
                    var ex = new TemplateException(sb.ToString());
                    ex.Error = err;
                    throw ex;
                }
            }
            else
            {
                try
                {
                    options.TempFiles.Delete();
                }
                catch { }
            }
            #endregion

            if (!results.Errors.HasErrors)
            {
                try
                {
                    return(results.CompiledAssembly);
                }
                catch { }
            }
            return(null);
        }