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