I\'m trying to specify a known type in my config, but I\'m having problems with the fact that it derives from Object. I can make it work specifying the known type via attrib
I'm not sure if it is by design, but the KnownTypeHelper below won't throw an error if you've not declared a service contract with known types. (i.e. its optional to add known types to service contracts).
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;
///
/// Helper for finding the known types for Wcf Services from a configuration file.
///
public static class KnownTypeHelper
{
///
/// Gets the known types for the service from a configuration file.
///
///
/// The provider.
///
///
/// The known types for the service from a configuration file.
///
public static IEnumerable GetServiceKnownTypes(ICustomAttributeProvider provider)
{
var result = new List();
var serviceKnownTypes = (ServiceKnownTypesSection)ConfigurationManager.GetSection("serviceKnownTypes");
if (serviceKnownTypes != null)
{
var service = serviceKnownTypes.Services[((Type)provider).AssemblyQualifiedName];
if (service != null)
{
foreach (ServiceKnownTypeElement knownType in service.KnownTypes)
{
result.Add(knownType.Type);
}
}
}
return result;
}
}
To save someone else the trouble of creating the configuration classes,
Note: There is no validation of the assembly qualified type names. If someone wants to add the appropiate attributes to do this, please do.
using System.Configuration;
///
/// Section for configuration known types for services.
///
public class ServiceKnownTypesSection : ConfigurationSection
{
///
/// Gets services.
///
[ConfigurationProperty("declaredServices", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "serviceContract", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
public DeclaredServiceElementCollection Services
{
get
{
return (DeclaredServiceElementCollection)base["declaredServices"];
}
}
}
///
/// Collection of declared service elements.
///
public class DeclaredServiceElementCollection : ConfigurationElementCollection
{
///
/// Gets the service for which known types have been declared for.
///
///
/// The key of the service.
///
public new DeclaredServiceElement this[string key]
{
get
{
return (DeclaredServiceElement)BaseGet(key);
}
set
{
var element = BaseGet(key);
var index = this.BaseIndexOf(element);
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
///
/// When overridden in a derived class, creates a new .
///
///
/// A new .
///
protected override ConfigurationElement CreateNewElement()
{
return new DeclaredServiceElement();
}
///
/// Gets the element key for a specified configuration element when overridden in a derived class.
///
///
/// An that acts as the key for the specified .
///
///
/// The to return the key for.
///
protected override object GetElementKey(ConfigurationElement element)
{
return ((DeclaredServiceElement)element).Type;
}
}
///
/// The service for which known types are being declared for.
///
public class DeclaredServiceElement : ConfigurationElement
{
///
/// Gets or sets Type.
///
[ConfigurationProperty("type", IsRequired = true, IsKey = true)]
public string Type
{
get
{
return (string) this["type"];
}
set
{
this["type"] = value;
}
}
///
/// Gets KnownTypes.
///
[ConfigurationProperty("knownTypes", IsDefaultCollection = false)]
[ConfigurationCollection(typeof(DeclaredServiceElement), AddItemName = "knownType", CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
public ServiceKnownTypeElementCollection KnownTypes
{
get
{
return (ServiceKnownTypeElementCollection)base["knownTypes"];
}
}
}
///
/// A collection of known type elements.
///
public class ServiceKnownTypeElementCollection : ConfigurationElementCollection
{
///
/// Gets an known type with the specified key.
///
///
/// The key of the known type.
///
public new ServiceKnownTypeElement this[string key]
{
get
{
return (ServiceKnownTypeElement)BaseGet(key);
}
set
{
var element = BaseGet(key);
var index = this.BaseIndexOf(element);
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
///
/// When overridden in a derived class, creates a new .
///
///
/// A new .
///
protected override ConfigurationElement CreateNewElement()
{
return new ServiceKnownTypeElement();
}
///
/// Gets the element key for a specified configuration element when overridden in a derived class.
///
///
/// An that acts as the key for the specified .
///
///
/// The to return the key for.
///
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServiceKnownTypeElement)element).Type;
}
}
///
/// Configuration element for a known type to associate with a service.
///
public class ServiceKnownTypeElement : ConfigurationElement
{
///
/// Gets or sets TypeString.
///
[ConfigurationProperty("type", IsRequired = true, IsKey = true)]
public string TypeString
{
get
{
return (string)this["type"];
}
set
{
this["type"] = value;
}
}
///
/// Gets or sets Type.
///
public Type Type
{
get
{
return Type.GetType(this.TypeString);
}
set
{
this["type"] = value.AssemblyQualifiedName;
}
}
}