ExtensionElementCollection.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //------------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------------------------
  4. namespace System.ServiceModel.Configuration
  5. {
  6. using System;
  7. using System.Configuration;
  8. [ConfigurationCollection(typeof(ExtensionElement), CollectionType = ConfigurationElementCollectionType.BasicMap)]
  9. public class ExtensionElementCollection : ServiceModelConfigurationElementCollection<ExtensionElement>
  10. {
  11. public ExtensionElementCollection()
  12. : base(ConfigurationElementCollectionType.BasicMap, ConfigurationStrings.Add)
  13. {
  14. }
  15. protected override void BaseAdd(ConfigurationElement element)
  16. {
  17. if (!this.InheritedElementExists((ExtensionElement)element))
  18. {
  19. this.EnforceUniqueElement((ExtensionElement)element);
  20. base.BaseAdd(element);
  21. }
  22. }
  23. protected override void BaseAdd(int index, ConfigurationElement element)
  24. {
  25. if (!this.InheritedElementExists((ExtensionElement)element))
  26. {
  27. this.EnforceUniqueElement((ExtensionElement)element);
  28. base.BaseAdd(index, element);
  29. }
  30. }
  31. protected override object GetElementKey(ConfigurationElement element)
  32. {
  33. if (null == element)
  34. {
  35. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
  36. }
  37. ExtensionElement configElementKey = (ExtensionElement)element;
  38. return configElementKey.Name;
  39. }
  40. bool InheritedElementExists(ExtensionElement element)
  41. {
  42. // This is logic from ServiceModelEnhancedConfigurationElementCollection
  43. // The idea is to allow duplicate identitcal extension definition in different level (i.e. app level and machine level)
  44. // We however do not allow them on the same level.
  45. // Identical extension is defined by same name and type.
  46. object newElementKey = this.GetElementKey(element);
  47. if (this.ContainsKey(newElementKey))
  48. {
  49. ExtensionElement oldElement = (ExtensionElement)this.BaseGet(newElementKey);
  50. if (null != oldElement)
  51. {
  52. // Is oldElement present in the different level of original config
  53. // and name/type matching
  54. if (!oldElement.ElementInformation.IsPresent &&
  55. element.Type.Equals(oldElement.Type, StringComparison.Ordinal))
  56. {
  57. return true;
  58. }
  59. }
  60. }
  61. return false;
  62. }
  63. void EnforceUniqueElement(ExtensionElement element)
  64. {
  65. foreach (ExtensionElement extension in this)
  66. {
  67. if (element.Name.Equals(extension.Name, StringComparison.Ordinal))
  68. {
  69. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
  70. SR.GetString(SR.ConfigDuplicateExtensionName, element.Name)));
  71. }
  72. bool foundDuplicateType = false;
  73. if (element.Type.Equals(extension.Type, StringComparison.OrdinalIgnoreCase))
  74. {
  75. foundDuplicateType = true;
  76. }
  77. else if (element.TypeName.Equals(extension.TypeName, StringComparison.Ordinal))
  78. {
  79. // In order to avoid extra assemblies being loaded, we perform type comparison only if the type names
  80. // are the same. See bug CSDMain 222573.
  81. Type elementType = Type.GetType(element.Type, false);
  82. if (null != elementType && elementType.Equals(Type.GetType(extension.Type, false)))
  83. {
  84. foundDuplicateType = true;
  85. }
  86. }
  87. if (foundDuplicateType)
  88. {
  89. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
  90. SR.GetString(SR.ConfigDuplicateExtensionType, element.Type)));
  91. }
  92. }
  93. }
  94. protected override bool ThrowOnDuplicate
  95. {
  96. get
  97. {
  98. return true;
  99. }
  100. }
  101. }
  102. }