Ejemplo n.º 1
0
        /// <summary>
        /// 编译程序集
        /// </summary>
        /// <param name="url"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        private static String CompilerAssembly(String url, String serviceName, String assemblyPath)
        {
            // 1. 使用 WebClient 下载 WSDL 信息。
            WebClient web = new WebClient();

            using (Stream stream = web.OpenRead(url + "?WSDL"))
            {
                // 2. 创建和格式化 WSDL 文档。
                ServiceDescription description = ServiceDescription.Read(stream);

                // 3. 创建客户端代理代理类。
                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();

                importer.ProtocolName          = "Soap";                               // 指定访问协议。
                importer.Style                 = ServiceDescriptionImportStyle.Client; // 生成客户端代理。
                importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;

                importer.AddServiceDescription(description, null, null); // 添加 WSDL 文档。

                // 4. 使用 CodeDom 编译客户端代理类。
                CodeNamespace   nmspace = new CodeNamespace(serviceName); // 为代理类添加命名空间,缺省为全局空间。
                CodeCompileUnit unit    = new CodeCompileUnit();
                unit.Namespaces.Add(nmspace);

                ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

                // 4.1 根据ESB的需要修正自动生成的代码, 只针对Java进行修正
                if (!url.EndsWith(".asmx"))
                {
                    FixAutoGenCode(nmspace, description);
                }

                CompilerParameters parameter = new CompilerParameters();
                parameter.GenerateExecutable = false;
                parameter.GenerateInMemory   = false;
                parameter.OutputAssembly     = assemblyPath; // 可以指定你所需的任何文件名。
                parameter.ReferencedAssemblies.Add("System.dll");
                parameter.ReferencedAssemblies.Add("System.XML.dll");
                parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
                parameter.ReferencedAssemblies.Add("System.Data.dll");

                CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);

                // 5. 如果编译出现异常,则直接抛出
                if (result.Errors.HasErrors)
                {
                    System.Text.StringBuilder sb = new StringBuilder();
                    sb.AppendLine("编译代理程序集出现异常:");

                    foreach (CompilerError ce in result.Errors)
                    {
                        sb.Append(ce.ToString() + System.Environment.NewLine);
                    }
                    throw new Exception(sb.ToString());
                }

                // 6. 返回代理类的名词
                Regex regSoap = new Regex("Soap$");
                // 注意:此处要用全名,因为可能存在多个服务共用一个DLL的情况
                String portTypeFullName = serviceName + "." + regSoap.Replace(description.PortTypes[0].Name, "");

                //--记录代理程序集的端口类名,当不需要编译程序集的时候可以直接从AssemblyType.GetInstance(assemblyPath).PortType获取
                AssemblyType.Add(assemblyPath, portTypeFullName);

                return(portTypeFullName);
            }
        }