Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KnownType for all derived types of an abstract class?

We have an abstract class that is the base for a number of different requests we send over a WCF service. It's an ugly heinous hack that every time we add a new request we have to remember to add the [KnownType] attribute to this base class.

Is there a way to tell the DataContractSerializer to treat ALL derivations of this abstract type as a KnownType?

like image 569
Joe Avatar asked Jun 07 '11 14:06

Joe


People also ask

What is the KnownType attribute in WCF?

The [KnownType] attribute informs the WCF service that "it is ok" to receive this Admin type because it is a subclass of the awaited UserAccount type. It is especially important when the Admin subclass has more properties, like a public string AdminEmail { get;set; } . This property will be sent by the client too.

Can you derive abstract classes from an abstract class?

Yes, You can inherit an abstract class from another abstract class.

What is used if you expect the service to accept and return inherited types?

If you expect the service to accept and return an inherited type then we use the knowntype attribute.


2 Answers

I had the same problem in a WCF service and did the following "less heinous" hack to work around the known type limitation. I'm outlining just for the sake of showing alternate options, it's up to you to decide if it's better or not.

  1. At service startup, load via reflection the types you want to expose. E.g. if all your WCF-exposed entities derive from a common abstract base (or more), load all types from the assembly they're supposed to be located into. Cache these types statically for performance reasons.

  2. Create a static method that returns the said cached types, with the following signature: public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)

  3. Mark the WCF interface with the following attribute [ServiceKnownType("GetKnownTypes", typeof(StaticClassThatCachesTypes))]

This should give you automatic exposing of all types that are or will be derived from the base class(es) of your choice, as long as the future developer(s) place them in the correct assembly.

like image 82
Dan C. Avatar answered Sep 23 '22 03:09

Dan C.


Another option in addition to the one given by Dan C. is to switch to the NetDataContractSerializer - it does not require known type declarations, since it is tightly coupled to the exact contract implementation, so you'll need to share the assembly which contains the types between the client and the server - and you'll definitely lose interoperability in this scenario. There are a few posts about doing that (I've seen this one pop up in google/bing results often).

like image 36
carlosfigueira Avatar answered Sep 24 '22 03:09

carlosfigueira