コード例 #1
0
        /// <summary>
        /// 加载代理程序集
        /// </summary>
        /// <param name="url"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        private static SoapClientItem LoadAssembly(String url, String serviceName)
        {
            String assemblyPath     = GetAssemblyPath(url);
            String portTypeFullName = String.Empty; // 注意此处要用全名:命名空间.类名

            // 如果代理程序集不存在则编译生成代理程序集,否则直接加载
            if (!File.Exists(assemblyPath))
            {
                portTypeFullName = CompilerAssembly(url, serviceName, assemblyPath);
            }
            else
            {
                portTypeFullName = AssemblyType.GetInstance(assemblyPath).PortType;
            }

            // 如果没有获取到端口类型则清空程序集缓存并抛出异常
            if (portTypeFullName == String.Empty)
            {
                ClearCache(url);
                throw new Exception(String.Format("获取服务:{0}『{1}』的端口类型失败!", serviceName, url));
            }

            Assembly asm = null;

            using (FileStream fs = File.OpenRead(assemblyPath))
            {
                asm = Assembly.Load(fs.ReadBytes(fs.Length)); // 此处采用文件流进行加载,使得加载后的程序集仍然可以被重新编译
            }

            if (asm == null)
            {
                throw new Exception(String.Format("加载代理程序集{0}失败!", assemblyPath));
            }

            //Assembly asm = result.CompiledAssembly;
            //Type portType = asm.GetType(String.Format("{0}.{1}", serviceName, portTypeName));
            //Type reqType = asm.GetType(String.Format("{0}.request", serviceName));

            // 如果在前面为代理类添加了命名空间,此处需要将命名空间添加到类型前面。
            Type portType = GetTypeFromAssembly(asm, portTypeFullName, assemblyPath);
            Type reqType  = GetTypeFromAssembly(asm, String.Format("{0}.request", portTypeFullName.Split('.')[0]), assemblyPath);

            // 创建端口类对象
            Object port = Activator.CreateInstance(portType);

            if (port == null)
            {
                throw new Exception(String.Format("创建:{0}『{1}』的端口类型对象失败!", serviceName, url));
            }

            // 将超时设置为10分钟
            portType.InvokeMember("Timeout", BindingFlags.SetProperty, null, port, new Object[] { 10 * 60 * 1000 });

            SoapClientItem item = new SoapClientItem()
            {
                ProxyAssembly = asm,
                PortObject    = port,
                PortType      = portType,
                RequestType   = reqType
            };

            return(item);
        }