|
//------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
namespace System.ServiceModel.Configuration
{
using System;
using System.Configuration;
[ConfigurationCollection(typeof(ExtensionElement), CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class ExtensionElementCollection : ServiceModelConfigurationElementCollection<ExtensionElement>
{
public ExtensionElementCollection()
: base(ConfigurationElementCollectionType.BasicMap, ConfigurationStrings.Add)
{
}
protected override void BaseAdd(ConfigurationElement element)
{
if (!this.InheritedElementExists((ExtensionElement)element))
{
this.EnforceUniqueElement((ExtensionElement)element);
base.BaseAdd(element);
}
}
protected override void BaseAdd(int index, ConfigurationElement element)
{
if (!this.InheritedElementExists((ExtensionElement)element))
{
this.EnforceUniqueElement((ExtensionElement)element);
base.BaseAdd(index, element);
}
}
protected override object GetElementKey(ConfigurationElement element)
{
if (null == element)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("element");
}
ExtensionElement configElementKey = (ExtensionElement)element;
return configElementKey.Name;
}
bool InheritedElementExists(ExtensionElement element)
{
// This is logic from ServiceModelEnhancedConfigurationElementCollection
// The idea is to allow duplicate identitcal extension definition in different level (i.e. app level and machine level)
// We however do not allow them on the same level.
// Identical extension is defined by same name and type.
object newElementKey = this.GetElementKey(element);
if (this.ContainsKey(newElementKey))
{
ExtensionElement oldElement = (ExtensionElement)this.BaseGet(newElementKey);
if (null != oldElement)
{
// Is oldElement present in the different level of original config
// and name/type matching
if (!oldElement.ElementInformation.IsPresent &&
element.Type.Equals(oldElement.Type, StringComparison.Ordinal))
{
return true;
}
}
}
return false;
}
void EnforceUniqueElement(ExtensionElement element)
{
foreach (ExtensionElement extension in this)
{
if (element.Name.Equals(extension.Name, StringComparison.Ordinal))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
SR.GetString(SR.ConfigDuplicateExtensionName, element.Name)));
}
bool foundDuplicateType = false;
if (element.Type.Equals(extension.Type, StringComparison.OrdinalIgnoreCase))
{
foundDuplicateType = true;
}
else if (element.TypeName.Equals(extension.TypeName, StringComparison.Ordinal))
{
// In order to avoid extra assemblies being loaded, we perform type comparison only if the type names
// are the same. See bug CSDMain 222573.
Type elementType = Type.GetType(element.Type, false);
if (null != elementType && elementType.Equals(Type.GetType(extension.Type, false)))
{
foundDuplicateType = true;
}
}
if (foundDuplicateType)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(
SR.GetString(SR.ConfigDuplicateExtensionType, element.Type)));
}
}
}
protected override bool ThrowOnDuplicate
{
get
{
return true;
}
}
}
}
|