PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/referencesource/System.ServiceModel/System/ServiceModel/ServiceConfiguration.cs

https://github.com/pruiz/mono
C# | 348 lines | 216 code | 42 blank | 90 comment | 25 complexity | cfaf5d19edc299294c6c73ca070702e0 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.ServiceModel
  5. {
  6. using System.Collections.Generic;
  7. using System.Collections.ObjectModel;
  8. using System.IdentityModel.Configuration;
  9. using System.Linq;
  10. using System.ServiceModel.Channels;
  11. using System.ServiceModel.Description;
  12. /// <summary>
  13. /// Facade over ServiceHost to use in programmatic configuration.
  14. /// </summary>
  15. public class ServiceConfiguration
  16. {
  17. private ServiceHost host;
  18. // ServiceConfiguration is a facade over a ServiceHost
  19. internal ServiceConfiguration(ServiceHost host)
  20. {
  21. CheckArgument(host, "host");
  22. this.host = host;
  23. }
  24. /// <summary>
  25. /// Gets a complete, in-memory description of the service being configured, including all the endpoints for the service and specifications for their respective addresses, bindings, contracts and behaviors.
  26. /// </summary>
  27. public ServiceDescription Description
  28. {
  29. get
  30. {
  31. return this.host.Description;
  32. }
  33. }
  34. /// <summary>
  35. /// Gets the ServiceAuthenticationBehavior currently enabled on the service's Description.
  36. /// </summary>
  37. public ServiceAuthenticationBehavior Authentication
  38. {
  39. get
  40. {
  41. return this.host.Authentication;
  42. }
  43. }
  44. /// <summary>
  45. /// Gets the ServiceAuthorizationBehavior currently enabled on the service's Description.
  46. /// </summary>
  47. public ServiceAuthorizationBehavior Authorization
  48. {
  49. get
  50. {
  51. return this.host.Authorization;
  52. }
  53. }
  54. /// <summary>
  55. /// Gets the ServiceCredentials currently enabled on the service's Description.
  56. /// </summary>
  57. public ServiceCredentials Credentials
  58. {
  59. get
  60. {
  61. return this.host.Credentials;
  62. }
  63. }
  64. /// <summary>
  65. /// Gets the base addresses for the service as specified by the underlying ServiceHost.
  66. /// </summary>
  67. public ReadOnlyCollection<Uri> BaseAddresses
  68. {
  69. get
  70. {
  71. return this.host.BaseAddresses;
  72. }
  73. }
  74. /// <summary>
  75. /// Gets or sets OpenTimeout for the underlying ServiceHost
  76. /// </summary>
  77. public TimeSpan OpenTimeout
  78. {
  79. get
  80. {
  81. return this.host.OpenTimeout;
  82. }
  83. set
  84. {
  85. this.host.OpenTimeout = value;
  86. }
  87. }
  88. /// <summary>
  89. /// Gets or sets CloseTimeout for the underlying ServiceHost
  90. /// </summary>
  91. public TimeSpan CloseTimeout
  92. {
  93. get
  94. {
  95. return this.host.CloseTimeout;
  96. }
  97. set
  98. {
  99. this.host.CloseTimeout = value;
  100. }
  101. }
  102. /// <summary>
  103. /// Gets or sets a value indicating whether to use token handlers
  104. /// </summary>
  105. public bool UseIdentityConfiguration
  106. {
  107. get
  108. {
  109. return this.Credentials.UseIdentityConfiguration;
  110. }
  111. set
  112. {
  113. this.Credentials.UseIdentityConfiguration = value;
  114. }
  115. }
  116. /// <summary>
  117. /// Gets or sets IdentityConfiguration for the underlying ServiceHost
  118. /// </summary>
  119. public IdentityConfiguration IdentityConfiguration
  120. {
  121. get
  122. {
  123. return this.Credentials.IdentityConfiguration;
  124. }
  125. set
  126. {
  127. this.Credentials.IdentityConfiguration = value;
  128. }
  129. }
  130. /// <summary>
  131. /// Validate a service endpoint and add it to Description
  132. /// </summary>
  133. /// <param name="endpoint">endpoint to add</param>
  134. public void AddServiceEndpoint(ServiceEndpoint endpoint)
  135. {
  136. CheckArgument(endpoint, "endpoint");
  137. // Do some other checks to match ServiceHostBase.AddServiceEndpoint
  138. if ((this.host.State != CommunicationState.Created) && (this.host.State != CommunicationState.Opening))
  139. {
  140. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxServiceHostBaseCannotAddEndpointAfterOpen")));
  141. }
  142. if (this.Description == null)
  143. {
  144. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString("SFxServiceHostBaseCannotAddEndpointWithoutDescription")));
  145. }
  146. if (endpoint.Address == null)
  147. {
  148. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString("SFxEndpointAddressNotSpecified"));
  149. }
  150. if (endpoint.Contract == null)
  151. {
  152. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString("SFxEndpointContractNotSpecified"));
  153. }
  154. if (endpoint.Binding == null)
  155. {
  156. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString("SFxEndpointBindingNotSpecified"));
  157. }
  158. if (!endpoint.IsSystemEndpoint || (endpoint.Contract.ContractType == typeof(IMetadataExchange)))
  159. {
  160. // Throw if contract is not valid for this service
  161. // i.e. if contract is not implemented by service, unless endpoint is a standard endpoint
  162. // note: (metadata endpoints require metadata behavior to implement IMetadataExchange even though it's a standard endpoint)
  163. IContractResolver resolver = this.host.GetContractResolver(this.host.ImplementedContracts);
  164. ConfigLoader configLoader = new ConfigLoader(resolver);
  165. configLoader.LookupContract(endpoint.Contract.ConfigurationName, this.Description.Name); // throws on failure
  166. }
  167. this.Description.Endpoints.Add(endpoint);
  168. }
  169. /// <summary>
  170. /// Create a new service endpoint and add it to Description
  171. /// </summary>
  172. /// <param name="contractType">interface annotated with [ServiceContract]</param>
  173. /// <param name="binding">protocol to use for communication</param>
  174. /// <param name="address">absolute address for service, or address relative to base address for supplied binding</param>
  175. /// <returns>The endpoint which was created</returns>
  176. public ServiceEndpoint AddServiceEndpoint(Type contractType, Binding binding, string address)
  177. {
  178. CheckArgument(address, "address");
  179. return this.AddServiceEndpoint(contractType, binding, new Uri(address, UriKind.RelativeOrAbsolute));
  180. }
  181. /// <summary>
  182. /// Create a new service endpoint and add it to Description
  183. /// </summary>
  184. /// <param name="contractType">interface annotated with [ServiceContract]</param>
  185. /// <param name="binding">protocol to use for communication</param>
  186. /// <param name="address">absolute address for service, or address relative to base address for supplied binding</param>
  187. /// <returns>The endpoint which was created</returns>
  188. public ServiceEndpoint AddServiceEndpoint(Type contractType, Binding binding, Uri address)
  189. {
  190. CheckArgument(contractType, "contractType");
  191. CheckArgument(binding, "binding");
  192. CheckArgument(address, "address");
  193. ContractDescription contract = this.host.ImplementedContracts == null
  194. ? null
  195. : this.host.ImplementedContracts.Values.FirstOrDefault(implementedContract => implementedContract.ContractType == contractType);
  196. if (contract == null)
  197. {
  198. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("contractType", SR.GetString(SR.SFxMethodNotSupportedByType2, this.host.Description.ServiceType, contractType));
  199. }
  200. ServiceEndpoint endpoint = new ServiceEndpoint(contract, binding, new EndpointAddress(ServiceHost.MakeAbsoluteUri(address, binding, this.host.InternalBaseAddresses)));
  201. this.AddServiceEndpoint(endpoint);
  202. return endpoint;
  203. }
  204. /// <summary>
  205. /// Create a new service endpoint and add it to Description
  206. /// </summary>
  207. /// <param name="contractType">interface annotated with [ServiceContract]</param>
  208. /// <param name="binding">protocol to use for communication</param>
  209. /// <param name="address">absolute logical address for service, or address relative to base address for supplied binding</param>
  210. /// <param name="listenUri">absolute physical address for service, or address relative to base address for supplied binding</param>
  211. /// <returns>The endpoint which was created</returns>
  212. public ServiceEndpoint AddServiceEndpoint(Type contractType, Binding binding, string address, Uri listenUri)
  213. {
  214. CheckArgument(listenUri, "listenUri");
  215. ServiceEndpoint endpoint = this.AddServiceEndpoint(contractType, binding, address);
  216. this.SetListenUri(endpoint, binding, listenUri);
  217. return endpoint;
  218. }
  219. /// <summary>
  220. /// Create a new service endpoint and add it to Description
  221. /// </summary>
  222. /// <param name="contractType">interface annotated with [ServiceContract]</param>
  223. /// <param name="binding">protocol to use for communication</param>
  224. /// <param name="address">absolute logical address for service, or address relative to base address for supplied binding</param>
  225. /// <param name="listenUri">absolute physical address for service, or address relative to base address for supplied binding</param>
  226. /// <returns>The endpoint which was created</returns>
  227. public ServiceEndpoint AddServiceEndpoint(Type contractType, Binding binding, Uri address, Uri listenUri)
  228. {
  229. CheckArgument(listenUri, "listenUri");
  230. ServiceEndpoint endpoint = this.AddServiceEndpoint(contractType, binding, address);
  231. this.SetListenUri(endpoint, binding, listenUri);
  232. return endpoint;
  233. }
  234. /// <summary>
  235. /// Convenience method to compute and set endpoint's address
  236. /// </summary>
  237. /// <param name="endpoint">endpoint to set</param>
  238. /// <param name="relativeAddress">address relative to the ServiceHost's base address, if any, for endpoint's current binding</param>
  239. public void SetEndpointAddress(ServiceEndpoint endpoint, string relativeAddress)
  240. {
  241. CheckArgument(endpoint, "endpoint");
  242. CheckArgument(relativeAddress, "relativeAddress");
  243. this.host.SetEndpointAddress(endpoint, relativeAddress);
  244. }
  245. /// <summary>
  246. /// Automatically add endpoints for all of a service's enabled contracts, for all of its enabled base addresses that match the specified binding.
  247. /// </summary>
  248. /// <param name="protocol">Binding to add endpoints for</param>
  249. /// <returns>Endpoints created</returns>
  250. public Collection<ServiceEndpoint> EnableProtocol(Binding protocol)
  251. {
  252. CheckArgument(protocol, "protocol");
  253. Collection<ServiceEndpoint> generatedEndpoints = new Collection<ServiceEndpoint>();
  254. if (this.host.ImplementedContracts != null)
  255. {
  256. // don't generate endpoints for contracts that serve as the base type for other reflected contracts
  257. IEnumerable<ContractDescription> contracts = this.host.ImplementedContracts.Values;
  258. IEnumerable<ContractDescription> mostSpecificContracts = contracts.Where(contract
  259. => contracts.All(otherContract
  260. => object.ReferenceEquals(contract, otherContract)
  261. || !contract.ContractType.IsAssignableFrom(otherContract.ContractType)));
  262. foreach (var uri in this.host.BaseAddresses)
  263. {
  264. if (uri.Scheme.Equals(protocol.Scheme))
  265. {
  266. foreach (ContractDescription contract in mostSpecificContracts)
  267. {
  268. ServiceEndpoint endpoint = new ServiceEndpoint(contract, protocol, new EndpointAddress(uri));
  269. this.AddServiceEndpoint(endpoint);
  270. generatedEndpoints.Add(endpoint);
  271. }
  272. }
  273. }
  274. }
  275. return generatedEndpoints;
  276. }
  277. /// <summary>
  278. /// Load endpoints and behaviors into service Description from current AppDomain's configuration
  279. /// </summary>
  280. public void LoadFromConfiguration()
  281. {
  282. this.host.LoadFromConfiguration();
  283. }
  284. /// <summary>
  285. /// Load endpoints and behaviors into service Description from supplied configuration
  286. /// </summary>
  287. /// <param name="configuration">configuration to load from</param>
  288. public void LoadFromConfiguration(System.Configuration.Configuration configuration)
  289. {
  290. CheckArgument(configuration, "configuration");
  291. this.host.LoadFromConfiguration(configuration);
  292. }
  293. private static void CheckArgument<T>(T argument, string argumentName)
  294. {
  295. if (argument == null)
  296. {
  297. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(argumentName);
  298. }
  299. }
  300. private void SetListenUri(ServiceEndpoint endpoint, Binding binding, Uri listenUri)
  301. {
  302. endpoint.UnresolvedListenUri = listenUri;
  303. endpoint.ListenUri = ServiceHost.MakeAbsoluteUri(listenUri, binding, this.host.InternalBaseAddresses);
  304. }
  305. }
  306. }