ServiceEndpoint.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Description
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.ComponentModel;
  10. using System.Diagnostics;
  11. using System.Globalization;
  12. using System.ServiceModel;
  13. using System.ServiceModel.Channels;
  14. using System.ServiceModel.Dispatcher;
  15. [DebuggerDisplay("Address={address}")]
  16. [DebuggerDisplay("Name={name}")]
  17. public class ServiceEndpoint
  18. {
  19. EndpointAddress address;
  20. Binding binding;
  21. ContractDescription contract;
  22. Uri listenUri;
  23. ListenUriMode listenUriMode = ListenUriMode.Explicit;
  24. KeyedByTypeCollection<IEndpointBehavior> behaviors;
  25. string id;
  26. XmlName name;
  27. bool isEndpointFullyConfigured = false;
  28. public ServiceEndpoint(ContractDescription contract)
  29. {
  30. if (contract == null)
  31. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
  32. this.contract = contract;
  33. }
  34. public ServiceEndpoint(ContractDescription contract, Binding binding, EndpointAddress address)
  35. {
  36. if (contract == null)
  37. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contract");
  38. this.contract = contract;
  39. this.binding = binding;
  40. this.address = address;
  41. }
  42. public EndpointAddress Address
  43. {
  44. get { return this.address; }
  45. set { this.address = value; }
  46. }
  47. public KeyedCollection<Type, IEndpointBehavior> EndpointBehaviors
  48. {
  49. get { return this.Behaviors; }
  50. }
  51. [EditorBrowsable(EditorBrowsableState.Never)]
  52. public KeyedByTypeCollection<IEndpointBehavior> Behaviors
  53. {
  54. get
  55. {
  56. if (this.behaviors == null)
  57. {
  58. this.behaviors = new KeyedByTypeCollection<IEndpointBehavior>();
  59. }
  60. return this.behaviors;
  61. }
  62. }
  63. public Binding Binding
  64. {
  65. get { return this.binding; }
  66. set { this.binding = value; }
  67. }
  68. public ContractDescription Contract
  69. {
  70. get { return this.contract; }
  71. set
  72. {
  73. if (value == null)
  74. {
  75. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
  76. }
  77. this.contract = value;
  78. }
  79. }
  80. public bool IsSystemEndpoint
  81. {
  82. get;
  83. set;
  84. }
  85. public string Name
  86. {
  87. get
  88. {
  89. if (!XmlName.IsNullOrEmpty(name))
  90. {
  91. return name.EncodedName;
  92. }
  93. else if (binding != null)
  94. {
  95. // [....]: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
  96. return String.Format(CultureInfo.InvariantCulture, "{0}_{1}", new XmlName(Binding.Name).EncodedName, Contract.Name);
  97. }
  98. else
  99. {
  100. return Contract.Name;
  101. }
  102. }
  103. set
  104. {
  105. name = new XmlName(value, true /*isEncoded*/);
  106. }
  107. }
  108. public Uri ListenUri
  109. {
  110. get
  111. {
  112. if (this.listenUri == null)
  113. {
  114. if (this.address == null)
  115. {
  116. return null;
  117. }
  118. else
  119. {
  120. return this.address.Uri;
  121. }
  122. }
  123. else
  124. {
  125. return this.listenUri;
  126. }
  127. }
  128. set
  129. {
  130. if (value != null && !value.IsAbsoluteUri)
  131. {
  132. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("value", SR.GetString(SR.UriMustBeAbsolute));
  133. }
  134. this.listenUri = value;
  135. }
  136. }
  137. public ListenUriMode ListenUriMode
  138. {
  139. get { return this.listenUriMode; }
  140. set
  141. {
  142. if (!ListenUriModeHelper.IsDefined(value))
  143. {
  144. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
  145. }
  146. this.listenUriMode = value;
  147. }
  148. }
  149. internal string Id
  150. {
  151. get
  152. {
  153. if (id == null)
  154. id = Guid.NewGuid().ToString();
  155. return id;
  156. }
  157. }
  158. internal Uri UnresolvedAddress
  159. {
  160. get;
  161. set;
  162. }
  163. internal Uri UnresolvedListenUri
  164. {
  165. get;
  166. set;
  167. }
  168. // This method ensures that the description object graph is structurally sound and that none
  169. // of the fundamental SFx framework assumptions have been violated.
  170. internal void EnsureInvariants()
  171. {
  172. if (Binding == null)
  173. {
  174. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AChannelServiceEndpointSBindingIsNull0)));
  175. }
  176. if (Contract == null)
  177. {
  178. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.AChannelServiceEndpointSContractIsNull0)));
  179. }
  180. this.Contract.EnsureInvariants();
  181. this.Binding.EnsureInvariants(this.Contract.Name);
  182. }
  183. internal void ValidateForClient()
  184. {
  185. Validate(true, false);
  186. }
  187. internal void ValidateForService(bool runOperationValidators)
  188. {
  189. Validate(runOperationValidators, true);
  190. }
  191. internal bool IsFullyConfigured
  192. {
  193. get { return this.isEndpointFullyConfigured; }
  194. set { this.isEndpointFullyConfigured = value; }
  195. }
  196. // for V1 legacy reasons, a mex endpoint is considered a system endpoint even if IsSystemEndpoint = false
  197. internal bool InternalIsSystemEndpoint(ServiceDescription description)
  198. {
  199. if (ServiceMetadataBehavior.IsMetadataEndpoint(description, this))
  200. {
  201. return true;
  202. }
  203. return this.IsSystemEndpoint;
  204. }
  205. // This method runs validators (both builtin and ones in description).
  206. // Precondition: EnsureInvariants() should already have been called.
  207. void Validate(bool runOperationValidators, bool isForService)
  208. {
  209. // contract behaviors
  210. ContractDescription contract = this.Contract;
  211. for (int j = 0; j < contract.Behaviors.Count; j++)
  212. {
  213. IContractBehavior iContractBehavior = contract.Behaviors[j];
  214. iContractBehavior.Validate(contract, this);
  215. }
  216. // endpoint behaviors
  217. if (!isForService)
  218. {
  219. (PartialTrustValidationBehavior.Instance as IEndpointBehavior).Validate(this);
  220. #pragma warning disable 0618
  221. (PeerValidationBehavior.Instance as IEndpointBehavior).Validate(this);
  222. #pragma warning restore 0618
  223. (TransactionValidationBehavior.Instance as IEndpointBehavior).Validate(this);
  224. (SecurityValidationBehavior.Instance as IEndpointBehavior).Validate(this);
  225. (System.ServiceModel.MsmqIntegration.MsmqIntegrationValidationBehavior.Instance as IEndpointBehavior).Validate(this);
  226. }
  227. for (int j = 0; j < this.Behaviors.Count; j++)
  228. {
  229. IEndpointBehavior ieb = this.Behaviors[j];
  230. ieb.Validate(this);
  231. }
  232. // operation behaviors
  233. if (runOperationValidators)
  234. {
  235. for (int j = 0; j < contract.Operations.Count; j++)
  236. {
  237. OperationDescription op = contract.Operations[j];
  238. TaskOperationDescriptionValidator.Validate(op, isForService);
  239. for (int k = 0; k < op.Behaviors.Count; k++)
  240. {
  241. IOperationBehavior iob = op.Behaviors[k];
  242. iob.Validate(op);
  243. }
  244. }
  245. }
  246. }
  247. }
  248. }