Friday, October 16, 2009

Patterns and Frameworks

I just returned from the Microsoft Patterns and Practices Summit 2009 which may be my favorite Microsoft conference. Great for exposure to customers with real applications and to the wonderful, dedicated Microsoft developers who aspire to serve them. More on this in another post. I have another point to make here, which is …

Patterns are not Frameworks. We should draw a bright line between Patterns and their Implementations. A pattern only becomes a pattern if and when there are multiple implementations. You don't know a pattern well until you've seen more than one implementation. If there is a single, canonical implementation, the thing is not a pattern, it’s a framework.

“Duh” you say. We know this. And yet it eludes us in practice.

I had numerous conversations about this with folks who work in PnP. The conversation goes something like this:

The Conversation

“We are not a product group. We don’t want to be a product group.

“We’re trying to provide guidance to consumers of Microsoft development products. We are reluctant even to say ‘best practices’ anymore. It’s just the best guidance we can give today, built with time, and commitment, and our access to experts inside and outside Microsoft.

“We’re answering the customer call for Microsoft to demonstrate how to use its own products in real applications.

“This bleeds inevitably into more general questions about how to build applications and soon (and properly) we investigate and describe general design and implementation patterns that go beyond the particulars of Microsoft products.

“It’s not enough to talk about the patterns. We need to demonstrate those patterns … express them in real code that works with Microsoft technology.

“That is when it starts to get away from us. Our guidance, as it becomes code, starts to cover more and more customer cases. It begins to harden and the pattern becomes harder to see behind the bells and whistles. Customers say ‘wow, can I use that in my application?’ and we say ‘sure’. They say ‘it would really help our particular situation if it also did this’ and we say ‘sure’ again.

“Then they want us to give it a name, package it up, support it, develop a roadmap. They want us to productize it … and we start to do that because serving customers is also our mission. And, in our (not so) secret hearts, we all want to ship products … we’re wired that way.

“Then we start worrying about backward compatibility … because customers get angry at us if we change anything

“Then others in the community, especially the Open Source community, get on our case for having sucked the oxygen away from alternative implementations that may be better in many scenarios. They say we have imposed, de facto, a particular implementation of the pattern; people can’t tell the difference between the pattern and what Microsoft did to it. And I see their point.

“And now we have old code (e.g., CAB) that no longer represents our current thinking … that, in fact, embodies practices we would counsel against today … and we cannot walk away from it.

--

I don’t know that there is an easy answer to this one. I’m not willing to place all the blame on PnP either. The customer should know better.

“Best Practices” do not sit still. They evolve, leaving behind a trail of “formerly best practices” to which millions of dollars and entire careers are firmly attached. PnP is pulled in one direction by its responsibility to offer the best current guidance … and by its responsibility to customers who have placed big bets on its past guidance.

Perhaps we need some different rules of engagement.

Explicit Shelf Life

What if PnP put a “Sell By” date on their code? What if it had a shelf life and warning label: “Use with caution. Do not expect support beyond 3 years”. Stamp this at the top of every piece of code and every web page.

Then mean it. If you need to break, you break. Customers need to know that you are serious about your commitment to giving them the best advice you can and you do them no favors by clinging to outdated code.

This happens in OSS all of the time. Dead bodies are strewn everywhere.

You can do this. Microsoft can’t but you can. I think you can wean your customers away from thinking of you as a product group. If that means fewer customers served … that may be for the best … for everyone: your customers, you, and Microsoft itself.

Play Well With Others

My thesis again: a pattern is independent of any one implementation. You don't know a pattern well until you've seen at least two implementations.

What if PnP routinely called out the other implementations of the patterns they describe? Front and center, not as an afterthought. Openly encourage customers to look at these alternatives … if only to gain a contrasting perspective on the PnP guidance.

One of the best ways to learn about the Composite Application Block (CAB), for example, was Jeremy Miller’s “Build your own CAB” series. I assure you I had no intention of following Jeremy’s advice and building my own CAB. It didn’t even occur to me. But that series was the best (unintentional) documentation of CAB I ever found, It introduced me to different ways of thinking about each issue (e.g., Event Aggregation and Dependency Injection). I learned indirectly what CAB was doing and the consequences of my choice. I’m not saying the consequences were all bad either; but there were consequences and I only recognized them in the oblique light cast by Jeremy’s series.

PnP might do more to highlight these alternatives and to encourage discussion about the contrasting choices. People who come to Prism should learn … right there on the home page … that a Caliburn exists. When they come to the Unity home page, they could learn that there are 5 to 10 other popular IoC containers to choose from and find links to learning more about IoC practices.

[I was just on the Unity page. It’s a fine product home page; it is not fine for guidance about Dependency Injection and IoC in general.]

I don’t think that PnP should endorse Caliburn or anything else for that matter. I’m not suggesting that PnP’s output is inferior or that PnP should express less than abundant enthusiasm for its own work.

I am saying that PnP is presenting itself as a product purveyor in a manner that conflicts with its role as a trusted source of guidance. This ensures that it will be trapped into long term support commitments, the kinds of commitments that some people there tell me they do not want.

PnP could say in some unambiguous fashion, “my dear customer, we offer a wonderful implementation of this pattern. HOWEVER … you ought to look at some alternatives, not only when first choosing your approach but also throughout your application development; there’s gold in seeing how others approach these same problems.”

True Open Source

What if PnP could accept contributions from the field? I don’t mean through “Contrib”; I mean directly into the guidance itself.

What if PnP developers actually read some of the Open Source code out there?

I’m pretty sure the legal guardians won’t permit it … in which case “Contrib” is the best they can do.

Conclusion

They call it "Microsoft Patterns and Practices", not "Microsoft Tool and Die".

It is time for customers to pull back from unrealistic expectations of Patterns and Practices. They are not your application infrastructure outsourcer. They are a trusted source of guidance. Rejoice if they provide more but do not expect or demand it.

Patterns and Practice doesn’t need to change what they build. I do think PnP can rethink its commitments to prior output. It can do a much better job of promoting the spirit of exploration and directing its community to external resources that offer contrasting implementations and points of view.

And now I descend from this soap box … in search of another.

Wednesday, September 16, 2009

Man and Superman

I was reading Jeremy Miller’s musings on “Two Types of Developers”.

Developers fall into two different extremes … Some developers can jump right into any technology and find out how best to use it and new ways to twist it and apply it without really questioning the “goodness” of that technology.  Others look at a technology with preconceived notions of how it should work and are quick to drop a technology when it doesn’t fit their vision of “good.”

I am reminded that there are two kinds of people in this world: the people who divide the world into two kinds of people and the people who don’t. I am one of those two kinds of people.

What Jeremy really means it that there are two developer mindsets. Actually-existing developers indulge both modalities as he also observes in this second paragraph. Still, the thrust of his argument is that developers habituate to one or the other extreme.

Jeremy aligns himself mostly with the second. He describes an encounter with someone who, as Jeremy would have it, is inclined to the first.

I happen to have read the blog post on exhibit, know both parties (call the other “B”), and participated in some of the exchange that ensued. It got me wondering whether I buy Jeremy’s dichotomy.

Jeremy strives to be non-judgmental, averring potential advantages on both sides. I suggest that his phrase “without really questioning the ‘goodness’ of that technology” gives the game away.

I know “B” and he is a curious fellow (double entendre intended). His curiosity is evident in the post and manifold in conversation. “B” never takes a technology on face value, certainly not “Prism” which was the technology at issue in this example.

It may be relevant to note that “B” was deeply involved in Prism development. He is obviously comfortable with it. But “B” was as deeply involved in the debates, disappointments, and compromises that are inevitable when one works collaboratively on a framework. He may be blind to some of its faults but he can’t be accused of being uncritical by nature.

What happened here is that “B” chose to implement a solution to a problem using technology that Jeremy dislikes. One may say so. One may ponder the reasons. But to leap to the conclusion that “B” (or anyone who chooses similarly) is simply “unquestioning” …  that is unjust.

Worse, it is lazy.

It forecloses a genuine attempt to investigate how developers actually make choices in the real world of customers and deadlines.

Are there drudge journeyman programmers who paint by numbers? Sure … but they aren’t relevant to this discussion and that is not what Jeremy thinks of “B”.

Do we often cheerily follow the easy, well-trod path? Of course. Do we challenge our every decision to be the best possible in the abstract. No. None of us do. Could “B” have made a better choice than Prism… even in his particular circumstances? Maybe … which makes it worth pursuing with “B” .

But Jeremy’s point isn’t that we are prone to be the willing captives of our familiar tools. No, he claims we are by nature either slaves or freeman, the “last man” or the “Übermensch”. That is the true import of his “interesting taxonomy of developers that I’ve observed for years”.

The earth has become small, and on it hops the last man, who makes everything small. … One still works, for work is a form of entertainment. But one is careful lest the entertainment be too harrowing. One no longer becomes poor or rich: both require too much exertion. … 'We have invented happiness,' say the last men, and they blink.

Behold, I teach you the overman. The overman is the meaning of the earth.Let your will say: the overman shall be the meaning of the earth! I beseech you, my brothers, remain faithful to the earth, and do not believe those who speak to you of otherworldly hopes!"

- Nietzsche's Thus spoke Zarathustra

It’s thrilling to hear … but I am not buying it.

I’m a huge Jeremy Miller fan; this was not his best day.

Saturday, September 12, 2009

Silverlight Spy 3 – First Look

Silverlight Spy 3 was just released. I think you’ll want this in your tool bag right away. Why? Because it is a great way of seeing what’s going on in your Silverlight application … and twiddling its appearance … at runtime.

It is especially helpful if you’re building a compositional application of many, independently-designed views; you want to see them playing together and understand what’s happening.

Quick Tour

I’m looking at my Prism Explorer demonstration app right now. This demo shows our DevForce Silverlight Data Services product working with Prism.

Fired it up in Visual Studio (to get the Cassini server side going), then pasted the URL (http: //localhost:9006/) into Spy’s address bar. Spy fires up the client in its browser just fine.

Spy drew the red highlight box, not me. I held down the ctrl + shift keys and moved my mouse around the browsed page; as I did, Spy highlighted each element in this manner; and then I clicked on the address to set the focus as you see it.

Now I swing over to the Explorer view and I see that the address is a TextBlock in the middle of a DataGridCell … deep in the visual (or logical) tree that begins with my Prism shell. I love being able to start from something I see on the page right to the element in the object tree.

I get the same effect in the other direction by navigating from the tree: select a node and watch Spy highlight the corresponding visual real estate in its browser.

I can see the XAML for this TextBlock in Spy’s View window:

Suppose I want to see what would happen if I gave the address a little more air. I open Spy’s Properties window, locate the Padding property and try “20” all around. I see the effect immediately:

Peeking and tweaking the look on the fly is value that can hardly be overstated especially in a composite app. Sometimes you just have to see the app run in a production context with real data behind it to understand what is going on. Adjusting some values to visualize how it might look after correction … that’s worth something to me.

Spy integrates seamlessly with Reflector so I can poke around in the client-side source code while in Spy. First, I tell Spy where to find Reflector through Tools / Options / Reflector. Then, in the Explorer window, “Object Browser” node, I navigate the assemblies in the XAP:

The View window exposes the disassembled code using Reflector:

I can also spy on other people’s applications. Now, when I see an effect I like, I’ll have a fighting chance to figure out how it’s done. Nothing evil in that.

Perhaps more productively, Spy can help me better support my customers. I don’t have their code. I don’t want their code! Now I can fire up their app in Spy from out here in Stinson Beach (yes, kicking back with the blog) and gain immediate insight. Having reflector baked in makes it easy to walk their code too.

Helpful Touches

Spy let’s me monitor mouse and key events which I can filter. In this snapshot, clicking on the event also takes me to the associated visual element.

I like to know when my app is visiting the server. Fiddler, Firebug (FireFox), and Web Development Helper (IE) are superior tools for the in-depth analysis. But if I just need to know that something went over the wire and peek at the headers, Spy does nicely. In this snap I just asked for a projection over all customers and their orders:

The top window is a grid of the traffic; double clicking a row reveals the headers panels in the lower half.

There’s a Performance Monitor with the visual familiarity of the one in Windows Task Manager.

The processor metric seems parallel to the Task Manager’s. The memory metric probably tracks just your app’s usage although how and how precisely I can’t tell. I noticed unpredictable figures simply by refreshing the application address to restart the app. I think of it as a rough gauge of relative behavior. You’ll get a general feel and you might be able to detect some memory leaks this way.

There are other goodies. These are just the features that attracted my immediate attention and made me want to buy.

Price

Spy was free in earlier incarnations. It now sells for roughly US$100 for a personal copy. You can download an evaluation copy that’s good for 27 days.

Frankly, I’m glad to see a price. I love “free” as much as the next guy but nothing is truly free. I want Spy’s author to keep improving this tool and he has to make a living at it to do it well. I’m bummed when a great free tool comes along and then it just sits there, waiting upon the author’s free time to answer questions, fix bugs, and take the next giant leap.

The biggest shortfall (as I will repeat) is the utter absence of documentation. With a little dough, Koen Zwikstra - the man behind spy - can afford to hire a tech writer and cut some videos.

Full disclosure: I got a free copy as an MVP. This review, however, is entirely my idea with no promise of reward.

Wrap Up

Silverlight Spy 3 is a super tool and a fine piece of work. Runs like a top. No install issues, no runtime glitches so far.

No documentation! None that I could find. This is a huge weakness. Thank goodness for Koen’s Channel 9 video with Adam Kinney recorded at MIX in March 2009; it opened my eyes to the potential and gave me valuable operating clues. How else would I discover “Ctrl+Shift+Mouse+Click”? Web search revealed nothing else (there is material on Spy 2).

Fortunately, it is pretty intuitive. Just bang around on it awhile and it starts to make sense. But some kind of guide needs to come out soon.

I’m hopeful this introduction piques your interest and gets you started.

A few minutes with Spy and you remember in a hurry never to put anything secret in your Silverlight client; that’s the wrong place for the Coca Cola recipe. Sure other tools can do it …. but Spy makes it so easy.

Go Spy!

Tuesday, September 8, 2009

AdventureWorks 2000 tinyint nightmare

You’re going to love this one!

Some of our integrations tests use AdventureWorks 2000. One developer’s test updated a Sales.SalesOrderDetail. The test suddenly blew up with a SQL Server 2005 error that complained about exceeding the size limit of a TinyInt.

The error didn’t say where this TinyInt lived or what the column was called. The best we could tell was that the exception occurred while updating Sales.SalesOrderDetail.

SalesOrderDetail has a TinyInt column, “LineNumber”, which was not jeopardized by the update.

Aside: I have a different AdventureWorks db on my machine that doesn’t have “LineNumber” or a TinyInt but it does have, “OrderQty”, which is a SmallInt. I would have suspected that (“SmallInt, TinyInt, what’s the difference?”); there would be no problem there either.

No other developer could reproduce the SQL exception.

After hours of hair-pulling, the developer found that there is an update trigger on SalesOrderDetail that updates the parent Sales.SalesOrderHeader. SalesOrderHeader has an update trigger that increments SalesOrderHeader.RevisionNumber … which is a TinyInt.

Over the course of many tests, that RevisionNumber kept creeping up … until it hit 255. Each developer has his own AdventureWorks copy so no surprise no one else could reproduce it.

You can blame the victim if you wish; should have had adequate rollback logic all along.

But I have to admire the genius who decided that you’d never exceed 255 updates of a SalesOrderHeader in a test database.

Let’s thank SQL Server for throwing an exception on exceeding the max for a TinyInt without telling us the name of the column or table involved.

Kudos also to the other evil genius in this mess who wrote a trigger on one table that fires a trigger on another table to update the RevisionNumber … and didn’t bother to check the type or implement exception logic that would help clarify the problem.

There must be an award for this kind of thing.

Lesson #1: If you are using AdventureWorks 2000, be sure to reset all SalesOrderHeader.RevisionNumber values to 0. It’s too late to mess with the schema.

Lesson #2: Hey, SQL Server folks, how about a little more help in exception messages?

Lesson #3: Please write good exception messages yourself … messages that would give the poor sod who received it a fighting chance of understanding the problem. Extra credit if you suggest how to fix it.

Lesson #4: Business logic in the database is killing us out here. You DBAs have got to be more helpful.

Lesson #5: Stop trying to squeeze every last byte out of the schema. TinyInt should be used only in the most extreme circumstances and never where it could be incremented.

Friday, September 4, 2009

On Software Warning Labels

"The only demand I make of my reader is that he should devote his whole life to reading my works." – James Joyce to an interviewer.

I’ve been weighing in on Colin Blair’s blog recently about concerns I have about the RIA Services DomainDataSource (DDS) … concerns that apply equally to our own DevForce ObjectDataSource.

Colin’s blog on RIA Services is worth watching as Colin’s is a thoughtful voice. He likes RIA Services a lot … but not uncritically.

His post is a response to Jeff Handley’s twitter poll: “Do you consider the .NET RIA Services DomainDataSource to be ‘Data Access Logic’ in the UI?”.

Collin said “Yes”, then did the responsible thing and posted his reasons. That set in motion a small to-and-fro with Jeff who is maintaining and evolving the DDS for Microsoft.

What is going on there is some sensible thinking. There is no Microsoft bashing. I suppose some posturing is inevitable (at least where I am involved) but I believe that matters of real substance are poking through. We’re not just talking about “good design”; we’re talking about consequences.

Which brings me to something that has been gnawing at me since I fulminated against Drag-and-Drop back in August.

I received feedback, not only from Microsoft friends, that I had been uncharacteristically caustic and univocal in my opinion. I seemed to be sliding into the camp that would “shun” people who might use a DDS control; the camp that would “think those people are stupid.”

I recall too well my Berkeley days of smug “Us versus Them”-dom. Appears my capacity for self-righteousness is undiminished.

Timeout! I do not believe that the people who use the DDS are stupid. On the other hand, I do meet a great number of developers who are overworked, undertrained, and uncurious. They constitute the majority of developers … as they do in every profession.

I look in the mirror and can say the same of myself with respect to many topics. There isn’t time to understand the implications and nuances of everything I do. I can muster little interest in certain areas of software development. I simply trust that the technologies work and are appropriate … and I move on with my busy day. Our love of our craft is not equally distributed over the entirety of our domain.

So when I … or anyone … get amped up on a topic like DDS or drag-and-drop or ViewModel … what should I expect? Is this stuff really that bad for you? Are they clubbing baby seals?

No. It’s only software. We are not geniuses. We are not James Joyce and we certainly don’t deserve that kind of devotion.

I’m not backing off my “concern” about drag-and-drop. I’m not recanting my critique of the DDS (and our own ObjectDataSource). I just want to position myself differently … a bit more sympathetically … perhaps suggest an approach that may benefit the developer community and lower the temperature.

What if Microsoft (and IdeaBlade) were more upfront about the consequences and alternatives of some of these dubious controls and practices?

There is the sense among many that Microsoft doesn’t talk as openly as it should about technical debt.

Taking on technical debt can be a wise investment. I use the DataForm with auto-generation in my demos. Incredibly convenient. Could probably get away with it for some production screens that have only a few fields and don’t need much management; it will save tons of time that would be utterly wasted if I did a better job of customizing the user interaction … because nobody wants or needs “a better job”.

I incur that technical debt with gratitude. I choose what I’m doing.

There is no problem with the DataForm, or the DDS, or drag-and-drop. The problem is that many developers are insufficiently aware of the debt they are incurring. I use my credit card knowing that I’ve got it covered; too many developers are using the “credit card” thinking it’s free money.

Alan Stevens suggested something like the following in the Herding Code podcast I wrote about. He said it would be ok to do demos with drag-and-drop if the presenter stopped for a moment and said:

“This approach has utility under specific circumstances … but watch-out because it has costs too. I strongly recommend that you read up on it over here … to appreciate the limits of what I’m showing you … and to learn about alternative paths that may be more appropriate now or in the future.”

That speech is a responsibility we have as presenters at conferences.

Those of us who make and sell a product bear an additional responsibility, especially when we target the broad market of developers who, let’s face it, don’t try very hard to master the craft.

It isn’t enough to squirrel the discussion away in the corner of some blog. That’s the equivalent of hiding in the small print.

I think we (IdeaBlade, Microsoft) should put a warning sticker right on the control itself. Put it in the XAML doc. Teach Intellisense to show the “warning” hyperlink.

Smack me as a hypocrite if we neglect to put a warning on our own ObjectDataSource when we ship it.

Saturday, August 29, 2009

Fiddler + WCF SOAP+ Cassini = Ooof!

What a PITA trying to observe my DevForce Silverlight application running in Cassini using Fiddler2. Thanks to John Papa I’ve got that working now.

Here’s the situation:

  • DevForce communicates using WCF SOAP service
  • I’m running both the client and the service in Cassini, not IIS
  • Tried all the recommended configurations (see below)

The problem is the WCF SOAP service. There is no issue with REST.

What Finally Worked

Can’t make it work with IE at all. Haven’t found anyone who knows how.

But I can make it work with FireFox … and I am fine with running in Firefox. Here ya go:

  1. Install Firefox (duh)
  2. In fiddler: Tools / Fiddler Options / General / disable IPv6 [may not be necessary]
  3. In fiddler: Tools / Fiddler Options / Connections. Click “Copy Browser Proxy Configuration URL” … which puts the right phrase in your clipboard
  4. In Firefox: Tools / Options / Network / Settings. Click “Automatic proxy” radio button which enables the text box. Paste script address from your clipboard.
    On Vista/Win 7, the address looks like
    “file:///C:/Users/YOUR_LOGIN_NAME/Documents/Fiddler2/Scripts/BrowserPAC.js”
  5. Remember to “OK” your way out of the dialogs (yes, I forgot this and hit cancel)
  6. Close Firefox
  7. Re-launch Firefox
  8. Re-launch Fiddler
  9. Confirm Firefox browser actions show up in Fiddler
  10. Launch your app
  11. Paste app address into Firefox

What Works If I Change Requirements

You can deploy the server to IIS and point the Silverlight Client at it. That’s fine … but I didn’t want to bother with that. Just want Cassini to do it all.

You can use Nikhil’s excellent IE plug-in, Web Development Helper. This works too. You enable it from the IE menu: View / Explorer Bars / Web Development Helper.  But I was looking for a Fiddler solution.

What Doesn’t Work

Don’t have VPN running. The minute I’m running my VPN, Fiddler stops listening to all IE traffic, even regular browser traffic (no problem for Firefox though). I’m sure there is a way around this. I don’t know what it is … and at the moment it is just easier to shut down my VPN.

Many kind people offered suggestions … all of which failed me one way or another:

  • localHost.:port/myapp (that’s with a period between “localhost” and colon) - app crashes, unspecified service security exception
  • 127.0.0.1:port/myapp instead of localhost - app crashes, unspecified service security exception
  • ipv4.fiddler:port/myapp instead of localhost - app crashes, unspecified service security exception (because translates to 127.0.0.1)
  • myMachineName:port/myapp instead of localhost – “[Fiddler] Connection to ward-xps failed.
    Exception Text: No connection could be made because the target machine actively refused it”
  • Fiddler proxy setting: Tools / Fiddler Options / General / uncheck “Enable IPv6” – no help
  • Fiddler Tools / WinINET Options / LAN Settings. “Use a proxy server” checked. Click Advanced button … proxy addresses are set to 127.0.0.1 – no help

Many of these suggestions are variations on the cryptic paragraphs in the configuration FAQ on the Fiddler site: http://www.fiddlertool.com/Fiddler/help/hookup.asp#Q-LocalTraffic

Saturday, August 22, 2009

Discover Silverlight with “Silverlight 3 Jumpstart”

Maybe you’ve heard of this Silverlight thing. There’ve been 2,300 new Microsoft technologies introduced this year but Silverlight seems like it might be important. You are a busy, experienced business application developer with limited time. You demand substance but there’s no way you’re going to wade through 800 pages of how to build custom flashy controls. You won’t tolerate marketecture; you don’t want the “Silverlight Programmers Bible” either.

You should snag a copy of “Silverlight 3 Jumpstart” by Microsoft MVP and Regional Director David Yack. At a slim 209 pages you can blaze through it on a roundtrip flight to Redmond just like I did. You won’t learn Silverlight in depth. But you will get a soup-to-nuts view of what building a business application in Silverlight is really like. All of the essential mechanics are there.

  • How Silverlight compares to alternative client technologies (ASP, WinForms, WPF, Flash/Flex/Air)
  • Development tools – got Visual Studio? not much more is absolutely required
  • “Hello, Silverlight” – of course
  • Hosting a Silverlight app – pretty easy stuff
  • Basic screen layout with XAML and visual controls
  • Data binding controls to data – because that’s our bread and butter
  • Debugging – about time someone talked about that
  • Making it look decent with styling - think CSS
  • SketchFlow intro – executable sketches to win your client’s confidence
  • Plumbing (aka, Application Architecture) – so you don’t reinvent every wheel

David is steadfast and clear about his purpose: to give you a firm grasp of what is involved in Silverlight development.

He shoves to the side everything that would get in the way. You already know it gets more complicated than “that” … whatever “that” happens to be. “Rough road ahead” signs are sufficient for the nonce; no need for the bumpy ride right now.

When it comes to getting data into and out of your application, I’m personally thrilled to report that David devotes pages [181 - 184] to our DevForce Silverlight product; full disclosure: I helped him with those four pages. Nearby you can read about the other “Business Application Frameworks”: CSLA, RIA Services, and roll-your-own.

Do yourself a huge favor: don’t roll-your-own; I hope you see why when you look at all the challenging ground these “frameworks” cover.

The very nature of this book requires that it be early to market. It’s not going to be a “timeless classic” nor is that its intention. This is one of the first … if not the first … Silverlight 3 books out there.

The haste shows. There are grammar and spelling mistakes. Chapter 10 was clearly intended to be Chapter 1 as it makes forward references to chapters that you’ve already read. That’s mildly disappointing. Don’t let this undermine your faith in the material; the book is accurate in all important respects relevant to your purpose: to learn what Silverlight development is like and whether it might be for you.

The book is affordably priced at $30 for print, $20 as an e-book; if you use the discount code for my blog (“WardBlog”), the e-book is only $15. The e-book arrives as a PDF and (unlike many technical books) is perfectly readable on your laptop or Kindle or other e-book reader.

Silverlight is a tremendous business application delivery vehicle and a heck of a lot more productive than any other web technology out there. Silverlight Jumpstart will show you why.