Acropolis @ TechEd: Q2 – Cool applications with little or no code? Really? Are you sure?
Continuing the series of posts on the top 5 Acropolis questions at TechEd 2007...
Now this is a really good question and usually led to a great discussion!
It usually followed in response to one of three things - the demos that we gave, the template and wizard features in Acropolis, or our adoption of XAML as a declarative format for components.
Simple Apps vs Real-World Apps
This question is usually asked in response to some of the demos that we've been showing here at TechEd. Since Acropolis is meant to provide the plumbing for an application (leaving you to focus on your business logic) we took the decision to emphasize the Acropolis plumbing in the demos that we gave. This would allow developers, so our reasoning went, to see more clearly exactly what functionality Acropolis is providing.
For example, in my break-out session I built a simple text editing application and demonstrated how you can swap in and swap out various components to support different patterns for navigation, layout, etc. I show the beginnings of this in the Getting Started video on the Acropolis home page on WindowsClient.net. I chose this example specifically because this application is pretty much all plumbing and does not have much business logic at all - in fact the whole application only has about 20 lines of code (including the pluggable spell check service) - so that I could focus on how the app model fits together and how the visual designers allow you to specify a large part of the behavior of the application without the need for plumbing code.
It seems, though, that some of the attendees that saw this demo got the impression that we were claiming that you could build all applications, at any level of complexity, using just the visual designers. Unfortunately, this isn't the case, as I'll describe below. In hindsight we maybe should have demonstrated building a more real-world application, something that contains non-trivial business logic, but then, no doubt, we'd have spent most of our demo time on business logic code rather than showing off the Acropolis application model. Ho hum...
Templates and Wizards
One of the goals of Acropolis is to let you focus more on your business logic code, and this notion extends to the situation when you first create the project too. One of my pet peeves is when you select File/New Project in Visual Studio and are invariably presented with a blank page or form and are left to go write all of the plumbing yourself from scratch, again.
So we set out to beef up the template system in Visual Studio so that we could provide richer templates for common application types. These templates will define enough of the application's structure so that you can start to focus on business logic immediately after your project is created. When we demo this feature, some developers saw this as an attempt to ‘pigeon-hole' applications into two or three restrictive types, or to just generate the code that we would have had to write before.
But our intention here is not to provide templates for all conceivable types of applications. - we'll probably only ship, say, templates for the 5 most application types - but to give you a much quicker turnaround time between project creation and getting stuck into writing your business logic code. And of course you'll be able to create your own templates, to support, for example, your corporate standard application types, as a way to speed up development.
Acropolis templates will also be configurable via an ‘Application Designer' which will let you choose between the various options provided by the template and give you a visual representation of the overall structure of your application. Again, this lets you start with a application that is as close as possible to the type of application you want to build.
In CTP 1 the Application Designer takes the form of a wizard. At present, the wizard lets you choose between a few simple options but it is not re-entrant - i.e. you can't go back and change your decisions after the initial code is generated, so what we have now is very similar to the old MFC one-shot application wizard. But we know that this isn't a good long term solution. In upcoming CTPs we'll be allowing you to go back and change the options for your application again and again without having to generate a new project and copy all of the code over.
This allows for a more iterative development process. You might start with a default application, implement your business logic code, get it into the hands of some users for feedback, make changes to your applications configurable settings, and then go round again for another round of feedback.
If you've downloaded and checked out the CTP 1 bits, you'll have noticed that we're using a declarative approach to define both the business logic components as well as the visual components of an application. Specifically, we're using XAML (Extensible Application Markup Language) to define business logic components, and to define the WPF user interface for those components.
When we demo this feature to developers, they are often initially surprised because they thought that XAML was exclusively a WPF technology (which we point out is not the case), and then they immediately ask us why we took this declarative approach. One part of the answer is that we wanted to more cleanly separate out the definition, or ‘logical structure', of a component from its implementation. Another part is that we wanted to provide a graphical way for you to define or visualize the logical structure of your component without necessarily having to write or read code.
We are finding from many discussions that this typically leads to a misconception about our intention here. Sometimes, people take this approach to mean that we are trying to obviate the need for code (or maybe even developers) altogether, which they point out is the ‘Impossible Dream' or ‘Holy Grail' of application development. We of course agree that this is unrealistic (at least for now J) - see an interesting discussion on these points here and here.
In reality, we expect that you will need to write lots and lots of code to build a real-world client application, even with Acropolis. Our goal is to allow you to focus your coding efforts on your business logic or business problem and not have to code up your applications plumbing. And of course, technically you could say that XAML is code of a sort...
Using a declarative approach like this, though, provides a number of benefits:
- Using XAML gives you a very concise way to express the structural aspects of your component - not just the external ‘class interface', but how it is structured internally. For example, it allows you to cleanly define how any child components or services that your component uses are configured or interact with each other.
- It allows you to concentrate more on the code that defines the actual implementation of your component. In other words, we want to make it so that 99%+ of the code that you do write is the actual code that will solve your business problem and not plumbing or glue code.
- It is much easier for us (or you) to build visual designers or other tools (including test tools) for your component since its structure is more easily ‘machine-parsable'. It also allows for a looser coupling between the application model and the tools allowing each of them to evolve more quickly.
The last point probably deserves some more detail.
Some visual tools read and write code directly without having an intermediate declarative step. But this is actually difficult and time-consuming thing to get right, since the tool and the model for the code that it reads and writes always have to be in lock-step. Why? Well this approach means that as a developer you can only express your intent in ‘raw' code which in turn implies a specific application model of some sort (i.e. a specific API or structure for the code). If the application model changes, the designer breaks; if the designer changes, it doesn't generate the right code. Having an intermediate and concise way for you to express your intent gives us more freedom to change the designer or the application model independently.
Of course the declarative format defines the ‘contract' between the tool and the application model, and you have to handle changes to the declarative format carefully (there is no such thing as a free lunch) but having this loose coupling allows us to quickly try different ideas and evolve the application model whilst keeping a high level of tool support at all times.
In fact, we expect that there will be a lot of changes and improvements to the application model in the coming months and we didn't want the tool experience to lag by too much. We have heard loud and clear from developers about the problems and woes that poor or late tool supports causes (<cough>WPF</cough>).
What are Connection Points?
Let me give you a specific example of the kind of application model changes we could make without affecting the designers and tools too much. At the same time, I'll answer another common question we often get asked J
In typical Acropolis fashion, we have tried to provide support for the typical or common ways or patterns that components in an application use to interact with each other. We encapsulate these patterns into distinct entities called ‘Connection Points'. We have connection points that represent component to component data exchange and notification patterns, for component to service interaction patterns, and for command handling patterns (we'll be adding more soon, like the pub-sub data exchange pattern that CAB developers are used to).
By dragging and dropping these connection points onto your component's visual design surface, you are specifying the patterns that the component will use to interact with its environment and with other components.
For example, the ‘Command Handler' connection point represents the fact that the component can handle a specific command when it is invoked. As well as the name or type of the command to be handled, you'd probably like to specify the exact behavior of the way that the command is handled.
For example, you'd probably want to specify some information about the command handler, for example a name or description that an external component might use to, say, automatically generate UI for the command (e.g. via a context menu). Or you might want to specify whether the command can currently be handled (i.e. whether the handler is currently enabled or not) so that any attached UI can automatically be enabled or disabled. Or whether the command can be invoked synchronously or asynchronously, and if it can be invoked asynchronously, whether it provides progress events or can be cancelled. Or how the command handler is to be integrated into the command routing system of the hosting application, etc, etc.
Defining all of this behavior in one place is really convenient and natural. Not only can you drop the command handling connection point onto your design surface, but you can select it and use the property grid to configure its exact behavior according to your requirements. We then store all of this information in the component's XAML file for later processing. In effect, the developer has expressed their intent for this aspect of the component's interaction with other components in a nice concise way.
Now, in CTP1 of Acropolis, connection points are actually components in their own right. This allows them to provide a rich, encapsulated implementation of the pattern that they represent. So when we compile the XAML, we generate code that instantiates and configures the actual command handling connection point object.
But what if we decided to change the implementation of connection points? (I'm not saying that we are, just that we could, depending on the feedback that we get J). Say for example, that instead of implementing these behaviors or patterns as distinct objects, we decided to implement them as plain old properties, methods and events on the target component. It would be more difficult (since we'd have more name clashes, etc, to worry about) but we could totally do it. But the important thing is that the intent of the developer (e.g. that the Save command handler should be invoked synchronously and has a description of ‘Save the current document') is the same, only the physical implementation changes. Of course any code that interacts with this behavior might need to change, but at least the designer experience is intact.
So to summarize, we think that the declarative approach provides many benefits (to you as well as the Acropolis team). But at the end of the day, you could still define components and construct applications by writing code without having to write any XAML whatsoever, just like you can construct WPF user interfaces without using XAML.
It's important to note though, that you'll still have to write code for your business logic, and since business logic can get very complicated, you might have to write a lot of it (though hopefully not quite as much as in the pre-Acropolis era J). Our goal is that you shouldn't have to worry too much about the application plumbing though.
Maybe the days will come when we can write a program just by talking to our computers like in Star Trek - "Computer, scan the planet below and give me a list of customers who have ordered Mark IV Phasers but have not yet received them via their in-home matter transporters!" - but where would the fun in that be?