Friday, January 25, 2008

ENOUGH WITH THE DAMN CODE COVERAGE ALREADY!

Whew!

Sorry about that, I just need to rant a little...

Here's what's got me so upset; TDD is a great cool thing. Everybody should be doing it. It's just the best thing since sliced bread, fluffy puppies and free Wi-Fi as Starbucks all rolled into one.

Now, I am NOT a TDD guru by any means. I've read some articles, tried rolling it into my approach and have had great results. I learn a little more everyday, and my understanding increases over time. If you really want to geek out on it you should talk to guys like Steve Harman and Jay Wren!

But there is an evil specter lurking that is threatening to ruin it all.

Code coverage.

Well, maybe not code coverage, but the way people with only a passing knowledge of TDD cling to code coverage like it's the last Red Bull in the fridge. The people who don't understand that the point of unit testing is not to increase code coverage at all cost, but to ensure your code does exactly what it is supposed to do; no more and no less.

I come not to bury code coverage, it's a perfect way to see what code is being tested, and more importantly what code is not being tested.

Here's where I get frustrated with peoples attitudes to code coverage (henceforth referred to at CC because I'm a lazy typist); there is a perception that a high CC number will guarantee quality code. That's simply not the case as you can hide a lot of skeletons behind a big enough door.

One "trick" I've seen to increase CC is to simply test EVERY method on the public interface of an object. This sucks.

My philosophy is that I really don't care about the individual gets/sets on a class. And to be honest, I don't like explicit tests of public methods on entities either. My belief is that you test the features. If you then find that there are methods and properties on a class that aren't being covered you have two options; either your tests suck or you don't need that property/method.

So maybe your tests suck. The best way around that is to make sure you write your tests first, THEN write your code. If you approach your tests like you approach your business requirements (user stories drive unit tests maybe?) and your test are meaningful this shouldn't be a problem, right?

Or maybe you don't need the property/method in question. I'm a big fan of pruning classes. If there is a method property on a class that never gets used why keep it? It sits there like a parasite, consuming maintenance costs and provides nothing in return. I say get rid of it!

We as developers/architects/information workers/whatever need to educate ourselves, our co-workers and are clients on this. High CC is NOT a panacea! The quality and intelligence of your tests is what ensures you are not developing crap-ware! Please, write your tests first, make sure all the features you develop are well tested. Review your co-workers tests and have them review yours. And if a high CC number is your goal look at what you are testing and don't be afraid to trim unused code!

OK, I feel better now. Code on!

Monday, January 21, 2008

The basics of the WCF stack

During CodeMash I did two "Ask the Experts" sessions where it was my intention to talk about WCF, which I've really been "geeking-out" on for several months. In the combined two hours that I "served" I only had one person come in with an issue, and it was really more of a complaint about why he couldn't use WCF.

I spoke to him for a few minutes and while his communication needs were not exactly run of the mill, they certainly weren't outside of the scope of WCF, given a few extension to the stack with a custom behavior or a custom channel.

After talking to him and a few other people I came to a realization; while there are many people who are using WCF, the vast majority of them don't really know how powerful it is. Most people seem to be content using the out of the box features of creating the normal endpoints. And granted, for 90% of the situations you face those may be fine.

But WCF offers a lot more. It is a open and extendable architecture, and with a little knowledge of the stack, what piece does what and how to extend those pieces, you can have almost unlimited power over the universe!

OK, I'm exaggerating a little. But you can still do some pretty cool stuff!

Lets review the WCF stack. This will provide the foundation for subsequent posts about extending WCF.

Basic WCF Stack

As you can see from the diagram there are a lot of pieces of functionality between your service code and the client. In actuality the client side of the stack also consists of dispatchers, at least one binding, a channel stack and a transport as well. To keep this diagram simple I've aggregated those down to the proxy object that developers use everyday with WCF but keep in mind that these things exist on the client side and the ability to customize WCF extends to that side as well (There are a few things you have to keep in mind with that, more in another post)

When a client makes a call to your service, it invokes a method on the proxy. A transport carries the message across a network to the transport on the service side. Between the transport  and the binding element is the channel stack. For an incoming message, each channel on the stack has a channel listener that receives the message from the previous channel (or in the case of the first channel in the stack, the transport) and creates your custom channel object. The custom channel then performs some action, which may or may not be based on the message, and passes it on to the next channel listener in the stack (or the binding element if it's the last channel in the stack).

This binding/channel/transport stack is what is know to most WCF developers as and endpoint. When you create an endpoint for your WCF service you are selecting a binding/channel/transport stack to for your service to use to communicate with the world. Your service can support as many endpoints as you wish, each with a unique and independent binding/channel/transport stack.

The binding hands the message off to a series of dispatchers. I'll get into these in more details when I discuss custom behaviors, but the three dispatchers that the message passes through in it's way to your service code are the channel dispatcher, the endpoint dispatcher and finally the operation dispatcher. At each one of these dispatchers, behaviors have an opportunity to be invoked. As I'll demonstrate in a future post, while custom channels are responsible for controlling how your service communicates with external applications, behaviors influence how messages are communicated internally to your service.

The response from your service back the client is essentially the reverse of the path the request just took; the response is passed through the dispatchers (this time operation, then endpoint and then channel) to the binding. The binding passes the message to the channel stack, however this time the channel listeners have been replaced with channel factories. The transport passes the message to the network where the it is returned to the client via the proxy.

With all these steps it's clear to see that there are several opportunities for customization. The ability to create these extensions give WCF it's power to allow unlimited ability to tailor how users consume your service and gives a great amount of flexibility that allows systems on disparate technologies to communicate with each other without having to worry about it at the service layer.

Up next, custom behaviors...

Wednesday, January 16, 2008

WCF Brain Fart (and why you "need" base addresses)

Well, you don't really need them, unless you are using the basicHTTPBinding and want to see the WCF help page.

Or want to create a proxy from metadata.

Hmm... OK, maybe you DO NEED base addresses!

Maybe I should back up.

The other day I was showing someone how to throw together a quick WCF service hosted in a console application. This was strictly a "Hello World" type of service, and I got everything written and wired up in about 5 minutes. I didn't worry about setting up a metadata behavior or endpoint, just wanted to get the service up an running as fast as I could. I started the app and fired up IE to show the person the WCF help page (a sure sign that it works and I'm brilliant) but instead of the help page I got this error:

<faultcode >a:ActionNotSupported</faultcode>

<faultstring xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring>

That really sucked.

In my haste, and my eagerness to show how fast and easy it was to get a service up and running, I forgot one minor but important thing; if you want to see the help page, you need to specify the base address if you are using the basicHttpBinding.

It makes sense; if you don't use a base address, you are sending an HTTP Get to your endpoint. Unless your endpoint knows what to do with it, it throws a fault. The wsHttpBinding is able to handle it, but the basic binding rely's on the Service Host which has some internal functionality that gives you the help page.

But since you need base addresses to use the service metadata behavior, you're just better off making sure you use it.

Friday, January 11, 2008

Codemash Day 1 part 2

After my "Ask the Exports" time, I headed over to see Keith Elder talk about Microsoft Workflow. The meat of his presentation can be found here. It was an bit of an entry level talk, which I think is desperately needed. There are still a lot of misconceptions out in the Enterprise community about what Workflow is, how it works and how it fits in with things like the .NET framework overall and Biztalk. He's doing an more "advanced" talk later today "custom activities" which I'm looking forward to.

After that I went to see Dustin Campbell do some F# stuff. I was playing with F# a bit before my laptop died (Note to Dell, you actually have to plug the fans in for them to cool the laptop down.) I haven't really had time to re-install and get back into it. Dustin's talk was almost SRO; functional programming, F# in particular, seems to be something that has gathered a lot of interest.

After dinner, I got to play a lot of "Rock Band" with Keith Elder and Scott Hanselman. Keith is scary good at the "Guitar Hero" type games. Scott claims he's never played the game before, but he did a great job on the drums! As for me... well, have I even mentioned how much "Guitar Hero"is NOT like really playing the guitar...

... speaking of playing guitar, the "CodeMash jam session" also happened last night. I didn't feel like dragging my rig up (I already got enough shit from Kaufman and Wingfield about my "larger-than-necessary suitcase) and I'm kind of glad I didn't. Most of the group seemed to be older guys with acoustics play country and CSN stuff. I doubt any of them know any "Iron Maiden", "Helloween" or even "Limozeen!" I'll track Dustin down later and make him a deal for next year; if he brings his stuff, I'll bring mine.

OK, drink now, more writing later.

Thursday, January 10, 2008

CodeMash, Day One Part One

Well, day one for me got off to a "bumpy" start. I request a wake up call for 7:00 intending to work out, and get downstairs in plenty of time for a little breakfast and the beginning of Neal Ford's keynote. Well, unfortunately, my wake up call didn't arrive till 8:00, so I didn't get to work out, missed breakfast and missed the first few minutes of the keynote.

One that subject...

I really dig what Neal Ford is saying about dynamic languages. I've been playing with Iron Python for a little while now and I see a lot of benefit in it, although it's still a bit "rough" in my opinion. If I never end up using it in a production project, it has made me re-think the way I do things in C#. He said something in his presentation that got a little chuckle out of me; compilers are basically weak unit tests and spell checkers. I remember being in school and hearing a lot of my fellow students in the computer lab "I can't understand why it didn't work, it compiled." I didn't think I would hear that after I left school, but I hear it at least once a year from co-workers. He also beat the testing drum, which I'm all for. I really wish this philosophy would catch on more widely in software development. I don't know why, but I'm still surprised when I meet with a client and find out that they have NO unit testing practices in place at all! I've been doing it so long myself, that I can't imagine developing without it.

From there I went to see Joe O'Brien present "Ruby:Testing Mandatory." I have to admit, I was definitely handicapped here since I have zero experience with Ruby, but I'm always interested in anything that can enhance my test-driven chops (very helpful when I evangelize this to clients). It did get me more interested then I had been in Ruby. I have been playing with Iron Python for awhile now, but I've decided I need to make some time for Ruby as well.

After that I went to see Jay Wren talk about Castle. I've heard a lot about Castle, but never really used it. It was pretty interesting.

Scott Hanselman's keynote was great! Had a great, funny intro followed by some very cool stuff for IIS 7. I've been playing with IIS 7 for a few months, but clearly haven't even scratched the surface with the HTTP Modules. More stuff to start playing with when I get home.

Served my first tour of duty in the "Ask the Experts" lounge. It was pretty cool; I didn't get a lot of people coming in for "hard-core" stuff; got one person looking for book recommendations (but that's another blog post), one person who had an interesting challenge which I will blog about later, but for the most part it was kind of an hour and hanging out and talking with Catherine Devlin and Darrell Hawley. I've never met Catherine, and if I want to continue learning Python, I should definitely start reading her blog. I hadn't seen Darrell in awhile and it was fun to talk to him again.

Off to the next session. To be continued...