Suppose you have a class hierarchy like the following:
public abstract class MyBaseClass
{
[DataMember]
public int id { get; set; }
}
public class DerivedType : MyBaseClass
{
[DataMember]
public string Name { get; set; }
public string Name { get; set; }
}
Now in your WCF service definition, your code should like this:
[ServiceContract]
interface MyService
{
[OperationContract]
[ServiceKnownType(typeof(DerivedType)]
void HelloWorld(MyBaseClass param1);
[ServiceKnownType(typeof(DerivedType)]
void HelloWorld(MyBaseClass param1);
}
This obviously creates a problem that anytime you add a new derived type; you need to add it to the ServiceKnownType attribute so that the WCF serializer recognizes the new types.
To solve this problem and allow the newly created derived types to be dynamically serialized without the need to modify the service definition code, you need to do the following:
Create a method that returns a list of the derived types as follows:
public static class TypesHelper
{
public static IEnumerable GetKnownTypes(ICustomAttributeProvider provider)
{
{
Assembly assembly = Assembly.GetAssembly(typeof(MyBaseClass));
List<Type> types = assembly.GetExportedTypes().Where(e => e.BaseType != null && e.BaseType.BaseType == typeof(MyBaseClass)).ToList();
List<Type> types = assembly.GetExportedTypes().Where(e => e.BaseType != null && e.BaseType.BaseType == typeof(MyBaseClass)).ToList();
return types;
}
}
Now add a call to the above created method in the ServiceKnownType attribute as follows:
[OperationContract]
[ServiceKnownType("GetKnownTypes", typeof(TypesHelper))]
void HelloWorld(MyBaseClass param1);
This way, we are benefiting from the ability to use our own method that dynamically supplies the derived types to the WCF serializer.