Monday, December 17, 2007

Is this really required?

Update 24/05/2009: I totally blew it with this blog post. At the moment of this writing I was relatively new to WCF and got confused with the IsRequired property being some kind of input validation. Alas, this won't be the last mistake I'll ever make. I'll leave the content of this post online so I can go back and see how I made this mistake. Thanks to Travis Spencer and Daryl for bringing this to my attention.

Today I learned about a small issue when using the IsRequired property of the DataMember attribute in WCF. I had a String property on a data contract written like so:

[DataMember(IsRequired=true, Name="Code")] public String Code { get{ return _code; } set { _code = value; } }

I thought I was set to go. To me it seemed that setting the IsRequired property to true ensured that whoever is going to make use of my service has to provide a value for this particular property. As so many times before, I was wrong. I tested it with setting this value on the client to a null reference. I even tried it without setting any value at all. It didn't throw an expected exception on the client, and a null reference was received on the service.

At first I thought I found a bug. Now what? I looked at the XML schema for the contract that was included in the WSDL. The following line appeared:

<xs:element name="Code" nillable="true" type="xs:string">

The minOccurs attribute is not included, so this means it defaults to 1 which is exactly what I wanted. Now, notice the nillable="true". It seems that for reference types, the nillable attribute is emitted by WCF and that this cannot be altered or changed through the DataMember attribute.

The reason why its possible to send null reference values to the service is because this is the default value for String. Even if I don't specify a value for it, it automatically defaults to a null reference that is sent to the service. The EmitDefaultValue property of the DataMember attribute is responsible for this. By default it is set to true, which means that a null reference is sent for every reference type in a data contract. In order to solve my problem, I had to change the code snippet to:

[DataMember(EmitDefaultValue=false, IsRequired=true, Name="Code")] public String Code { get{ return _code; } set { _code = value; } }

This ensured that the client always has to specify a value for this particular property in my data contract. The XML schema is changed like so:

<xs:element name="Module" nillable="true" type="xs:string"> <xs:annotation> <xs:appinfo> <DefaultValue EmitDefaultValue="false"/> </xs:appinfo> </xs:annotation> </xs:element>

Now think about a Int32 property on the data contract.

[DataMember(IsRequired=true, Name="SomeNumber")] public Int32 SomeNumber { get{ return _someNumber; } set { _someNumber = value; } }

Because its a value type, it is described in the XML schema like the following:

<xs:element name="SomeNumber" type="xs:int"/>

It means that you have to specify a value for SomeNumber. Making this property nullable changes the XML schema to:

<xs:element name="SomeNumber" nillable="true" type="xs:int"/>

Now its no longer necessary to provide a value for SomeNumber although IsRequired is not changed.

For me, putting an IsRequired property on the DataMember attribute is kind of misleading, certainly when it only does half of the things that its name promises.

The lesson I learned from this is that one should not rely on WCF to enforce the use of the data contract. As I wrote in a previous blog post, making use of design-by-contract in the underlying domain is necessary in order to prevent improper use. Be aware to use IsRequired in combination of EmitDefaultValue in order to achieve the strictness you want from your data contract.

Sunday, December 16, 2007

My 100th blog post for 2007

Yep, this is my 100th blog post for this year. I have to admit, its not as impressive as post #3000 from Oren, but hey, I'm a father of 3 little kids. Its kind of a small miracle I get to write 100 blog posts a year ;-). To celebrate, I've been practicing a little dance this week. Wanna see it? Sure you do! Well, here goes. Needs some more practice, I guess. Let me know what you think.

Friday, December 07, 2007

Module View Presenter Bundle

This is the stuff I want to see from Microsoft! Guidance on how to write testable, maintainable and quality applications. Not yet-another-dependency-injection-container. Credits to the P&P team.

Thursday, December 06, 2007

Another Awesome "Book of the Month"

The nice people of MSDN Belux are providing the developer community here in Belgium and Luxemburg with a 40% discount on the "Book of the Month". Every other month or so, another MS Press book is chosen. This month, the most excellent Software Estimation: Demystifying the Black Art has been chosen. For more information, see here. Kudos to the Microsoft team here in Belgium for making this happen!

Sunday, December 02, 2007

Why O Why - The Day after

Alex Henderson picked up on my "Why O Why" post in his take on the Pluggable IoC in WPF Composite & Enterprise Library v.Next.

I still believe that an IoC Application Block in the next version Enterprise Library is not a good thing. There are a number of very talented people working on existing open-source DI containers for a long time now. Their efforts do not only involve providing source-code to these open-source projects, but also teaching a community on how to write better and maintainable applications. Instead of rewarding and honoring these very talented guys 'n dolls, Microsoft decided to ignore their work and provide their own (Oren has a point here).

Isn't it possible for the P&P team to pick the three most commonly used DI containers out there, write a provider model for them and use these in the Enterprise Library and the WPF Composite framework. Provide the means for other DI containers out there to write providers of their own so that their communities can use the P&P stuff with their own favorite container. How hard can it be? Maybe I'm being a bit too simplistic about it, but I hope you'll get my point here. 

I agree that providing an IoC Application Block in the Enterprise Library would reach a lot more developers than is the case today. But a completely new DI container written by the P&P team only adds to the underlying problem here. This underlying problem is the fact that most developers in the .NET community only look at what is coming from Microsoft and that's it. If the P&P team would have the courage to stand up, provide some existing DI containers out there today, these developers could come to the conclusion that the .NET community != Microsoft.

Scott Gu seems to get it! Not only by opening up the ASP.NET MVC framework, but providing support for the xUnit frameworks that exist out there today.

I shiver on the thought of what is next. A Mocking application block? My two cents.

Saturday, December 01, 2007

Why O Why

Glenn Block announced on the ALT.NET Yahoo Group that the P&P team is developing a new dependency injection framework. To say it with the words of Captain Alberto Bertorelli from the British sitcom Allo 'Allo:

"What a mistake-a to make-a!"

I mean, there is the wonderful Castle Windsor, the great StructureMap and the magnificent Spring.NET framework. Why is Microsoft reinventing the wheel again? Why is it possible for Scott Gu to provide test project templates for MS Test, NUnit  and MbUnit with the ASP.NET MVC framework and is it not possible for the P&P team to reuse the existing DI containers out there? Why is it possible for a company like Sun to cooperate with and leverage open-source projects and Microsoft seems to fail in this area?

Let's assume for a moment that this new DI container sucks less than ObjectBuilder, but that it can never compete with the existing feature-rich DI containers (seems like a very realistic scenario to me). I can see the discussions coming in my company as to why our team doesn't (want to) use this new shiny DI container from Microsoft as opposed to Castle Windsor and that we should start migrating. What a PITA!