/// <summary>
        /// This is the workhorse method of the program. Given a web service type, 
        /// it generates a proxy class for it, strips out any excess types, and then 
        /// adds a few using statments to it. 
        /// </summary>
        /// <param name="type">The web service type</param>
        /// <param name="uri">The URL for the service that will be set in the constructor</param>
        private bool Compile()
        {
            try
            {
                // These next two lines do the generate the WSDL based on the web service class
                ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
                reflector.Reflect(m_type, m_uri);

                if (reflector.ServiceDescriptions.Count > 1)
                    throw new Exception(string.Format("Don't know how to deal with multiple service descriptions in {0}", m_type));

                // Now we take the WSDL service description and turn it into a proxy in CodeDOM form
                ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
                importer.AddServiceDescription(reflector.ServiceDescriptions[0], null, null);
                importer.Style = m_style;

                // Probably a good idea to make the namespace a command-line parameter, but hardcode it for now
                //CodeNamespace codeNamespace = new CodeNamespace("Integic.ePower.Psd.WebServices.Common.Proxies");
                CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
                codeCompileUnit.Namespaces.Add(CodeNamespace);

                ServiceDescriptionImportWarnings warnings = importer.Import(CodeNamespace, codeCompileUnit);

                // TODO: explicitly handle all of the warnings generated by the ServiceImporter
                if (warnings != 0)
                {
                    Trace.TraceError("Warnings: {1}", warnings);

                    string errorMessage;
                    switch (warnings)
                    {
                        case ServiceDescriptionImportWarnings.NoMethodsGenerated:
                            errorMessage = string.Format("Error: Web service at {0} does not contain any web methods", m_type.FullName);
                            throw new ApplicationException(errorMessage);
                        case ServiceDescriptionImportWarnings.NoCodeGenerated:
                            errorMessage = string.Format("Error: No code was generated for web service at {0}", m_type.FullName);
                            throw new ApplicationException(errorMessage);
                        default:
                            errorMessage = string.Format("Error: Unhandled error while generating code for web service {0} : {1}", m_type.FullName, warnings.ToString());
                            throw new ApplicationException(errorMessage);
                    }
                }

                if (!GenerateCode())
                    return false;

            }
            catch (Exception ex)
            {
                Errors.Add(new CompilerError(string.Empty, 0, 0, string.Empty, ex.Message));
                Trace.TraceError(ex.ToString());
                return false;
            }

            return true;

        }
 internal DocumentationServerType(Type type, string uri) : base(typeof(DocumentationServerProtocol))
 {
     uri = new Uri(uri, true).GetLeftPart(UriPartial.Path);
     this.methodInfo = new LogicalMethodInfo(typeof(DocumentationServerProtocol).GetMethod("Documentation", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance));
     ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
     reflector.Reflect(type, uri);
     this.schemas = reflector.Schemas;
     this.serviceDescriptions = reflector.ServiceDescriptions;
     this.schemasWithPost = reflector.SchemasWithPost;
     this.serviceDescriptionsWithPost = reflector.ServiceDescriptionsWithPost;
 }
示例#3
0
        public void Generate(Type type, string url, TextWriter writer)
        {
            ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
            reflector.Reflect(type, url);

            if (reflector.ServiceDescriptions.Count > 1)
                throw new Exception("Deal with multiple service descriptions later");

            using (XmlTextWriter wtr = new XmlTextWriter(writer))
            {
                wtr.Formatting = Formatting.Indented;
                reflector.ServiceDescriptions[0].Write(wtr);
                wtr.Close();
            }

        }
		public void ReflectNullableInt ()
		{
			ServiceDescriptionReflector r =
				new ServiceDescriptionReflector ();
			r.Reflect (typeof (NullableContainer), null);
			ServiceDescription sd = r.ServiceDescriptions [0];
			XmlSchema xs = sd.Types.Schemas [0];
			XmlSchemaElement el = null;
			foreach (XmlSchemaElement e in xs.Items) {
				if (e.Name != "GetNullResponse")
					continue;
				el = e;
				break;
			}
			XmlSchemaComplexType ct =
				el.SchemaType as XmlSchemaComplexType;
			XmlSchemaSequence s = ct.Particle as XmlSchemaSequence;
			XmlSchemaElement e2 = s.Items [0] as XmlSchemaElement;
			Assert.IsTrue (e2.IsNillable);
		}
 internal DiscoveryServerType(Type type, string uri) : base(typeof(DiscoveryServerProtocol))
 {
     this.schemaTable = new Hashtable();
     this.wsdlTable = new Hashtable();
     uri = new Uri(uri, true).GetLeftPart(UriPartial.Path);
     this.methodInfo = new LogicalMethodInfo(typeof(DiscoveryServerProtocol).GetMethod("Discover", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance));
     ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
     reflector.Reflect(type, uri);
     XmlSchemas schemas = reflector.Schemas;
     this.description = reflector.ServiceDescription;
     XmlSerializer serializer = ServiceDescription.Serializer;
     this.AddSchemaImports(schemas, uri, reflector.ServiceDescriptions);
     for (int i = 1; i < reflector.ServiceDescriptions.Count; i++)
     {
         ServiceDescription description = reflector.ServiceDescriptions[i];
         Import import = new Import {
             Namespace = description.TargetNamespace
         };
         string key = "wsdl" + i.ToString(CultureInfo.InvariantCulture);
         import.Location = uri + "?wsdl=" + key;
         reflector.ServiceDescription.Imports.Add(import);
         this.wsdlTable.Add(key, description);
     }
     this.discoDoc = new DiscoveryDocument();
     this.discoDoc.References.Add(new ContractReference(uri + "?wsdl", uri));
     foreach (Service service in reflector.ServiceDescription.Services)
     {
         foreach (Port port in service.Ports)
         {
             SoapAddressBinding binding = (SoapAddressBinding) port.Extensions.Find(typeof(SoapAddressBinding));
             if (binding != null)
             {
                 System.Web.Services.Discovery.SoapBinding binding2 = new System.Web.Services.Discovery.SoapBinding {
                     Binding = port.Binding,
                     Address = binding.Location
                 };
                 this.discoDoc.References.Add(binding2);
             }
         }
     }
 }
 // See comment on the ServerProtocol.IsCacheUnderPressure method for explanation of the excludeSchemeHostPortFromCachingKey logic.
 internal DocumentationServerType(Type type, string uri, bool excludeSchemeHostPortFromCachingKey)
     : base(typeof(DocumentationServerProtocol))
 {
     if (excludeSchemeHostPortFromCachingKey)
     {
         this.UriFixups = new List<Action<Uri>>();
     }                   
     //
     // parse the uri from a string into a URI object
     //
     Uri uriObject = new Uri(uri, true);
     //
     // and get rid of the query string if there's one
     //
     uri = uriObject.GetLeftPart(UriPartial.Path);
     methodInfo = new LogicalMethodInfo(typeof(DocumentationServerProtocol).GetMethod("Documentation", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
     ServiceDescriptionReflector reflector = new ServiceDescriptionReflector(this.UriFixups);
     reflector.Reflect(type, uri);
     schemas = reflector.Schemas;
     serviceDescriptions = reflector.ServiceDescriptions;
     schemasWithPost = reflector.SchemasWithPost;
     serviceDescriptionsWithPost = reflector.ServiceDescriptionsWithPost;
 }
        private XmlElement GetWsdl()
        {
            ServiceDescriptionReflector reflector = new ServiceDescriptionReflector();
            reflector.Reflect(typeof(EditServiceImplementation), HttpContext.Current.Request.RawUrl);

            if (reflector.ServiceDescriptions.Count > 1)
            {
                throw new Exception("I'll deal with multiple service descriptions later");
            }

            MemoryStream ms = new MemoryStream();
            XmlTextWriter wtr = new XmlTextWriter(ms, System.Text.Encoding.UTF8);
            wtr.Formatting = System.Xml.Formatting.Indented;
            reflector.ServiceDescriptions[0].Write(wtr);
            wtr.Close();
            ms.Position = 0;

            XmlDocument doc = new XmlDocument();
            doc.Load(ms);

            return doc.DocumentElement;
        }
		public void IncludeTest ()
		{
			ServiceDescriptionReflector reflector = new ServiceDescriptionReflector ();
			reflector.Reflect (typeof (IncludeTestServices), "http://localhost/IncludeTestServices.asmx");

			Assert.AreEqual (0, reflector.Schemas.Count, "#1");
			Assert.AreEqual (1, reflector.ServiceDescriptions.Count, "#2");

			ServiceDescription sd = reflector.ServiceDescriptions[0];

			Assert.IsNull (sd.Name, "#3");
			Assert.AreEqual (1, sd.Types.Schemas.Count, "#4");

			StringWriter sw = new StringWriter ();
			sd.Write (sw);

			Assert.AreEqual (string.Format(CultureInfo.InvariantCulture,
				"<?xml version=\"1.0\" encoding=\"utf-16\"?>{0}" +
#if NET_2_0
				"<wsdl:definitions xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\""  +
				" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\"" +
				" xmlns:tns=\"http://tempuri.org/\" xmlns:s=\"http://www.w3.org/2001/XMLSchema\"" +
				" xmlns:soap12=\"http://schemas.xmlsoap.org/wsdl/soap12/\"" +
				" xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" targetNamespace=\"http://tempuri.org/\"" +
				" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">{0}" +
#else
				"<wsdl:definitions xmlns:http=\"http://schemas.xmlsoap.org/wsdl/http/\" xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"" +
				" xmlns:s=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"" +
				" xmlns:tns=\"http://tempuri.org/\" xmlns:tm=\"http://microsoft.com/wsdl/mime/textMatching/\"" +
				" xmlns:mime=\"http://schemas.xmlsoap.org/wsdl/mime/\" targetNamespace=\"http://tempuri.org/\"" +
				" xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\">{0}" +
#endif
				"  <wsdl:types>{0}" +
				"    <s:schema elementFormDefault=\"qualified\" targetNamespace=\"http://tempuri.org/\">{0}" +
				"      <s:element name=\"EchoString\">{0}" +
				"        <s:complexType>{0}" +
				"          <s:sequence>{0}" +
				"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"strval\" type=\"s:string\" />{0}" +
				"          </s:sequence>{0}" +
				"        </s:complexType>{0}" +
				"      </s:element>{0}" +
				"      <s:element name=\"EchoStringResponse\">{0}" +
				"        <s:complexType>{0}" +
				"          <s:sequence>{0}" +
				"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"MyTime\" type=\"s:time\" />{0}" +
				"          </s:sequence>{0}" +
				"        </s:complexType>{0}" +
				"      </s:element>{0}" +
				"      <s:element name=\"Vehicle\">{0}" +
				"        <s:complexType>{0}" +
				"          <s:sequence>{0}" +
				"            <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"licenseNumber\" type=\"s:string\" />{0}" +
				"          </s:sequence>{0}" +
				"        </s:complexType>{0}" +
				"      </s:element>{0}" +
				"      <s:element name=\"VehicleResponse\">{0}" +
				"        <s:complexType>{0}" +
				"          <s:sequence>{0}" +
				"            <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"NewVehicle\" nillable=\"true\" type=\"tns:Vehicle\" />{0}" +
				"          </s:sequence>{0}" +
				"        </s:complexType>{0}" +
				"      </s:element>{0}" +
				"      <s:complexType name=\"Vehicle\" abstract=\"true\">{0}" +
				"        <s:sequence>{0}" +
				"          <s:element minOccurs=\"0\" maxOccurs=\"1\" name=\"licenseNumber\" type=\"s:string\" />{0}" +
				"          <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"make\" type=\"s:dateTime\" />{0}" +
				"          <s:element minOccurs=\"1\" maxOccurs=\"1\" name=\"age\" type=\"tns:TimeSpan\" />{0}" +
				"        </s:sequence>{0}" +
				"      </s:complexType>{0}" +
				"      <s:complexType name=\"TimeSpan\" />{0}" +
				"      <s:complexType name=\"Car\">{0}" +
				"        <s:complexContent mixed=\"false\">{0}" +
				"          <s:extension base=\"tns:Vehicle\" />{0}" +
				"        </s:complexContent>{0}" +
				"      </s:complexType>{0}" +
				"    </s:schema>{0}" +
				"  </wsdl:types>{0}" +
				"  <wsdl:message name=\"EchoStringSoapIn\">{0}" +
				"    <wsdl:part name=\"parameters\" element=\"tns:EchoString\" />{0}" +
				"  </wsdl:message>{0}" +
				"  <wsdl:message name=\"EchoStringSoapOut\">{0}" +
				"    <wsdl:part name=\"parameters\" element=\"tns:EchoStringResponse\" />{0}" +
				"  </wsdl:message>{0}" +
				"  <wsdl:message name=\"VehicleSoapIn\">{0}" +
				"    <wsdl:part name=\"parameters\" element=\"tns:Vehicle\" />{0}" +
				"  </wsdl:message>{0}" +
				"  <wsdl:message name=\"VehicleSoapOut\">{0}" +
				"    <wsdl:part name=\"parameters\" element=\"tns:VehicleResponse\" />{0}" +
				"  </wsdl:message>{0}" +
				"  <wsdl:portType name=\"IncludeTestServicesSoap\">{0}" +
				"    <wsdl:operation name=\"EchoString\">{0}" +
				"      <wsdl:input message=\"tns:EchoStringSoapIn\" />{0}" +
				"      <wsdl:output message=\"tns:EchoStringSoapOut\" />{0}" +
				"    </wsdl:operation>{0}" +
				"    <wsdl:operation name=\"Vehicle\">{0}" +
				"      <wsdl:input message=\"tns:VehicleSoapIn\" />{0}" +
				"      <wsdl:output message=\"tns:VehicleSoapOut\" />{0}" +
				"    </wsdl:operation>{0}" +
				"  </wsdl:portType>{0}" +
				"  <wsdl:binding name=\"IncludeTestServicesSoap\" type=\"tns:IncludeTestServicesSoap\">{0}" +
#if NET_2_0
				"    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" />{0}" +
#else
				"    <soap:binding transport=\"http://schemas.xmlsoap.org/soap/http\" style=\"document\" />{0}" +
#endif
				"    <wsdl:operation name=\"EchoString\">{0}" +
				"      <soap:operation soapAction=\"http://tempuri.org/EchoString\" style=\"document\" />{0}" +
				"      <wsdl:input>{0}" +
				"        <soap:body use=\"literal\" />{0}" +
				"      </wsdl:input>{0}" +
				"      <wsdl:output>{0}" +
				"        <soap:body use=\"literal\" />{0}" +
				"      </wsdl:output>{0}" +
				"    </wsdl:operation>{0}" +
				"    <wsdl:operation name=\"Vehicle\">{0}" +
				"      <soap:operation soapAction=\"http://tempuri.org/Vehicle\" style=\"document\" />{0}" +
				"      <wsdl:input>{0}" +
				"        <soap:body use=\"literal\" />{0}" +
				"      </wsdl:input>{0}" +
				"      <wsdl:output>{0}" +
				"        <soap:body use=\"literal\" />{0}" +
				"      </wsdl:output>{0}" +
				"    </wsdl:operation>{0}" +
				"  </wsdl:binding>{0}" +
#if NET_2_0
				"  <wsdl:binding name=\"IncludeTestServicesSoap12\" type=\"tns:IncludeTestServicesSoap\">{0}" +
				"    <soap12:binding transport=\"http://schemas.xmlsoap.org/soap/http\" />{0}" +
				"    <wsdl:operation name=\"EchoString\">{0}" +
				"      <soap12:operation soapAction=\"http://tempuri.org/EchoString\" style=\"document\" />{0}" +
				"      <wsdl:input>{0}" +
				"        <soap12:body use=\"literal\" />{0}" +
				"      </wsdl:input>{0}" +
				"      <wsdl:output>{0}" +
				"        <soap12:body use=\"literal\" />{0}" +
				"      </wsdl:output>{0}" +
				"    </wsdl:operation>{0}" +
				"    <wsdl:operation name=\"Vehicle\">{0}" +
				"      <soap12:operation soapAction=\"http://tempuri.org/Vehicle\" style=\"document\" />{0}" +
				"      <wsdl:input>{0}" +
				"        <soap12:body use=\"literal\" />{0}" +
				"      </wsdl:input>{0}" +
				"      <wsdl:output>{0}" +
				"        <soap12:body use=\"literal\" />{0}" +
				"      </wsdl:output>{0}" +
				"    </wsdl:operation>{0}" +
				"  </wsdl:binding>{0}" +
#endif
				"  <wsdl:service name=\"IncludeTestServices\">{0}" +
#if ONLY_1_1
				"    <documentation xmlns=\"http://schemas.xmlsoap.org/wsdl/\" />{0}" +
#endif
				"    <wsdl:port name=\"IncludeTestServicesSoap\" binding=\"tns:IncludeTestServicesSoap\">{0}" +
				"      <soap:address location=\"http://localhost/IncludeTestServices.asmx\" />{0}" +
				"    </wsdl:port>{0}" +
#if NET_2_0
				"    <wsdl:port name=\"IncludeTestServicesSoap12\" binding=\"tns:IncludeTestServicesSoap12\">{0}" +
				"      <soap12:address location=\"http://localhost/IncludeTestServices.asmx\" />{0}" +
				"    </wsdl:port>{0}" +
#endif
				"  </wsdl:service>{0}" +
				"</wsdl:definitions>", Environment.NewLine), sw.ToString (), "#5");
		}
		public void Bug345449 ()
		{
			ServiceDescriptionReflector r =
				new ServiceDescriptionReflector ();
			r.Reflect (typeof (Bug345448Service), "urn:foo");
			ServiceDescription sd = r.ServiceDescriptions [0];

			Assert.AreEqual("Bug345448ServiceSoap", sd.Services [0].Ports [0].Name, "sd #3");
			Assert.AreEqual("Bug345448ServiceSoap12", sd.Services [0].Ports [1].Name, "sd #4");
		}
		public void Bug332150 ()
		{
			ServiceDescriptionReflector r =
				new ServiceDescriptionReflector ();
			r.Reflect (typeof (Bug332150Service), "urn:foo");
			StringWriter sw = new StringWriter ();
			r.ServiceDescriptions [0].Write (sw);
			ServiceDescription.Read (new StringReader (sw.ToString ()));
		}
		public void EmptyAction ()
		{
			ServiceDescriptionReflector r =
				new ServiceDescriptionReflector ();
			r.Reflect (typeof (EmptyActionService), "urn:foo");
			Binding b = r.ServiceDescriptions [0].Bindings ["EmptyActionServiceSoap"];
			OperationBinding o = b.Operations [0];
			SoapOperationBinding sob = o.Extensions [0] as SoapOperationBinding;
			Assert.AreEqual (String.Empty, sob.SoapAction);
		}
		public void ReflectTypeNonDefaultBinding ()
		{
			// bug #78953
			ServiceDescriptionReflector r =
				new ServiceDescriptionReflector ();
			r.Reflect (typeof (EdaInterface), "urn:foo");
//foreach (ServiceDescription sss in r.ServiceDescriptions) sss.Write (Console.Out);
			// It should create two wsdls, one for www.DefaultNamespace.org and
			// another for urn:localBinding:local .
			Assert.AreEqual (2, r.ServiceDescriptions.Count, "#1");
			Assert.IsNotNull (r.ServiceDescriptions ["www.DefaultNamespace.org"], "#1-1");
			ServiceDescription sd = r.ServiceDescriptions ["urn:localBinding:local"];
			Assert.IsNotNull (sd, "#1-2");
#if NET_2_0
			// Soap and Soap12
			Assert.AreEqual (2, sd.Bindings.Count, "#2-2.0");
#else
			// Soap
			Assert.AreEqual (1, sd.Bindings.Count, "#2-1.1");
#endif
			Binding b = sd.Bindings [0];
			Assert.AreEqual ("Local", b.Name, "#3");
		}
示例#13
0
		internal ServiceDescriptionCollection GetDescriptions ()
		{
			if (_descriptions == null)
			{
				ServiceDescriptionReflector reflector = new ServiceDescriptionReflector ();
				reflector.Reflect (ServiceType,_url);
				_schemas = reflector.Schemas;
				_descriptions = reflector.ServiceDescriptions;
			}
			return _descriptions;
		}
示例#14
0
文件: MonoWSDL.cs 项目: Anjoli/mono
		///
		/// <summary>
		///	Driver's main control flow:
		///	 - parse arguments
		///	 - report required messages
		///	 - terminate if no input
		///	 - report errors
		/// </summary>
		///
		int Run(string[] args)
		{
			try
			{
				// parse command line arguments
				foreach (string argument in args)
				{
					ImportArgument(argument);
				}
				
				if (noLogo == false)
					Console.WriteLine(ProductId);
				
				if (help || (!hasURL && className == null))
				{
					Console.WriteLine(UsageMessage);
					return 0;
				}
				
				if (className == null) {
					DiscoveryClientProtocol dcc = CreateClient ();

					foreach (string urlEntry in urls) {
						string url = urlEntry;
						dcc.AllowAutoRedirect = true;
						if (!url.StartsWith ("http://") && !url.StartsWith ("https://") && !url.StartsWith ("file://"))
							url = new Uri (Path.GetFullPath (url)).ToString ();
							
						dcc.DiscoverAny (url);
						dcc.ResolveAll ();
					}

					foreach (object doc in dcc.Documents.Values) {
						if (doc is ServiceDescription)
							descriptions.Add ((ServiceDescription) doc);
						else if (doc is XmlSchema)
							schemas.Add ((XmlSchema) doc);
					}

					if (descriptions.Count == 0) {
						Console.WriteLine ("Warning: no classes were generated.");
						return 0;
					}
				} else {
					string[] names = className.Split (',');
					if (names.Length != 2) throw new Exception ("Invalid parameter value for 'type'");
					string cls = names[0].Trim ();
					string assembly = names[1].Trim ();
					
					Assembly asm = Assembly.LoadFrom (assembly);
					Type t = asm.GetType (cls);
					if (t == null) throw new Exception ("Type '" + cls + "' not found in assembly " + assembly);
					ServiceDescriptionReflector reflector = new ServiceDescriptionReflector ();
					foreach (string url in urls)
						reflector.Reflect (t, url);
					foreach (XmlSchema s in reflector.Schemas)
						schemas.Add (s);
						
					foreach (ServiceDescription sd in reflector.ServiceDescriptions)
						descriptions.Add (sd);
				}
				
				if (sampleSoap != null)
				{
					ConsoleSampleGenerator.Generate (descriptions, schemas, sampleSoap, generator.Protocol);
					return 0;
				}
				
				// generate the code
				generator.GenerateCode (descriptions, schemas);
				return 0;
			}
			catch (NullReferenceException e)
			{
				Console.WriteLine (e);
				return 2;
			}
			catch (InvalidCastException e)
			{
				Console.WriteLine (e);
				return 2;
			}
			catch (Exception exception)
			{
				Console.WriteLine("Error: {0}", exception.Message);
				// FIXME: surpress this except for when debug is enabled
				//Console.WriteLine("Stack:\n {0}", exception.StackTrace);
				return 2;
			}
		}
        // See comment on the ServerProtocol.IsCacheUnderPressure method for explanation of the excludeSchemeHostPortFromCachingKey logic.
        internal DiscoveryServerType(Type type, string uri, bool excludeSchemeHostPortFromCachingKey)
            : base(typeof(DiscoveryServerProtocol))
        {
            if (excludeSchemeHostPortFromCachingKey)
            {
                this.UriFixups = new List<Action<Uri>>();
            }            
            //
            // parse the uri from a string into a Uri object
            //
            Uri uriObject = new Uri(uri, true);
            //
            // and get rid of the query string if there's one
            //
            uri = uriObject.GetLeftPart(UriPartial.Path);
            methodInfo = new LogicalMethodInfo(typeof(DiscoveryServerProtocol).GetMethod("Discover", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
            ServiceDescriptionReflector reflector = new ServiceDescriptionReflector(this.UriFixups);
            reflector.Reflect(type, uri);

            XmlSchemas schemas = reflector.Schemas;
            this.description = reflector.ServiceDescription;
            
            // We need to force initialization of ServiceDescription's XmlSerializer since we
            // won't necessarily have the permissions to do it when we actually need it
            XmlSerializer serializer = ServiceDescription.Serializer;

            // add imports to the external schemas
            AddSchemaImports(schemas, uri, reflector.ServiceDescriptions);

            // add imports to the other service descriptions
            for (int i = 1; i < reflector.ServiceDescriptions.Count; i++) {
                ServiceDescription description = reflector.ServiceDescriptions[i];
                Import import = new Import();
                import.Namespace = description.TargetNamespace;

                // 


                string id = "wsdl" + i.ToString(CultureInfo.InvariantCulture);

                import.Location = uri + "?wsdl=" + id;
                this.AddUriFixup(delegate(Uri current)
                {
                    import.Location = CombineUris(current, import.Location);
                });
                reflector.ServiceDescription.Imports.Add(import);
                wsdlTable.Add(id, description);
            }

            discoDoc = new DiscoveryDocument();
            ContractReference contractReference = new ContractReference(uri + "?wsdl", uri);
            this.AddUriFixup(delegate(Uri current)
            {
                contractReference.Ref = CombineUris(current, contractReference.Ref);
                contractReference.DocRef = CombineUris(current, contractReference.DocRef);
            });
            discoDoc.References.Add(contractReference);

            foreach (Service service in reflector.ServiceDescription.Services) {
                foreach (Port port in service.Ports) {
                    SoapAddressBinding soapAddress = (SoapAddressBinding)port.Extensions.Find(typeof(SoapAddressBinding));
                    if (soapAddress != null) {
                        System.Web.Services.Discovery.SoapBinding binding = new System.Web.Services.Discovery.SoapBinding();
                        binding.Binding = port.Binding;
                        binding.Address = soapAddress.Location;
                        this.AddUriFixup(delegate(Uri current)
                        {
                            binding.Address = CombineUris(current, binding.Address);
                        });
                        discoDoc.References.Add(binding);
                    }
                }
            }
        }