- Monday @ Gamefest, the XNA team announced XNA Game Studio 2.0. The two big new things are support for the entire VS product line (1.0 only works on VC# Express) and the addition of networking APIs. Let’s Kill Dave has a good wrapup of the announcements from Gamefest Day One.
- Speaking of Xbox 360, I played thru the demos of Stranglehold and Bioshock. Two thumbs up on both. It’s gonna be an expensive year for Xbox gamers.
- Mark Cuban noodles on taking your house public. “Why not create a market or exchange where homeowners can sell equity in their homes?” I’ve thought about this myself from time to time. However, Mark thinks making it happen would “probably take the country’s biggest banks working together”. I wonder if there’s a more Web 2.0 social lending approach that would work better.
- Jeff Atwood calls virtualization as “the next great frontier for computer security”. I agree 100%. But I don’t think the action is going to be in “full-machine” virtualization like Virtual PC. Rather, it’s going to be sandbox virtualization. Jeff mentions GreenBorder (now part of Google) but it’s not the only solution. Some time ago, Microsoft acquired SoftGrid which uses sandbox virtualization for application deployment, but using SystemGuard for security sandboxing seems like a logical step.
- The WCF LOB Adapter SDK has released. Sonu Arora has the details. As part of the Integration team @ MSIT, I have a feeling we’re going to become fairly familiar with this technology. (via Jesus Rodriguez).
- Speaking of Jesus, he thinks the six new SCA4SOA committees are “going to help”. Why? Because inventing technology in committee has turned out so well in the past?
- John deVadoss cements BPM’s fad du jour status by contrasting “big” BPM and “little” BPM. It’s fairly obvious to me that big *anything* just doesn’t work in the enterprise. But I worry that little *anything* doesn’t work that well either. So how long until someone (probably Nick) starts arguing for “middle out” BPM?
- David Bressler wonders “What is it about registries that everyone thinks is a panacea for all things SOA?” Amen, Brother! Joe McKendrick claims it’s required for governance, but then gets to what I think is the *real* reason for focus on registries: the “registry is a tangible offering” that vendors can sell. Just because it’s productizable doesn’t mean you need it.
- Hartmut Wilms responds to my retire the tenets post, but he seems to contradict himself. On the one hand, he suggests that “the four tenets just expressed, what “almost” everybody outside the MS world knew already”. But then he goes on to dispute that the SO paradigm shift has even occurred! Hartmut, I’ll grant you that WCF (among other similar stacks) are way too focused on “you write the classes, we’ll handle the contracts and messages”. On the other hand, if you don’t provide a productive interface that most everyone can pick up and run with, the technology won’t get adopted in the first place.
Morning Coffee 110
Retire the Tenets
John Heintz and I continue to be in mostly violent agreement. It’s kinda like me saying “You da architect! Look at my massive scale EAI Mashup!” and having him respond “No, you da architect! The SOA tenets drive me bonkers!” Makes you wonder what would happen after a few beers. What’s the architect version of Tastes Great, Less Filling? ^[Not that you would catch me drinking Miller Lite. Ever.]
Speaking of the tenets, John gives them a good shredding:
Tenet 1: Boundaries are Explicit
(Sure, but isn’t everything? Ok, so SQL based integration strategies don’t fall into this category. How do I build a good boundary? What will version better? What has a lower barrier to mashup/integration?)Tenet 2: Services are Autonomous
(Right. This is a great goal, but provides no guidance or boundaries to achieve it.)Tenet 3: Services share schema and contract, not class
(So do all of my OO programs with interface and classes. What is different from OO design that makes SOA something else?)Tenet 4: Service compatibility is based upon policy
(This is a good start: the types and scope of policy can shape an architecture. The policies are the constraints in a system. There not really defined though, just a statement that they should be there.)Ah, I feel better getting that out.
As John points out, the four tenets aren’t particularly useful as guidance. They’re too high level (like Mt. Rainier high) to be really actionable. They’re like knowing a pattern’s name but not understanding how and when to use the actual pattern. However, I don’t think the tenets were ever intended to be guidance. Instead, they were used to shift the conversation on how to build distributed applications just as Microsoft was introducing the new distributed application stack @ PDC03.
John’s response to the first tenet makes it sound like having explicit boundaries is obvious. And today, maybe it is. But back in 2003, mainstream platforms typically used a distributed object approach to building distributed apps. Distributed objects were widely implemented and fairly well understood. You created an object like normal, but the underlying platform would create the actual object on a remote machine. You’d call functions on your local proxy and the platform would marshal the call across the network to the real object. The network hop would still be there, but the platform abstracted away the mechanics of making it. Examples of distributed object platforms include CORBA via IOR, Java RMI, COM via DCOM and .NET Remoting.
The (now well documented and understood) problem with this approach is that distributed objects can’t be designed like other objects. For performance reasons, distributed objects have to have what Martin Fowler called a “coarse-grained interface”, a design which sacrifices flexibility and extensibility in return for minimizing the number of cross-network calls. Because the network overhead can’t be abstracted away, distributed objects are a very leaky abstraction.
So in 2003, Indigo folks came along and basically said “You know the distributed object paradigm? The one we’ve been shipping in our platform since 1996? Yeah, turns out we think that’s the wrong approach.” Go back and check out this interview with Don Box from early 2004. The interviewer asks Don if WCF will “declare the death of distributed objects”. Don hems and haws at first, saying “that’s probably too strong of a statement” but then later says that the “contract, protocol, messaging oriented style will win out” over distributed objects because of natural selection.
The tenets, IMHO, were really designed to help the Windows developer community wrap their heads around some of the implications of messaging and service orientation. These ideas weren’t really new – the four tenets apply to EDI, which has been around for decades. But for a generation of Windows developers who had cut their teeth on DCOM, MTS and VB, it was a significant paradigm shift.
These days, with the tenets going on four years old, the conversation has shifted. Platform vendors are falling over themselves to ship service/messaging stacks like WCF and most developers are looking to these stacks for the next systems they build. Did the tenets do that? In part, I think. Mainstream adoption of RSS was probably the single biggest driver of this paradigm shift, but the tenets certainly helped. Either way, now that service orientation is mainstream, I would say that the tenets’ job is done and it’s time to retire them. Once you accept the service-oriented paradigm, what further guidance do the tenets provide? Not much, if any.
Fantasy, Free Code and the SharePoint Model
It might sounds like a fantasy, but Nick Malik really wants free code.
He started talking about
it
a few months ago when he was getting raked over the coals by
debating Mort with the agile .NET community:
Rather than look at “making code maintainable,” what if we look at making code free. Why do we need to maintain code? Because code is expensive to write. Therefore, it is currently cheaper to fix it than rewrite it. On the other hand, what if code were cheap, or free? What if it were cheaper to write it than maintain it? Then we would never maintain it. We’d write it from scratch every time.
Then about a week ago, he laid out the reasons why free code would be a good thing. At a high level (Nick’s blog has the details), those reasons are:
- Lower the cost of IT through reduced skill requirements.
- The speed of development goes up.
- Projects become more agile.
- Solution quality goes up.
Talking about the benefits of free code is sorta like talking about talking about the benefits of dating a movie star. The benefits are actually pretty obvious, but talking about them doesn’t really help you get there from here.
Actually, Nick isn’t suggesting that all code can be free. He’s focused on separating out business process modeling/development from the rest of software development. In essence, he’s describing a new class of developer (should we call the persona Nick as an homage?) who needs their own class of tools and for the IT department to “formally” allow them to “easily develop, test, and deploy [aka host] their processes.” For the most part, these BP developers wouldn’t be traditional developers. They’d be more like software analysts who do the work directly instead of writing specs for developers.
I call this separation of business and IT concerns the SharePoint Model. SharePoint, IMO, does an amazing job of separating the concerns and needs of business and IT users when it comes to running intranet web sites. Only the truly geeky stuff that requires specialized access, knowledge or equipment – installing the SharePoint farm in the first place, keeping it backed up, installing service packs, etc. – is done by IT. Everything else is done by the business folks. Need a new site? Provision it yourself. Need to give your v-team members access to it? Do it yourself. I see similarities in the free BP code approach Nick’s suggesting. I’d even argue that SharePoint is the natural “host” for such business processes. It already supports WF and can provide access to back-end enterprise data via the Business Data Catalog.
On the other hand, some of what Nick suggests seems fairly impractical. For example, he thinks IT should “formally and officially take control of managing the common enterprise information model and the business event ontology.” First off, who officially manages this today? Does such an official information model or event ontology even exist? I’m guessing not. That means you’ve got to start by getting the business people to agree on one. That’s usually a sucker’s bet. Nick also suggests we “reduce the leaky abstractions” in our services. To suggest this is even possible seems incredibly naive.
The good news is the things that will work (evolving BP into its own
development discipline, building custom tools for BP development,
getting IT into the BP hosting business) don’t depend in any way on the
things that wont work (getting lots of folks to agree on anything,
breaking the laws of physics, overcoming the law of leaky
abstractions). I’m not sure it will result it truly free code, but it
sure would bring the costs down dramatically. Thus, I think most of
Nick’s free code vision is quite practical and not a fantasy at all.
As for dating a movie star, you’re on your own.
Another InitImportantThing Approach
I thought of another approach to the InitImportantThing problem that I blogged about yesterday. I think it’s a bit harder to code, but it’s certainly explicit and avoids the magic method that Jon dislikes so much.
The crux of the problem is that ServiceHostBase needs a valid ServiceDescription in order to operate. The WCF team chose to provide said description to ServiceHostBase via the abstract CreateDescription method. But as we saw, ServiceHostBase can’t call CreateDescription from it’s own constructor. So instead, derived classes are forced to call InitializeDescription in their own constructor. Since that call isn’t enforced by the compiler, it’s easy to forget to include it. Since the exception that gets thrown doesn’t really tell you what went wrong, it’s easy to spend hours trying to figure it out.
So here’s a better approach: since the ServiceHostBase needs a valid ServiceDescription in order to operate, why not pass it in as a constructor parameter?
ServiceHostBase has a protected constructor with no parameters. But since it needs you to call InitializeDescription in your derived class constructor, it really needs the ServiceDescription, a collection of ContractDescriptions (also returned from CreateDescription) and a collection of base addresses (passed into InitalizeDescription). If these were parameters on ServiceHostBase’s constructor, it could validate that information directly, without needing abstract or magic methods.
The one problem with this approach is that the creation of a ServiceDescription is non-trivial. ServiceHost’s implementation of CreateDescription generates the ServiceDescription by reflecting over the service type. You still need that code, but now you would call it from the base constructor initializer instead. That means it has to be a static method, but otherwise it would work just fine. Here’s yesterday’s code, updated for this approach:
public abstract class Base { public Base(string importantThing) { if (string.IsNullOrEmpty(importantThing)) throw new Exception(); _importantThing = importantThing; } private string _importantThing; public string ImportantThing { get { return _importantThing; } } } public class Derived : Base { private object _data; public Derived(DateTime dt) : base(CreateImportantThing(dt)) { _data = dt; } private static string CreateImportantThing(DateTime dt) { //this is obviously trivial, but could be much //more complicated if need be return dt.ToLongDateString(); } }
This seems like the best approach to me. You remove the un-obvious magic method call requirement when deriving your own service host while still enforcing the data consistency check in the base class during construction. Best of both worlds, right?
So I wonder why the WCF team didn’t do it this way?
Calling InitImportantThing
Jon Flanders throws a little vitriol at the WCF team fore their design of the abstract ServiceHostBase class, calling the current design “stupid”. Normally, I’m not one to take up for the WCF team. I’ve spent many an hour banging my head against WCF for different reasons but exactly how Jon describes. However, in this case, the WCF team looks caught between a rock and a hard place, where the rock is correct behavior and the hard place is the way CLR object construction works.
The crux of Jon’s beef is that if you build your own ServiceHost by inheriting from SeviceHostBase, it’s not enough just to override the abstract CreateDescription method. You also have to call the “magic” InitializeDescription method in your derived class constructor. If you don’t, CreateDescription never gets called. CreateDescription returns a ServiceDescription instance which is to route messages from the channel layer to the and service layer. Jon writes that “Creating a valid ServiceDescription and returning the list of implemented contracts is essential for making your ServiceHostBase-derived class work.” I.e. it’s really important. Yet, unless you remember to call InitializeDescription, this “essential” ServiceDescription doesn’t get configured correctly. Yep, I see how that might sound stupid.
But if this design is stupid, what would be a better design? After thinking about this specific problem a while, I’m don’t think there is a better design out there.
The question is, when is the right time to set up the service description? Jon called ServiceDescription “essential” to the operation of ServiceHostBase. That implies it should be configured during the construction of a new service host instance. It wouldn’t do to have ServiceDescription unconfigured for some period of time between construction and use. What if the ServiceDescription is invalid or the call to CreateDescription throws an exception? Then you’d be in a position where you could create what looks like a valid service host, but it would throw an exception when you tried to use it. You can see why the WCF team would want to avoid that scenario.
So if you want the service host to have a valid ServiceDescription by the end of construction, what choices do you have? Given that the ServiceDescription depends on derived class data, the only choice is to use a magic method! Here’s an example to demonstrate what I mean:
public abstract class Base { public Base() { } private string _importantThing; protected abstract string CreateImportantThing(); protected void InitImportantThing() { _importantThing = CreateImportantThing(); if (_importantThing == null) throw new Exception(); } public string ImportantThing { get { return _importantThing; } } } public class Derived : Base { private object _data; public Derived(DateTime dt) { _data = dt; } protected override string CreateImportantThing() { return _data.ToString(); } }
I’ve tried to distill out the relevant parts of ServiceHostBase. In the example, Base stores some important thing that gets created by the derived class based on data that’s passed into the derived class’s constructor. Remember, we want the class to be fully configured by the end of the constructor. If CreateImportantThing throws an exception or returns null, we want to know about it right away when the object is created.
In the code above, the magic method InitImportantThing never gets called and thus the _importantThing field never gets setup. This roughly corresponds to Jon’s scenario where he didn’t know to call InitalizeDescription. And like WCF, we can make this sample work by inserting a call to InitImportantThing at the end of Derived’s constructor.
You might be tempted to put the call to InitImportantThing in Base’s constructor. But that won’t work because Base’s constructor runs before Derived’s constructor does. Thus, Derived’s _data field will still be null and the call to CreateImportantThing throws a null reference exception.
The final option would be to place the a call to InitImportantThing in ImportantThing’s property get method, if _importantThing is null. This defers construction of _importantThing until the first time it’s used. By this time, the derived class constructor will have run and so the derived class data will be available for use. This eliminates the magic method call, but it means we don’t know if the instance is valid until we go to use it – i.e. the scenario we were expressly trying to avoid.
So basically, the looks like the WCF team had two choices:
- Err on the side of caution and require calling InitializeDescription in the ServiceHostBase derived class’s constructor.
- Err on the side of easy extensibility and call InitializeDescription the first time the ServiceDescription.
Put that way, what the WCF team ended up doing doesn’t seem so stupid. This is especially true when you consider that the vast majority of people aren’t creating their own service hosts anyway. It would have been possible to do both: explicitly call InitializeDescription in ServiceHost’s constructor but also have an implicit call in ServiceDescription property get if the field was null. But I’m not on the product team, so I don’t know what other tradeoffs that implies. Checking for a null reference seems like no big deal, but I don’t know how often this property gets called.
One other point: even though I don’t think this design is stupid, I agree 100% with Jon that the exception is misleading.The way it’s written, the immediate assumption is that your implementation of CreateDescription is bad, not that you forgot to call InitializeDescription. It turns out that ServiceHostBase is already tracking wether InitializeDescription has been called via the initializeDescriptionHasFinished field. So why can’t it throw an exception like “Dude, you forgot to call InitializeDescription” when that field is false? It wouldn’t make the design any cleaner, but it would have saved Jon hours of digging thru the implementation of ServiceHost and ServiceHostBase in Reflector.