Relearning WCF

Of late I have been playing with WCF again. We have some projects here at work that require some integration and we are desperately trying to move away from the old ASMX based services. Unfortunately because I have not touched WCF the whole time I have been here (12 months now, wow! That has gone fast!) and I have found myself at a point where I really need to relook at WCF again and basically relearn it… oh well.
Anyway here is a bunch of stuff that here, that at work we have found to be useful that you may not otherwise be able to do with ASMX or may not be aware you could do with WCF.

IOC and WCF

You can in fact use IoC with WCF, there are some good blog posts and accompanying videos to show what to do and if, like me, you just want one ready to that uses the CSL then The Code Junkie has done it for you!

Dynamic KnownType Resolution

This always erked me that I had to put into the data contract that I knew of other types, it was like really bad tight coupling*. There are a bunch of way to declare known types with the bottom example seeemingly a little known alternative : a provider mechanism

in config

Data contract with attributes


[KnownType(typeof(PurchaseApprovalRequest))]
[DataContract]
public class ApprovalRequest
{...

Knowntype provider

The way I have just found out is by declaring a knowntype provider on the service contract:

[ServiceKnownType("GetKnownTypes", typeof(ApprovalRequestKnownTypesProvider))]
[ServiceContract]
public interface IApprovalService
{...

with the following class (change the implementation to suit yourself, this is from some of my demo code, it’s not recommended!)

internal static class ApprovalRequestKnownTypesProvider
{
public static IEnumerable GetKnownTypes(ICustomAttributeProvider provider)
{
// collect and pass back the list of known types
foreach (var module in Assembly.GetExecutingAssembly().GetLoadedModules())
{
foreach (var knownType in module.FindTypes(
(t, f) => ((Type)f).IsAssignableFrom(t), typeof(ApprovalRequest)))
{
yield return knownType;
}
}
}
}

With these two little nuggets I have been able to produce a pretty handy little broker service that act as a very basic content based router that keeps the client messages very clean and does not expose any implementation details (i.e. no passing of service or workflow names in the message header!)

*NB: to paraphrase Krzysztof: “Polymorphism is an OO term, not SOA term, so I don’t use it, and make my contracts explicit wherever possible.” be wary that you are using known types for the right reasons

The satisfaction of refactoring

I am in the process of heavily re factoring our service facade (ie WCF) layer. the first file i got hold over i have already removed 60% of the LOC and got a significant number of the methods to one line
eg:
public GeoLocationFindByIdResponse GeoLocationFindById(GeoLocationFindByIdRequest aTransportObject)
{

return FindEntityById
<IGeoLocation>(aTransportObject.Payload,this.Domain.GeoLocationFindById);
}

that’s a big improvement from the 36 liner that it replaces and a whole lot easier to read.
One of our major issues was cut and paste code of logging and auditing/instrumentation. As we are not using AOP I have decided to go with passing delegates. It has actually sped up the method calls too as i have re factored out redundant methods calls and repeated logging. Now all of fault handling and the “aspect” like stuff can be handled in one place and the code is a whole lot easier to maintain.

Cool, i am happy with that!

Intention revealing interfaces

In the argument of “Intention revealing interfaces” vs “Reusable DTO/message” i will 99% of the time lean heavily toward the “Intention revealing interfaces” side.

I have just encountered code where i can see a (somewhat) noble intention of trying to keep the number of messages available in an assembly down to a minimum. Considering the system(s) mainly passes entities across boundaries, message are not common currency.
Unfortunately i don’t think enough thought was put into the decision. Leaving the notion of passing entities around as another issue, the fact that this DTO is now being used as a request AND response object in MULTIPLE service functions means the intention of each DTO is very unclear.
There are multiple fields on the DTO that are not used by the service and there is a magical “ObjectPacket” property that is of type object (as in System.Object) that is actually quite important. The reason the property’s type was left as object is because of “reuse”, as the different functions do different things with that property.
OMG.
Many hours, nay days, of bug fixing could have been saved if this DTO was split in to just 4 classes, 2 response and 2 requests. These could have been generic enough for the remained of the functions and revealed, along with the service function names* the intention of the call.

Thinks of other when you names stuff (classes, components, service, methods and parameters) and think of whether re usability is actually a benefit before bundling on bonus properties to a transfer object. 😉

*yes this is a JBOS interaction

NHibernate many to many collections

We had been having issues with entities not serialising across the wire (yes we are sending Nhibernate entities over WCF services) with not a lot of clues why some worked and some didn’t.

Upon investingation it appeared it was the collections of some of these entiies that were causing the issues, not the enties themselves. I finally realised that we where creating entities for the join tables in the DB (which to me didnt really make sense), thus cause self referencing relationships in the object model, not a good place to be if this needs to be serialised to XML!

A bit of a clean up to the mapping files and we look to be all good.

I am sure this is the most trivial of trival ORM mapping stuff, but it was something that went un noticed around here for months, or at least swept under the rug by those that did.

Below is a the email outlining the scenario….

EMAIL TO WORK TEAM MATES

*If you use Nhibernate or other ORM’s this is of Note, otherwise feel free to delete*

ORM School time:

Background (trivial, but work with me here)

  • We have a whole bunch of Data Entities/ Database Tables that have “one to many” or “many to many” relationships
  • We use joining tables to create these relation ships I.e. to join AssetMetadata & GenreType we use AssetMetadataGenreType table.
  • We use an ORM (NHibernate) to convert the table structure to a usable C# managed code structure.
  • We also use the ORM to map these relationships.
  • Unfortunately we are mapping these tables too explicitly. There really is no such entity as an AssetMetadataGenreType, only an AssetMetadata entity and a GenreType entity. The AssetMetadataGenreType is only a relationship that has no context on its own.

This over eager mapping of joining table may be the problem of our serialisation issues.

Fore example: Currently we have a AssetMetadata entity that then has a collection of AssetMetadataGenreType with each one relating to a AssetMetadata and GenreType entity. The problem here is that every one of these causes a self referencing scenario (AssetMetadata è AssetMetadataGenreType è AssetMetadata). Normally no one would care. Serialisation however does not like this, as self referencing data and XML do not play nice.

Solution: Don’t map the joining tables.

These are not real entities so should not exist in the managed code world. They only exist in the DB thru necessity.

Step one: remove all of these mapping entities (well maybe not delete, but start re-factoring where possible)

Change the mapping so the subject entity knows about its relations. Inverse this relationship in the other mapping files IF NESSECARY. i.e. genre types do not need to know about there related asset metadata

Example below:

<!– The links to associated genres –><!–

–>

<!– RC: 07/02/2008: Trying a different approach so we dont try to pass self referencing data around,

I think this is a dormant issue waiting for collections to populate before it rears up and attacks us–>

<idbag name=GenreTypes table=ASSET_METADATA_GENRE_TYPE lazy=false>

<collection-id column=ID type=Int32>

<generator class=sequence>

<param name=sequence>ASSET_METADATA_GENRE_TYPE_SEQ</param>

</generator>

</collection-id>

<key column=ASSET_METADATA_ID/>

<many-to-many column=GENRE_TYPE_ID class=GenreType fetch=join/>

</idbag>

Another benefit includes faster update times as we are taking advantage of the index of the primary key on the join table.

http://www.hibernate.org/hib_docs/nhibernate/html/collections.html#collections-idbag

I still have to test the hell out of this, however prelim test are all positive.

Rhys