Wednesday, June 24, 2009

WPF / Silverlight Differences White Paper

I didn’t write it but I just read it and, at 69 pages, it’s as comprehensive an inventory as you’re likely to find.

Sergio Loscialo from Wintellect wrote it – on contract to Microsoft I believe – and posted it to CodePlex (at an interesting address: “wpfslguidance.codeplex.com”) on June 04, 2009. Get it here.

The paper describes Silverlight 2 and the coeval version of WPF.  Microsoft has been rapidly whittling down the differences between the technologies and enriching both with new releases due in a matter of weeks and radical changes slated for SL 4 in 2010. This paper forecasts some of the changes that arrive in SL 3 but there is much omitted; we must hope that Microsoft continues the funding to keep it current.

Nonetheless, it is a superb baseline and should retain its relevance for at least another year even in its current form. Highly recommended.


Read more of this post!

Monday, June 15, 2009

Screen Factory

Let’s go right to the ending. When I need a class to construct a Model-View-ViewModel triad, I’ll call that class a “Screen Factory”;  the terms I’ve been toying with recently, “Coordinator” and “Director” should be reserved for cases involving triad coordination. How did I get here?

Jeremy Miller called me last week after reading my post on the “Coordinator”. He’s been watching a lot of the MVVM noise we’ve all been making recently as he girds his loins to write a book about “Presentation Patterns”. He recently announced his plans for this book and I encourage you to look at his proposed Table of Contents and send him feedback.

[Warning: I am about to render my recollection of our conversation and to try to represent Jeremy’s thinking accurately. He is more than capable of doing that for himself. But I’m forging ahead because he’s off to Norway, won’t get to these topics for awhile, and I’d rather misremember and flub the concepts than forget altogether.]

Anyway, he read my post and called to talk about it … as well as some of his ideas for the book. He mentioned almost casually that I had misunderstood something he wrote awhile back. He was right about that … as we’ll see.

The gist of my post was that the creation of Model-View-ViewModel (MVVM) triads is a separate responsibility from the internal synchronization among the triad members parts. The VM is dedicated to synchronization of V and M. It should not also assemble either its own triad or other MVVM triads. The job of creating a complex view belongs to something I called a “Coordinator”.

To support my argument about separating creation and synchronization concerns, I cited Jeremy’s “Main Players” article from his 2006 “Build Your Own Cab” series.There he identified something he called the “Screen Conductor” which he said was responsible for “the activation and deactivation lifecycle of the screens within the application.” I glommed on to this, thinking it to be another name for what I’m calling “Coordinator”.

Turns out that isn’t what he had in mind at all. His Screen Conductor doesn’t create screens or views. It oversees a collection of “screens” and decides when to activate (show) or deactivate (hide/close) them. Activation is not creation … although it may require screen creation; Deactivation is not screen destruction … although we may dispose of the screen once it has been deactivated.

Think of Visual Studio. Click an item in the Solution Explorer tree and VS displays the selected solution element in one of its tabs. Click another element and you get another tab. Click the first element again … and instead of a new tab, VS activates the already displayed tab. Try to close that tab and, if you’ve made any changes, you’ll be asked if you want to save or cancel; cancel and the tab remains in place. You’re seeing the Screen Conductor at work, managing a collection of “editors” displayed in tabs.

Note: I don’t know how VS is actually put together. This is an exercise of my imagination; join me, won’t you? 

How does the Screen Conductor add a new tab? I figure it finds the association between the item you clicked and an editor for an item of that type. It then might ask something to construct an appropriate editor instance for the selected item … and then adds a tab populated with this editor.

Whatever the actual implementation, we can be sure that the Screen Conductor itself does not construct views. It may know which view to create: a code editor for a C# file, an XML editor for an app.config file. But it doesn’t know squat about how the editors themselves are built. It delegates creational responsibility to something else.

My “Coordinator”, on the other hand, does construct views.

Observe also that there need only be one Screen Conductor in the entire VS application. Screen Conductor is a part of the VS Application Controller … of which there should be exactly one. VS only needs one apparatus to manage the coming and going of tabs.

But there are many “Coordinators” in an application, each capable of constructing a composite “view” of a particular type.

Clearly “Screen Conductor” is not “Coordinator”. This would have been clear to me if I had reread his article with a modicum of care … as I invite you to do.

“So Jeremy”, I said, “if the Screen Conductor doesn’t create the view, what does?”

After a brief digression into open-generic type resolution with StructureMap and whether he actually needed anything specific to create the view, we arrived at the essence of it.

“If you need something to create screens, it would be a Screen Factory.”

“Factory” versus “Coordinator”

When the Screen Conductor determines that the Visual Studio item you clicked - the item that identifies the “Screen Subject” that you’re interested in – is not represented in a tab on screen, it finds the right factory for this kind of subject … and calls it. If you can rely on the IoC container to assemble the pieces; fine … it is acting as your factory. But if you’re not comfortable with IoC handling that task, you’ll want a screen factory class.

And, trust me, you will find that you cannot always rely on IoC / Dependency Injection to create the “view” (the MVVM triad) for you, especially if the “view” is complex and composed of constituent views. You may need a dedicated factory class to assemble such a view. Of course you’ll use IoC to acquire or inject this factory where you need to call it.

My “Coordinator” class is functioning as such a factory. If all it did was create triads, I should have given it a different name … a name with the word “factory” in it.

How did I miss that? The title of my post was “Birth … of M-V-VM Triads”. Hello?

I missed it because I was thinking about an (unnamed) class in one of my applications. That class has additional responsibilities. I was thinking about how it closes and disposes of views. And I was thinking a lot about how it coordinates a set of closely collaborating MVVM triads.

Somehow, in my entire post, I barely mentioned view coordination … which was the reason I called this thing “Coordinator” in the first place. I redress that omission below in a sidebar on “Coordinated Collaborating Views” where I also consider whether you’re “permitted” to write a class that creates, coordinates, and destroys views or if you “must” re-factor such a class because it violates the Single Responsibility Principle (SRP).

But I got ahead of myself. I should have stuck to the challenges of view creation … and called it a factory.

“Screen Factory” or “View Factory”?

What do we call it? Jeremy calls it a “Screen Factory” in keeping with “Screen Conductor”, “Screen Collection”, “Screen Subject”.

We both feel uncomfortable with the word “screen”. “Screen” can mean “everything that appears within the windowed walls of your application.” That’s too big a canvas. In the Visual Studio example, when we say the Conductor manages a collection of screens we are referring to the individual tabs, each one of which holds a “screen.” Is that confusing?

John Papa and I considered calling it a “View Factory” instead. Unfortunately, “View” is at least as overloaded as “Screen.” “View” has the “big” versus “small” problem in reverse. A toolbar or a chart might be implemented as a view within a larger view composition. Some views can be adequately represented with a data template. I wouldn’t want to write a factory for these. Too far down in the weeds. I only need a factory for a view with heft … such as the editor view in the Visual Studio tab.

Moreover, there is potential confusion surrounding the difference between the view type, the “V” in the “M-V-VM” triad, and the view concept which the triad implements. Writing “the MVVM triad” gets old fast. I prefer to just say “View” meaning the conceptual view … and trust that you understand that I mean “that which appears in the UI”, regardless of its implementation. It should be obvious when I’m talking specifically about the V in MVVM (or MVP, or MVC).

But in code, if you see a class named “CustomerOrdersViewFactory” you might wonder if it creates the whole view or just the view instance within the triad. In fact, I may need a view instance factory that determines dynamically which of several alternative view implementations is most appropriate for this particular user at a particular moment. Localization, accessibility requirements, user authorization, … these kinds of factors can lead you to offer several flavors of what is otherwise the same view; the V changes while the M and VM do not.

I’m going to stick with Jeremy’s “Screen Factory” … for now. By “screen” I’ll mean the chunk of visual real estate devoted to a significant user scenario.

Does this work for you?

SideBar: Coordinated Collaborating Views

In the general case, MVVM triad interactions are loosely coupled … often through some pub/sub scheme, e.g., Event Aggregator (EA). There is no need for anything to coordinate them. They just listen and respond. Or they publish an event that another view might care about … and then they immediately forget about it. Remember: EA is always fire-and-forget.

However, I often have a set of “views” that collaborate too closely and too dynamically for a reasonable EA implementation. For example, imagine a “Customer Screen” displayed as a Customer overview positioned above a Details Tab Control. Each detail tab displays particulars of the customer: orders, contacts, credit info, etc.

I would construct this “Customer Screen” compositionally; there would be some MasterDetails mini-shell … the visual framework for the “Customer Screen” … into which I poured the customer overview and each of the detail tab views. Something has to put all of these pieces together (the creational responsibility) and something has to mediate among the composite views to keep them in sync.

Why sync? It is inevitable that something will happen in one of the customer sub-views that affects its colleagues. You could use EA to signal across views. But that gets out of hand pretty quickly. The number of cross-view synchronization events begins to multiply. You start to worry about the diversity of event payloads. The moment you enable viewing of multiple Customer Screens (e.g,, to see “Acme Grocery” and “Fine Food Mart” simultaneously) you have to scope the events by customer so that the two customer screens don’t respond to each other’s messages. You’re reliance upon pub/sub complicates testing and debugging. It’s a mess.

My preferred approach is to provide a common context object to each of the constituent views (I mean their VMs of course) . The context constrains the scope to a single customer and contains all the necessary coordinating machinery. The constituent views remain decoupled from each other … they never address each other directly … but we can still coordinate them with something that is both local and apposite to the task.

What do we call this context? A “coordinator”? A “director”?  Either name will do.  What I’ve described fits the Mediator pattern as described in GoF where the example class is called “DialogDirector”; it also appears in Wirfs-Brock’s, “Object Design”, as a Coordinator implemented with the Mediator pattern (p. 339).

Look closely at the GoF DialogDirector sample code. Notice that the DialogDirector both creates the constituent components (“widgets”) and coordinates them. It passes itself into the constructor of each of the components it creates.

Argue if you will that the GoF  “Director” violates the Single Responsibility Principle (SRP); at least I am in good company.

Is this a problem? Certainly there are at least two dimensions of change. We could change the way we construct the dialog and we could change the way we coordinate its parts. We could refactor DialogDirector into a DialogFactory and a DialogCoordinator. The factory would “make” the widgets, “make” a coordinator, and wire them all together. I have taken this approach with modest success. But I must admit that many found it a tad confusing and overwrought.

I’m not sure it is necessary. Multiple responsibility classes are “bad” because the forces of change impinge upon the responsibilities from different sources at different rates. But the dimensions of change in our coordinator are rarely independent. Am I really going to change how the dialog is constructed without simultaneously changing how its parts are coordinated? Can I change the coordination without knowing about the parts and their instantiation?

Maybe. But let’s be pragmatic, not pedantic. We can always refactor after we take the first bullet.


Read more of this post!

Friday, June 12, 2009

RIA Services Ain’t Cheap

I’ve been fielding questions recently about the differences between RIA Services and our DevForce product. We both help you move data across the web in a Silverlight business application so it’s natural to compare.

Inevitably I get some variation on the following:

Why should my company pay for DevForce when RIA Services is free?”, they ask. “My company doesn’t like to pay for software.

I’m a passionate guy … so a small tantrum begins in my head: “You’ve got to be kidding. Do you work for free? Does your boss work for free?” I want to go off like Harlan Ellison.

Then I chill a bit and I make mistake #2: I start to enumerate the many ways in which DevForce goes way beyond what RIA Services does today or will do even when it arrives for real some time next year. You’ll find such an inventory on our website where we sound three themes:

  • Production-ready now
  • Maturity
    • Seven year head-start
    • Real customer and field experience
  • Features you need

Then I realize that all of these details are secondary. The real question is about economic value. “Speeds and feeds” are nice but your company wants you to net it out … make it simple. So here it is.

DevForce is the far better deal!

In fact, it’s a no-brainer … assuming they pay you more than $0.00 per hour. Let’s do the math.

What is your time worth? $80k per year? Your load factor (benefits,  facilities, management, etc.) is probably about 1.4 … even if you work for yourself. That makes your annual cost $112,000 or about $65/hour if you are actually productive 35 hours per week (don’t count meetings. meals, emails, twitter-time, and general BS).

Right now you can get an unrestricted DevForce Silverlight developer license for less than $1,000 and there are no server or runtime fees.

By my calculations you breakeven after a mere 28 hours of added value.

Now print that inventory we prepared and throw a few darts at it.

After each hit, ask yourself how long it would take you to implement that feature or compensate for that deficiency. For example, how long will it take to

  • Re-write your RIA Services calls after the latest overhaul of the API
  • Find out why it’s taking so long to fetch data … what’s it doing anyway?
  • Re-deploy to multiple servers because you needed to change a query
  • Save the user’s pending work locally so it isn’t lost if the connection drops or the app crashes
  • Confirm immediately that the just-entered “before date” is earlier than the “end date”
  • Execute a sequence of asynchronous tasks, accounting for exceptions thrown anywhere in the chain
  • Stop an employee user from seeing the social security number (although an admin user can)
  • Test with in-memory persistence operations that don’t go to the database.
  • Configure and switch among dev, test, stage, and production environments.

You get the idea. A few darts land on “I don’t care”. Many more pierce issues that really matter to you … and 28 hours disappear in a flash.

Talking to Management

You’re sitting down with your manager trying to explain the options: “We could build the application with raw WCF Services or RIA Services or DevForce. … This approach has this feature but that one doesn’t yet so we’d have to build it … or we can wait until … when they’ve said that …” Blah, blah, blah.

You see the eyes roll back in his head. He doesn’t know what you’re talking about and isn’t sure you do either. All he remembers is that he either has to write a check for $1,000 or he doesn’t. You get to tell him why he should in the simplest possible terms:

Breakeven in 28 HOURS … after which it’s all upside.

Even your manager understands that!


Read more of this post!

Wednesday, June 10, 2009

Kent Beck For Free

Most of us are untroubled by our participation in the market economy.

Kent Beck is unusual in this regard (as in so many others) … another reason to treasure his existence in our corner of the world.

Kent is genuinely conflicted about when he should and should not get paid for his work. He poured his angst out in this post … which is well worth reading if you’ve ever wondered seriously about your worth in … and your responsibility to … the so-called developer community.

He’s not saying that he thinks his work should be free or that he should rely on the kindness of all of us to pay for his unquestionably great service. His question is more subtle than that, as we see in this excerpt from his comment to his own post:

One thing I’d like to clarify is that I don’t have trouble saying “no,  [you can’t have that for free]” in general. What was different in this case is that I said “no” when there was absolutely no additional cost to me. I was prepared to give the talk for the value of the feedback (although I think the talk would be worth more than that to the client). That seemed like a fair exchange, at least in today’s weird market. However when they asked for more value [, permission to distribute a recording of the talk throughout the company,] that wasn’t going to cost me anything extra, that’s when I crossed my own line. I’ve hitherto always delighted in creating more value at no additional cost to me

For a contrasting perspective from an unperturbed conscience, check out Harlan Ellison fulminating against free in this startlingly blunt … and funny … interview.

They want everything for nothing. They wouldn’t go for five seconds without being paid and they’ll bitch about how much they’re paid and want more. I should do a freebie for Warner Brothers ?!?!? What is Warner Brothers? … with an eye-patch and a tin cup out on the street ?!?! Fuck no!!!

They always want the writer to work for nothing.

And the problem is there are so many goddamn writers who have no idea that they’re supposed to be paid. Every time they do something they do it for nothing. “Look at me, I’m going to be noticed … ”. You tell me, are they any less the media whore than I? I think not. Nobody’s offered to buy their soul. I sell my soul … but at the highest rates.

No ambiguity for this fellow!

Amusing Coda: (1) it was Kent Beck himself (via Twitter ) who pointed (approvingly) to the Harlan Ellison video … and (2) Harlan doesn’t get a nickel for his tirade because someone ripped it off and stuck it on YouTube. LOL

Finally, if you have something to say on the matter, consider posting it to Kent’s blog rather than mine. This is really his thread and you’ll be responding to him and his audience. My notice here is merely a sign post directing you toward a point of great human interest.


Read more of this post!

Thursday, May 28, 2009

Galapagos Bound!

No more posts from me for the next ten days. My wife and I are going to the Galapagos Islands. No computer. No phone. No twitter. Heaven.


Read more of this post!

Can I write a WPF+Silverlight App?

In this post we explore the question, “can it be done ?”

If we were asking “can we write one application that targets both Windows Forms and ASP?”, I would say “sure but there will be little code in common.” The data access and business layer perhaps … if you are careful. At the application, UI, and presentation levels there are irreconcilable differences. Maybe 10% to 20% of the code can be the same in both environments. That’s my opinion based on recent observations of such a case.

I believe the story is much better when it comes to writing a single application with both a Silverlight and a WPF face. It helps enormously that they share the same presentation philosophy, the same UI specification language (XAML), the same client-side execution model, and many of the same components.

According to my calculations for Silverlight v.3, you will be able to re-use between 52.6% and 93.7% of your code-base to support both platforms.

I’m sure you are wondering … why the big spread?

Let’s walk up the application stack and evaluate the opportunities for re-use at each level.

Let us stipulate that we can use the same database regardless of client technology.

You can write a 99% common data access and business layer … at least you can if you adopt my company’s DevForce product; Rocky’s CSLA.NET for Silverlight may be another option.

This high percentage presupposes that you are prepared to use the same asynchronous server-access in your WPF application that you must use in your Silverlight application. Silverlight only permits asynchronous communications with the server. This means you can’t issue a query and block the UI thread until the data arrive. You must design and develop a user experience that keeps going while the program is waiting for data.

Some argue that this is a good idea anyway. Unfortunately, only a handful of developers have experience writing non-blocking UIs. You should anticipate a slower initial pace of development as the team learns to program in async style.

North of 90% of your non-visual application layer classes can be written once and “shared” between regular DotNet and Silverlight assemblies.

The word “shared” deserves at least passing comment. The DotNet and Silverlight assemblies often look alike but they are not the same. Your Silverlight projects must be compiled against Silverlight assemblies; your WPF projects must be compiled against DotNet assemblies. Obviously you don’t want to duplicate your code. The trick is to arrange for the two kinds of project – Silverlight and WPF – to share the same physical code files. You can do this manually in Visual Studio but it is far more convenient to use the Project Linker from Microsoft Patterns and Practices.

Rocky Lhotka presented techniques for coordinating bi-platform development in his Tech Ed 2009 talk “WUX313 Sharing Code between Your Microsoft .NET Framework Applications and Microsoft Silverlight”; I hope a public link to his talk becomes available soon; you can always ask Rocky for it.

You can rely on Prism to glue your application together because Prism was built to support multi-platform scenarios.

XAML is the Problem

It is the visual classes – the XAML files in particular – that present a significant challenge.

There is no issue if you’ll have one look for Silverlight and a different look for WPF. The Model-View-ViewModel pattern makes it easy to share the non-visual Model and ViewModel classes across platform; all you have to do is whip up your separate View XAML files and – shazam! - you’re done.

Did he really say “whip up your separate XAML files …”? He’s got to be kidding!

Yes I am kidding. Unless you’re auto-generating your views (which I cannot recommend), you will invest heavily in crafting XAML that both looks good and enhances user productivity.

If you decide to produce different views for each platform – and there are strong arguments for doing so – you’ve just identified the 50% of your application (measured in effort if not in kilobytes) that will differ across platform.

On the other hand, if you intend to use the same views – the same XAML – on both platforms, you can hope for 90+% XAML re-use, thus bringing your total for the application to the coveted 93.7% mark.

So there’s the spread: 50% common code if you have separate views and 90+% if you have shared views. No brainer, right?

Not so fast. The effort and compromises essential to re-use XAML can be daunting. WPF and Silverlight XAML are similar but maddeningly different in critical details. I won’t explore these differences in depth here but I will call out a few of the obstacles.

First, there are many features in WPF that don’t exist in Silverlight 3. Implicit styling is one example but there are numerous others. Because WPF is (mostly) a superset of Silverlight, if you design for Silverlight you’ll have a better chance of retargeting the XAML for WPF.

Second, there are features of Silverlight 3 that are not yet in WPF-proper such as the DataForm. It will show up eventually but you’ll have to wait for it.

Third, some of the features available on both platforms happen to be declared in different namespaces; Shawn Burke posted about this back in November 2008 and I don’t believe the incompatibilities have been resolved in Silverlight 3. If I recall (to be confirmed) the VisualStateManager is one crucial example of a component that is not in the same namespace on both platforms.

As it happens, you can define a namespace that doesn’t exist in your XAML file as long you don’t reference it. Your app will build and run fine with a phantom namespace declaration such as xmlns:dummy="dummy". You might think this would provide some relief. You could define one prefix to refer to the WPF namespace and and a second prefix to  refer to the Silverlight namespace. But which prefix do you use when you want to declare a VisualStateManager? You can’t toggle prefixes.

Fourth, XAML does not support compiler directives (#if/#else/#endif), namespace aliasing, or partial class files. Why does this matter? Because we use all three of these techniques to manage the inevitable differences between WPF and Silverlight implementations … when managing such differences in code.

If XAML supported compiler directives, for example, we could work around the dueling namespace prefix problem with something like this:

<!-- This does not work! -->
#if SILVERLIGHT
xmlns:Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
#else
xmlns:Controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
#endif


You can find a XAML pre-processor that will recognize and resolve compiler-like directives in XAML. Sadly, you won’t be able to use the visual design tools (e.g., Blend) because they won’t recognize or honor the directives.



I hope you will join me in asking Microsoft to make support for conditional XAML a priority.



Netting It Out



It is reasonable to contemplate writing a single application that sports both a WPF and Silverlight client experience.



It isn’t automatic. Microsoft could make it easier … and eventually will. But the important take away is that you can do it and it is relatively easy today if you are willing to write distinct Silverlight and WPF XAML files.



In a future post we’ll talk about who wants to write a WPF+Silverlight application and why.


Read more of this post!

Wednesday, May 27, 2009

Are We Overselling Prism?

A very good friend just hung up on me in the middle of an IM exchange about whether “we” are over-hyping Prism and recommending it for situations in which it is overkill. He said yes; I said no.

Ok, he didn’t actually hang up on me; our IM connection failed.

I’m replaying our exchange … and because he bailed,however involuntarily, … I get the last word.

-----

Friend: [So-and-so] thinks that [some people] are starting to push Prism in cases where they shouldn't.

Me: Such as?

Friend: They are saying that anyone who builds line-of-business (LOB) applications with Silverlight should use Prism. He doesn't agree. He thinks that most of Prism is good only for Composite UI, with a few exceptions like delegate command, and the project linker. I agree with him. Prism is not the “end-all” for every solution.

Me: True ... but it's the right call for modular solutions. And the bootstrapper + Dependency Injection (DI) are pretty much central to anything I would build.

Friend: Anything YOU build yes. But I don't think you can assume that DI is a given. You can't make using DI a “must”. Sure, for composite apps it makes total sense. For TDD (Test Driven Development) and decoupling of components yes ... but I won't go as far as to say "you must".

Me: It isn't a “must”. Nothing is a “must”. But come on ... once you're comfortable with DI, you never want to be without it again. It is trivial to put in place, easy to use, and it makes writing single-responsibility code every so much easier. And testing, by the way, is NOT why I like DI. You get the major benefits of DI without writing a single test.

Friend: In general I agree but there is a bit of self-selection there. I mean DI appeals to you...and me, and others like us but that does not mean it is something that will work for everyone or that they will perceive the benefits.

Me: No, this is not a case of elitist self-selection. DI does benefit everyone. I think you do the inquiring developer a disservice by supposing that they will be unable to see the value. Look, if you don't want guidance ... if you just want to wing it, then don't ask for my advice. If you want guidance, than I say that something like Prism is good for you in almost any business application.

Friend: Huh? I would be careful if I were you. You’re starting to sound dogmatic.

Me: I'm trying to respond authentically to the developer who asks "how do I build an app?"

Friend: It sounds like you’re recommending a swiss army knife. I would be very wary of that!

Me: No, I don’t thing so. There are some standard problems in any business app ... and Prism ... or parts of it anyway ... and I include it's promotion of certain patterns ... Prism addresses those standard problems. DI is NOT a swiss army knife part. Neither is the bootstrapper. And every app has some kind of shell. These constructs are basic to just about any application.

The other Prism components you may safely ignore until you need them. You may not need Regions and Commanding and Event Aggregator during the first weeks. Not to worry. They are non-intrusive. They are waiting for you, quietly, causing no trouble at all. When you do need them, they’ll be ready for you.

Do you want to argue that the presence of unused components is indicative of a "swiss army knife” syndrome? You might as well say that WPF and Silverlight are swiss army knives because they have loads of features you will never use.

Friend: Not the same.

Me: I'm listening. Why not?

Friend: I don't think you can assume that every app must use modules. I don't think you can even assume the bootstrapper needs to be there. Why would I need a bootstrapper? I have Main.xaml as a shell.

Me: I didn't say every app needs modules. You could use Main.xaml as the shell. But what happens is that all of the other jazz that happens at start-up tends to be piled into Main.xaml or App.xaml. This practice is almost always bad. You’re combining the view that defines the application’s screen real estate with initialization logic; these are wildly different concerns. You really SHOULD think about how the application starts as as a thing unto itself. Failure to do so leads to trouble.

Friend: If I am not writing a Composite UI , why do I care?

Me: You care because the app.xaml gets out of control very quickly as more and more initializations mingle with the code to support how your application hosts it’s views. That is the “shell” function. I’m talking about all of the little services you’ll need – logging, authentication, authorization, persistence, email - you want to register them somewhere. This is bootstrapping, not view hosting; these start-up activities belong in a dedicated class.

And if you're NOT thinking in terms of these services – if you’re thinking you’ll introduce these capabilities by “new-ing” up classes or referencing singletons wherever you need them – you’re heading straight for the kind of hopelessly entangled, brittle application that gets progressively harder to maintain and evolve.

Friend: You realize you do come off a bit biased don't you? I know everything you are saying and am being a bit of devil's advocate.

Me: I realize I am talking to you and so I can make some aggressive claims in my argument without serious risk of contradiction. I don’t think my present approach will persuade the uninitiated. But I resist the notion that I am being “biased”. By charging “bias” you are suggesting that I am somehow an unthinking captive to an ideology. That’s the easy, simplistic way to dismiss advice of any kind.

It is not just a “bias” when I tell you that maxing out your credit card with no ability to pay puts you on the road to trouble.

I see a lot of applications. I see a lot of applications go wrong. They tend to go wrong in the same way over and over again.

The concepts that Prism fosters help you find a way out of those familiar mistakes.

Friend: look I am not saying Prism is bad ...

Me: And I will agree that it is not a magic bullet.

But it is more than a collection of components, more than a bag of tricks. If it were only that, you could argue that the tricks were needed only for applications of sufficient sophistication.

I think Prism is something completely different. I think it is is a lens that helps us see farther and more clearly. Through that lens we can find solutions to the problems that would otherwise mire us in the half-measures that gradually slow our progress and make our code stink.

And, by the way, when I say “Prism”, I mean it to stand in for any such ensemble of guidance and infrastructure code. What Prism-like thing you actually use could come from anywhere; you could write your own. The Prism that comes from Pattern and Practices is just an instance of what I have in mind.

Instant Messenger: Your friend signed off at Wed May 27 01:36:30 2009. This user is offline.  Your messages will most likely *not* be received!

Me: Grrrr

------

Feel free to chime in yourself.


Read more of this post!