| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Collections; |
| | | 6 | | using System.Collections.Generic; |
| | | 7 | | using System.Configuration; |
| | | 8 | | using System.Security; |
| | | 9 | | using System.Xml; |
| | | 10 | | |
| | | 11 | | namespace CoreWCF.Configuration |
| | | 12 | | { |
| | | 13 | | public abstract class ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> : ServiceModelConfigurat |
| | | 14 | | where TServiceModelExtensionElement : ServiceModelExtensionElement |
| | | 15 | | { |
| | | 16 | | private readonly string _extensionCollectionName; |
| | | 17 | | private bool _modified; |
| | | 18 | | private List<TServiceModelExtensionElement> _items; |
| | | 19 | | |
| | 20 | 20 | | internal ServiceModelExtensionCollectionElement(string extensionCollectionName) |
| | | 21 | | { |
| | 20 | 22 | | _extensionCollectionName = extensionCollectionName; |
| | 20 | 23 | | } |
| | | 24 | | |
| | | 25 | | public TServiceModelExtensionElement this[int index] |
| | | 26 | | { |
| | 0 | 27 | | get { return Items[index]; } |
| | | 28 | | } |
| | | 29 | | |
| | | 30 | | public TServiceModelExtensionElement this[Type extensionType] |
| | | 31 | | { |
| | | 32 | | get |
| | | 33 | | { |
| | 34 | 34 | | if (extensionType == null) |
| | | 35 | | { |
| | 0 | 36 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(extensionType)); |
| | | 37 | | } |
| | | 38 | | |
| | 34 | 39 | | if (!CollectionElementBaseType.IsAssignableFrom(extensionType)) |
| | | 40 | | { |
| | 0 | 41 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("extensionType", |
| | 0 | 42 | | SR.Format(SR.ConfigInvalidExtensionType, |
| | 0 | 43 | | extensionType.ToString(), |
| | 0 | 44 | | CollectionElementBaseType.FullName, |
| | 0 | 45 | | _extensionCollectionName)); |
| | | 46 | | |
| | | 47 | | } |
| | 34 | 48 | | TServiceModelExtensionElement retval = null; |
| | | 49 | | |
| | 68 | 50 | | foreach (TServiceModelExtensionElement collectionElement in this) |
| | | 51 | | { |
| | 0 | 52 | | if (null != collectionElement) |
| | | 53 | | { |
| | 0 | 54 | | if (collectionElement.GetType() == extensionType) |
| | | 55 | | { |
| | 0 | 56 | | retval = collectionElement; |
| | | 57 | | } |
| | | 58 | | } |
| | | 59 | | } |
| | | 60 | | |
| | 34 | 61 | | return retval; |
| | | 62 | | } |
| | | 63 | | } |
| | | 64 | | |
| | | 65 | | public int Count |
| | | 66 | | { |
| | 0 | 67 | | get { return Items.Count; } |
| | | 68 | | } |
| | | 69 | | |
| | | 70 | | bool ICollection<TServiceModelExtensionElement>.IsReadOnly |
| | | 71 | | { |
| | 0 | 72 | | get { return IsReadOnly(); } |
| | | 73 | | } |
| | | 74 | | |
| | | 75 | | internal List<TServiceModelExtensionElement> Items |
| | | 76 | | { |
| | | 77 | | get |
| | | 78 | | { |
| | 185 | 79 | | if (_items == null) |
| | | 80 | | { |
| | 20 | 81 | | _items = new List<TServiceModelExtensionElement>(); |
| | | 82 | | } |
| | 185 | 83 | | return _items; |
| | | 84 | | } |
| | | 85 | | } |
| | | 86 | | |
| | | 87 | | public virtual void Add(TServiceModelExtensionElement element) |
| | | 88 | | { |
| | 17 | 89 | | if (IsReadOnly()) |
| | | 90 | | { |
| | 0 | 91 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR. |
| | | 92 | | } |
| | 17 | 93 | | if (element == null) |
| | | 94 | | { |
| | 0 | 95 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element)); |
| | | 96 | | } |
| | | 97 | | |
| | 17 | 98 | | element.ExtensionCollectionName = _extensionCollectionName; |
| | | 99 | | |
| | 17 | 100 | | if (Contains(element)) |
| | | 101 | | { |
| | 0 | 102 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("element", SR.Format(SR.ConfigDuplicateKey, |
| | | 103 | | } |
| | 17 | 104 | | else if (!CanAdd(element)) |
| | | 105 | | { |
| | 0 | 106 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("element", |
| | 0 | 107 | | SR.Format(SR.ConfigElementTypeNotAllowed, |
| | 0 | 108 | | element.ConfigurationElementName, |
| | 0 | 109 | | _extensionCollectionName)); |
| | | 110 | | } |
| | | 111 | | else |
| | | 112 | | { |
| | 17 | 113 | | ConfigurationProperty configProperty = new ConfigurationProperty(element.ConfigurationElementName, eleme |
| | 17 | 114 | | Properties.Add(configProperty); |
| | 17 | 115 | | this[configProperty] = element; |
| | 17 | 116 | | Items.Add(element); |
| | 17 | 117 | | _modified = true; |
| | | 118 | | } |
| | 17 | 119 | | } |
| | | 120 | | |
| | | 121 | | internal void AddItem(TServiceModelExtensionElement element) |
| | | 122 | | { |
| | 0 | 123 | | if (IsReadOnly()) |
| | | 124 | | { |
| | 0 | 125 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR. |
| | | 126 | | } |
| | 0 | 127 | | element.ExtensionCollectionName = _extensionCollectionName; |
| | 0 | 128 | | Items.Add(element); |
| | 0 | 129 | | _modified = true; |
| | 0 | 130 | | } |
| | | 131 | | |
| | | 132 | | public virtual bool CanAdd(TServiceModelExtensionElement element) |
| | | 133 | | { |
| | 0 | 134 | | if (element == null) |
| | | 135 | | { |
| | 0 | 136 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element)); |
| | | 137 | | } |
| | | 138 | | |
| | 0 | 139 | | Type elementType = element.GetType(); |
| | | 140 | | |
| | 0 | 141 | | return !IsReadOnly() && !ContainsKey(elementType); |
| | | 142 | | } |
| | | 143 | | |
| | | 144 | | public void Clear() |
| | | 145 | | { |
| | 0 | 146 | | if (IsReadOnly()) |
| | | 147 | | { |
| | 0 | 148 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR. |
| | | 149 | | } |
| | 0 | 150 | | if (Properties.Count > 0) |
| | | 151 | | { |
| | 0 | 152 | | _modified = true; |
| | | 153 | | } |
| | | 154 | | |
| | 0 | 155 | | List<string> propertiesToRemove = new List<string>(Items.Count); |
| | 0 | 156 | | foreach (TServiceModelExtensionElement item in Items) |
| | | 157 | | { |
| | 0 | 158 | | propertiesToRemove.Add(item.ConfigurationElementName); |
| | | 159 | | } |
| | | 160 | | |
| | 0 | 161 | | Items.Clear(); |
| | | 162 | | |
| | 0 | 163 | | foreach (string name in propertiesToRemove) |
| | | 164 | | { |
| | 0 | 165 | | Properties.Remove(name); |
| | | 166 | | } |
| | 0 | 167 | | } |
| | | 168 | | |
| | | 169 | | internal Type CollectionElementBaseType |
| | | 170 | | { |
| | 51 | 171 | | get { return typeof(TServiceModelExtensionElement); } |
| | | 172 | | } |
| | | 173 | | |
| | | 174 | | public bool Contains(TServiceModelExtensionElement element) |
| | | 175 | | { |
| | 17 | 176 | | if (element == null) |
| | | 177 | | { |
| | 0 | 178 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element)); |
| | | 179 | | } |
| | 17 | 180 | | return ContainsKey(element.GetType()); |
| | | 181 | | } |
| | | 182 | | |
| | | 183 | | public bool ContainsKey(Type elementType) |
| | | 184 | | { |
| | 34 | 185 | | if (elementType == null) |
| | | 186 | | { |
| | 0 | 187 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elementType)); |
| | | 188 | | } |
| | 34 | 189 | | return (this[elementType] != null); |
| | | 190 | | } |
| | | 191 | | |
| | | 192 | | public bool ContainsKey(string elementName) |
| | | 193 | | { |
| | 17 | 194 | | if (string.IsNullOrEmpty(elementName)) |
| | | 195 | | { |
| | 0 | 196 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elementName)); |
| | | 197 | | } |
| | 17 | 198 | | bool retval = false; |
| | 34 | 199 | | foreach (TServiceModelExtensionElement element in this) |
| | | 200 | | { |
| | 0 | 201 | | if (null != element) |
| | | 202 | | { |
| | 0 | 203 | | string configuredSectionName = element.ConfigurationElementName; |
| | 0 | 204 | | if (configuredSectionName.Equals(elementName, StringComparison.Ordinal)) |
| | | 205 | | { |
| | 0 | 206 | | retval = true; |
| | 0 | 207 | | break; |
| | | 208 | | } |
| | | 209 | | } |
| | | 210 | | } |
| | 17 | 211 | | return retval; |
| | | 212 | | } |
| | | 213 | | |
| | | 214 | | public void CopyTo(TServiceModelExtensionElement[] elements, int start) |
| | | 215 | | { |
| | 0 | 216 | | if (elements == null) |
| | | 217 | | { |
| | 0 | 218 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elements)); |
| | | 219 | | } |
| | 0 | 220 | | if (start < 0 || start >= elements.Length) |
| | | 221 | | { |
| | 0 | 222 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("start", |
| | 0 | 223 | | SR.Format(SR.ConfigInvalidStartValue, |
| | 0 | 224 | | elements.Length - 1, |
| | 0 | 225 | | start)); |
| | | 226 | | } |
| | | 227 | | |
| | 0 | 228 | | foreach (TServiceModelExtensionElement element in this) |
| | | 229 | | { |
| | 0 | 230 | | if (null != element) |
| | | 231 | | { |
| | 0 | 232 | | string configuredSectionName = element.ConfigurationElementName; |
| | | 233 | | |
| | 0 | 234 | | TServiceModelExtensionElement copiedElement = CreateNewSection(configuredSectionName); |
| | 0 | 235 | | if ((copiedElement != null) && (start < elements.Length)) |
| | | 236 | | { |
| | 0 | 237 | | copiedElement.CopyFrom(element); |
| | 0 | 238 | | elements[start] = copiedElement; |
| | 0 | 239 | | ++start; |
| | | 240 | | } |
| | | 241 | | } |
| | | 242 | | } |
| | 0 | 243 | | } |
| | | 244 | | |
| | | 245 | | /// <summary> |
| | | 246 | | /// Returns the extension element, or null if the type cannot be loaded in certain situations (see the code for |
| | | 247 | | /// </summary> |
| | | 248 | | private TServiceModelExtensionElement CreateNewSection(string name) |
| | | 249 | | { |
| | 17 | 250 | | if (ContainsKey(name) && !(name == ConfigurationStrings.Clear || name == ConfigurationStrings.Remove)) |
| | | 251 | | { |
| | 0 | 252 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR. |
| | 0 | 253 | | name, |
| | 0 | 254 | | GetType().Name), |
| | 0 | 255 | | ElementInformation.Source, |
| | 0 | 256 | | ElementInformation.LineNumber)); |
| | | 257 | | } |
| | | 258 | | |
| | | 259 | | TServiceModelExtensionElement retval; |
| | | 260 | | |
| | | 261 | | Type elementType; |
| | 17 | 262 | | ContextInformation evaluationContext = EvaluationContext; |
| | | 263 | | |
| | 17 | 264 | | elementType = GetExtensionType(evaluationContext, name); |
| | | 265 | | |
| | | 266 | | |
| | 17 | 267 | | if (null != elementType) |
| | | 268 | | { |
| | 17 | 269 | | if (CollectionElementBaseType.IsAssignableFrom(elementType)) |
| | | 270 | | { |
| | 17 | 271 | | retval = (TServiceModelExtensionElement)Activator.CreateInstance(elementType); |
| | 17 | 272 | | retval.ExtensionCollectionName = _extensionCollectionName; |
| | 17 | 273 | | retval.ConfigurationElementName = name; |
| | 17 | 274 | | retval.InternalInitializeDefault(); |
| | | 275 | | } |
| | | 276 | | else |
| | | 277 | | { |
| | 0 | 278 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format |
| | 0 | 279 | | name, |
| | 0 | 280 | | CollectionElementBaseType.FullName), |
| | 0 | 281 | | ElementInformation.Source, |
| | 0 | 282 | | ElementInformation.LineNumber)); |
| | | 283 | | } |
| | | 284 | | } |
| | | 285 | | else |
| | | 286 | | { |
| | 0 | 287 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR. |
| | 0 | 288 | | name, |
| | 0 | 289 | | _extensionCollectionName), |
| | 0 | 290 | | ElementInformation.Source, |
| | 0 | 291 | | ElementInformation.LineNumber)); |
| | | 292 | | } |
| | | 293 | | |
| | 17 | 294 | | return retval; |
| | | 295 | | } |
| | | 296 | | |
| | | 297 | | |
| | | 298 | | private Type GetExtensionType(ContextInformation evaluationContext, string name) |
| | | 299 | | { |
| | 17 | 300 | | ExtensionElementCollection collection = ExtensionsSection.LookupCollection(_extensionCollectionName, evaluat |
| | 17 | 301 | | if (collection.ContainsKey(name)) |
| | | 302 | | { |
| | 17 | 303 | | ExtensionElement element = collection.GetElementExtension(name); |
| | 17 | 304 | | Type elementType = Type.GetType(element.Type, false); |
| | 17 | 305 | | if (null == elementType) |
| | | 306 | | { |
| | 0 | 307 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format |
| | 0 | 308 | | ElementInformation.Source, |
| | 0 | 309 | | ElementInformation.LineNumber)); |
| | | 310 | | } |
| | 17 | 311 | | return elementType; |
| | | 312 | | } |
| | 0 | 313 | | return null; |
| | | 314 | | } |
| | | 315 | | |
| | | 316 | | internal void MergeWith(List<TServiceModelExtensionElement> parentExtensionElements) |
| | | 317 | | { |
| | 0 | 318 | | Merge(parentExtensionElements, this); |
| | 0 | 319 | | Clear(); |
| | 0 | 320 | | foreach (TServiceModelExtensionElement parentExtensionElement in parentExtensionElements) |
| | | 321 | | { |
| | 0 | 322 | | Add(parentExtensionElement); |
| | | 323 | | } |
| | 0 | 324 | | } |
| | | 325 | | |
| | | 326 | | private static void Merge(List<TServiceModelExtensionElement> parentExtensionElements, IEnumerable<TServiceModel |
| | | 327 | | { |
| | 0 | 328 | | foreach (TServiceModelExtensionElement childExtensionElement in childExtensionElements) |
| | | 329 | | { |
| | 0 | 330 | | Type childExtensionElementType = childExtensionElement.GetType(); |
| | 0 | 331 | | parentExtensionElements.RemoveAll(element => |
| | 0 | 332 | | element != null && element.GetType() == childExtensionElementType); |
| | 0 | 333 | | parentExtensionElements.Add(childExtensionElement); |
| | | 334 | | } |
| | 0 | 335 | | } |
| | | 336 | | |
| | | 337 | | |
| | | 338 | | protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey) |
| | | 339 | | { |
| | 20 | 340 | | DeserializeElementCore(reader); |
| | 20 | 341 | | } |
| | | 342 | | |
| | | 343 | | private void DeserializeElementCore(XmlReader reader) |
| | | 344 | | { |
| | 20 | 345 | | if (reader.HasAttributes && 0 < reader.AttributeCount) |
| | | 346 | | { |
| | 44 | 347 | | while (reader.MoveToNextAttribute()) |
| | | 348 | | { |
| | 24 | 349 | | if (Properties.Contains(reader.Name)) |
| | | 350 | | { |
| | 24 | 351 | | this[reader.Name] = Properties[reader.Name].Converter.ConvertFromString(reader.Value); |
| | | 352 | | } |
| | | 353 | | else |
| | | 354 | | { |
| | 0 | 355 | | OnDeserializeUnrecognizedAttribute(reader.Name, reader.Value); |
| | | 356 | | } |
| | | 357 | | } |
| | | 358 | | } |
| | | 359 | | |
| | 20 | 360 | | if (XmlNodeType.Element != reader.NodeType) |
| | | 361 | | { |
| | 20 | 362 | | reader.MoveToElement(); |
| | | 363 | | } |
| | | 364 | | |
| | 20 | 365 | | XmlReader subTree = reader.ReadSubtree(); |
| | 20 | 366 | | if (subTree.Read()) |
| | | 367 | | { |
| | 94 | 368 | | while (subTree.Read()) |
| | | 369 | | { |
| | 74 | 370 | | if (XmlNodeType.Element == subTree.NodeType) |
| | | 371 | | { |
| | | 372 | | // Create new child element and add it to the property collection to |
| | | 373 | | // associate the element with an EvaluationContext. Then deserialize |
| | | 374 | | // XML further to set actual values. |
| | 17 | 375 | | TServiceModelExtensionElement collectionElement = CreateNewSection(subTree.Name); |
| | 17 | 376 | | if (collectionElement != null) |
| | | 377 | | { |
| | 17 | 378 | | Add(collectionElement); |
| | 17 | 379 | | collectionElement.DeserializeInternal(subTree, false); |
| | | 380 | | } |
| | | 381 | | } |
| | | 382 | | } |
| | | 383 | | } |
| | 20 | 384 | | } |
| | | 385 | | |
| | | 386 | | public IEnumerator<TServiceModelExtensionElement> GetEnumerator() |
| | | 387 | | { |
| | 228 | 388 | | for (int index = 0; index < Items.Count; ++index) |
| | | 389 | | { |
| | 17 | 390 | | TServiceModelExtensionElement currentValue = _items[index]; |
| | 17 | 391 | | yield return currentValue; |
| | | 392 | | } |
| | 97 | 393 | | } |
| | | 394 | | |
| | | 395 | | protected override bool IsModified() |
| | | 396 | | { |
| | 0 | 397 | | bool retval = _modified; |
| | 0 | 398 | | if (!retval) |
| | | 399 | | { |
| | 0 | 400 | | for (int i = 0; i < Items.Count; i++) |
| | | 401 | | { |
| | 0 | 402 | | TServiceModelExtensionElement element = Items[i]; |
| | 0 | 403 | | if (element.IsModifiedInternal()) |
| | | 404 | | { |
| | 0 | 405 | | retval = true; |
| | 0 | 406 | | break; |
| | | 407 | | } |
| | | 408 | | } |
| | | 409 | | } |
| | 0 | 410 | | return retval; |
| | | 411 | | } |
| | | 412 | | |
| | | 413 | | protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader) |
| | | 414 | | { |
| | | 415 | | // When this is used as a DefaultCollection (i.e. CommonBehaviors) |
| | | 416 | | // the element names are unrecognized by the parent tag, which delegates |
| | | 417 | | // to the collection's OnDeserializeUnrecognizedElement. In this case, |
| | | 418 | | // an unrecognized element may be expected, simply try to deserialize the |
| | | 419 | | // element and let DeserializeElement() throw the appropriate exception if |
| | | 420 | | // an error is hit. |
| | 0 | 421 | | DeserializeElement(reader, false); |
| | 0 | 422 | | return true; |
| | | 423 | | } |
| | | 424 | | |
| | | 425 | | public bool Remove(TServiceModelExtensionElement element) |
| | | 426 | | { |
| | 0 | 427 | | if (element == null) |
| | | 428 | | { |
| | 0 | 429 | | throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element)); |
| | | 430 | | } |
| | 0 | 431 | | bool retval = false; |
| | 0 | 432 | | if (Contains(element)) |
| | | 433 | | { |
| | 0 | 434 | | string configuredSectionName = element.ConfigurationElementName; |
| | | 435 | | |
| | 0 | 436 | | TServiceModelExtensionElement existingElement = this[element.GetType()]; |
| | 0 | 437 | | Items.Remove(existingElement); |
| | 0 | 438 | | Properties.Remove(configuredSectionName); |
| | 0 | 439 | | _modified = true; |
| | 0 | 440 | | retval = true; |
| | | 441 | | } |
| | 0 | 442 | | return retval; |
| | | 443 | | } |
| | | 444 | | |
| | | 445 | | protected override void Reset(ConfigurationElement parentElement) |
| | | 446 | | { |
| | 0 | 447 | | ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> collection = |
| | 0 | 448 | | (ServiceModelExtensionCollectionElement<TServiceModelExtensionElement>)parentElement; |
| | 0 | 449 | | foreach (TServiceModelExtensionElement collectionElement in collection.Items) |
| | | 450 | | { |
| | 0 | 451 | | Items.Add(collectionElement); |
| | | 452 | | } |
| | | 453 | | // Update my properties |
| | 0 | 454 | | UpdateProperties(collection); |
| | | 455 | | |
| | 0 | 456 | | base.Reset(parentElement); |
| | 0 | 457 | | } |
| | | 458 | | |
| | | 459 | | protected override void ResetModified() |
| | | 460 | | { |
| | 74 | 461 | | for (int i = 0; i < Items.Count; i++) |
| | | 462 | | { |
| | 17 | 463 | | TServiceModelExtensionElement collectionElement = Items[i]; |
| | 17 | 464 | | collectionElement.ResetModifiedInternal(); |
| | | 465 | | } |
| | 20 | 466 | | _modified = false; |
| | 20 | 467 | | } |
| | | 468 | | |
| | | 469 | | protected void SetIsModified() |
| | | 470 | | { |
| | 0 | 471 | | _modified = true; |
| | 0 | 472 | | } |
| | | 473 | | |
| | | 474 | | protected override void SetReadOnly() |
| | | 475 | | { |
| | 0 | 476 | | base.SetReadOnly(); |
| | | 477 | | |
| | 0 | 478 | | for (int i = 0; i < Items.Count; i++) |
| | | 479 | | { |
| | 0 | 480 | | TServiceModelExtensionElement element = Items[i]; |
| | 0 | 481 | | element.SetReadOnlyInternal(); |
| | | 482 | | } |
| | 0 | 483 | | } |
| | | 484 | | |
| | | 485 | | IEnumerator IEnumerable.GetEnumerator() |
| | | 486 | | { |
| | 0 | 487 | | return GetEnumerator(); |
| | | 488 | | } |
| | | 489 | | |
| | | 490 | | protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, Configur |
| | | 491 | | { |
| | 0 | 492 | | if (sourceElement == null) |
| | | 493 | | { |
| | 0 | 494 | | return; |
| | | 495 | | } |
| | | 496 | | |
| | 0 | 497 | | ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> sourceCollectionElement = (ServiceMode |
| | | 498 | | |
| | 0 | 499 | | UpdateProperties(sourceCollectionElement); |
| | 0 | 500 | | base.Unmerge(sourceElement, parentElement, saveMode); |
| | 0 | 501 | | } |
| | | 502 | | |
| | | 503 | | private void UpdateProperties(ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> sourceElemen |
| | | 504 | | { |
| | 0 | 505 | | foreach (ConfigurationProperty property in sourceElement.Properties) |
| | | 506 | | { |
| | 0 | 507 | | if (!Properties.Contains(property.Name)) |
| | | 508 | | { |
| | 0 | 509 | | Properties.Add(property); |
| | | 510 | | } |
| | | 511 | | } |
| | | 512 | | |
| | 0 | 513 | | foreach (TServiceModelExtensionElement extension in Items) |
| | | 514 | | { |
| | 0 | 515 | | string configuredSectionName = extension.ConfigurationElementName; |
| | 0 | 516 | | if (!Properties.Contains(configuredSectionName)) |
| | | 517 | | { |
| | 0 | 518 | | ConfigurationProperty configProperty = new ConfigurationProperty(configuredSectionName, extension.Ge |
| | 0 | 519 | | Properties.Add(configProperty); |
| | | 520 | | } |
| | | 521 | | } |
| | 0 | 522 | | } |
| | | 523 | | } |
| | | 524 | | } |