Jeremy Likness

Jeremy Likness is a Senior Consultant for Wintellect with 15 years of experience developing enterprise applications. He has worked with software in multiple verticals ranging from insurance, health and wellness, supply chain management, and mobility. His primary focus for the past decade has been building highly scalable web-based solutions using the Microsoft technology stack.

Posts

January 25, 12:44 PM

I have to admit that I may have rolled my eyes a bit when I first learned about the KnockoutJS library. It sounded too much like forcing a square peg into a round hole. Isn’t Model-View-Controller (MVC) already it’s own pattern? Does it make sense to apply something like Model-View-ViewModel (MVVM) to HTML? I already had enough issues dealing with MVVM on the platform it was designed for, XAML and C# (WPF and Silverlight). Some people simply didn’t get the pattern, others were pushing it without really understanding its benefits, and many applications completely and unnecessarily overcomplicated their implementation of the pattern. So before we talk about whether it makes sense in HTML-based applications, we first need to agree on what the benefits of the pattern are.

I’ve heard many opinions regarding this and have not only read lists, but also published my own. You might hear things like “decoupled code” or “best practices” or “modularity.” Many of the benefits often cited are really just good coding practices that should be implemented regardless of the user interface (UI) pattern being followed. After looking at all of the different benefits, coding using different patterns, and spending several years building enterprise Line of Business (LOB) Silverlight applications it really boils down to two specific benefits:

  1. Testability – MVVM improves the testability of your application. This is only a benefit if you feel that testing itself provides benefits.
  2. Designer-Developer Workflow – MVVM facilitates a separation of UI and presentation logic concerns from the business layer that makes it easy to streamline the development process by allowing design cycles to happen in parallel with development. A great example of this was the Microsoft Looking Glass project that had more than 6 designers working on design for over 3 months while we developed it. The total delivery time was around 4 months, instead of the typical 7 (3 + 3 + 1 month of testing) you get when the design process has to happen sequentially and not parallel to the development effort.

The design-time views even without the workflow are useful but not critical in my opinion. So how does this all translate to HTML-based development?

HTML is Not XAML

The first distinction that Silverlight and WPF developers need to make is between HTML and XAML. They are often compared, but are they really similar?

XAML is a declarative language for instantiating an object graph. While it is commonly used for UI elements, it can create special objects like styles that apply theming to elements, behaviors, triggers, even code that has no visual artifacts whatsoever. XAML by nature is extensible. You can create new elements that map to custom classes, and extend the attributes of existing elements through attachments and custom markup extensions. This strict relationship between the declaration and the object graph means that invalid XAML is a Bad Thing™ and causes the XAML parser to choke. If it cannot instantiate an object or set a property, the entire visual tree is invalid and that’s that.

HTML is declarative markup. It defines a structure. Most of that structure is simply containers for information. There is minimal behavior. Elements are pre-defined based on an accepted standard and arbitrary extension or customization is not supported. The containers provide some structure to information, but it is ultimately CSS that defines the UI and to an extent some of the presentation logic and behaviors. JavaScript handles the object graph for the page, but neither CSS nor HTML declaratively instantiate JavaScript objects. It’s the other way around – JavaScript in the context of a page is more like parsing an XML Document in C# code than it is like having XAML and code-behind. The closest thing to XAML in the web world is server-side code that through whatever mechanism emits the HTML and JavaScript code elements of a web page.

Because HTML is just structure, browsers can also be very forgiving in their parsing. They do not have to map an element to an actual class or type that is instantiated. Browsers will close your tags for you and even make substitutions for elements they don’t recognize. There are well-known algorithms for rendering HTML.

So how does this fit into MVC? First, let’s be clear on one important distinction:

MVC as a Framework, not a Pattern

Note I didn’t say MVC is a framework, but in the context of this conversation we’ll have to agree that I’m referring to MVC as a Microsoft Framework and not the pattern. When you talk about the pattern, it can get very confusing when introducing an entirely separate pattern like MVVM. When you talk about a framework based on the pattern, it’s a little easier to understand. While ASP. NET MVC is based on the MVC pattern, it doesn’t force a strict implementation or interpretation of the pattern and provides quite a bit of flexibility with how you structure your pages. You can choose different view engines and write your code in different languages.

So what about MVVM in the MVC framework? One of the key problems I’ve found when dealing with MVC is markup that looks like this:

<div id="logoDisplay">                
   <% Html.RenderPartial("LogoControl"); %>            
</div>                      
<div id="menuContainer">
   <ul id="menu">
      <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
      <li><%: Html.ActionLink("About", "About", "Home")%></li>
   </ul>                       
</div>

What’s wrong with this? It compiles and runs perfectly fine, right? Here’s my issue: I’ve just lost my designer-developer workflow. True, I might be able to hire an MVC-savvy designer who can work with this code, or I may be responsible for design myself. I’ve seen this workflow before:

  1. Designer creates Adobe Photoshop assets
  2. Same designer or someone else turns it into a beautiful HTML web page
  3. Developer has to rip out the HTML as best as they can and format it into the view and merge into CSS
  4. QA tester finds some strange nuance where a field wraps and unfortunately the designer doesn’t know how to fix it because their version works fine, it’s only in the runtime that it happens
  5. It turns out one of the embedded commands emitted some whitespace that the template didn’t account for and was causing the issue
  6. etc. etc. etc.

This also gives me no design-time experience. If HTML was real HTML without any embedded markup, I could just drag it into a browser and go to town. This is one place I start to see value with MVVM in MVC. I could do the same thing above, but make it look like this instead:

<div id="menuContainer">
   <ul id="menu">
      <li data-bind="foreach: menuItem">
         <span data-bind="text: name">Name</span>
      </li>     
   </ul>   
</div>

Now I’ve got clean HTML that I can hand to a designer. I can even pull it up in a browser and view it to get a preview. Only … there’s still a problem. Can you see it?

The Problem with Data-Bind

Remember how I mentioned that HTML is not XAML? HTML is not supposed to be arbitrarily extended as in the previous example. In fact, most editors will complain about the data-bind attribute because it’s not a valid, defined attribute. Sure, you’ll get away with it: browsers are notoriously forgiving when it comes to bad mark-up, but this is what I would call an invasive or intrusive way to mark up HTML. What would really be nice is if we could do this more cleanly and provide pristine HTML with CSS, then provide our behaviors, validations, etc. in a way that is design-time friendly and testable.

A Clean Approach

For my “clean” approach I decided to model a simple form. It allows for first name and last name, shows the name dynamically as it is edited, and only allows submission when both fields are entered. First, let’s take a look at the HTML. I’m confident I could pass this off to a designer and they could modify it to their heart’s content. The only requirement is that they honor my “contract” which is the specific ids I’ve assigned. We agree there is something called a first name and last name and that they should be consistently referenced as firstName and lastName – whatever else they want to change is up to them.

The full HTML is here:

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>Example MVVM Form</title>
      <link rel="stylesheet" href="style.css" type="text/css" media="screen" />
      <script type="text/javascript" language="javascript" src="jquery-1.7.1.js"></script>
      <script type="text/javascript" language="javascript" src="knockout-2.0.0.js"></script>
   </head>
   <body>
      <h1>Example MVVM Form</h1>
      <p>This is an example of an MVVM-based form. The HTML is "clean" markup - there are no custom attributes, tags, or embedded JavaScript. Everything is wired separately through code.</p>
      <form id="mainForm" action="#">
         <div class="form-label">Full Name:</div>
         <div class="form-field"><span id="fullName"></span>&nbsp;</div>
         <div class="form-label">First Name:</div>
            <div class="form-field">
               <input id="firstName" class="textField" type="text"/>
               <span id="firstNameValidation" class="field-validation"></span>
            </div>
         </div>
         <div class="form-label">Last Name:</div>
            <div class="form-field">
               <input id="lastName" class="textField" type="text"/>
               <span id="lastNameValidation" class="field-validation"></span>
            </div>
         </div>
         <input type="submit" class="formButton" value="Save">
      </form>
      <script type="text/javascript" language="javascript" src="./viewModel.js"></script>
      <script type="text/javascript" language="javascript" src="./mvvm.validations.js"></script>
      <script type="text/javascript" language="javascript" src="./bindings.js"></script>
   </body>
</html>
Now that we have a page we can easily edit, let’s make it a little prettier with some simple CSS:
body {
    font-family: arial, helvetica, sans serif;
}

h1 {
   color: maroon; font-size: 20pt; font-weight: bold;
}
p {
   font-size: 12pt; 
}
.form-label {
   font-weight: bold;
   float: left;
   width: 200px;
   padding: 10px; 
}
.form-field {
   padding: 10px;
}
input.textField {
   width: 300px;
}
input.formButton {
   width: 100px;
   background-color: lightgreen;
   border: 2px solid green;
}
input.formButton:hover {
   background-color: lightred;
   border: 2px solid red;
}
.field-validation {
   font-weight: bold;
   padding-left: 10px;
   color: red;
}

The view model is easy enough, it simply defines fields for the first and last names and a computed field that shows the full name. I’ve even been kind enough to humbly supply a default first name:

function NameViewModel() {

   var self = this;

   this.firstName = ko.observable('Jeremy');
   this.lastName = ko.observable('');

   this.fullName = ko.computed(function() {
      if (self.lastName()) {
         if (self.firstName()) {
            return self.lastName() + ', ' + self.firstName();
         }
         return self.lastName();
      }
      return self.firstName();
   });
}

var viewModel = new NameViewModel();

What’s nice about the MVVM approach is that I can easily extend the view model to provide validation. I will eventually use the JavaScript module pattern to create the validations so they can be easily attached and extended, but for this simple example I just used a simple object instead. In this case there is simply a required validation. In a full production system, I would have a library of these validations and also keep a collection on the target object to allow multiple validations to attach to the same attribute.

ko.extenders.required = function (target, overrideMessage) {
    
    target.hasError = ko.observable();
    target.validationMessage = ko.observable();

    function validate(newValue) {
        target.hasError(newValue ? false : true);
        target.validationMessage(newValue ? "" : 
             overrideMessage || "This field is required.");
    }

    validate(target());
    target.subscribe(validate);
    return target;
};

function MvvmValidations() {
    
    this.required = function(target, overrideMessage) {
        target.extend({ required: overrideMessage });
    };

}

Now I have a view model specific to my view and a validation library that I can reuse across multiple views. I tie them all to the HTML like this – note that what is important is that the contracts were honored for the identifiers of the various elements, but everything else can be simply attached and declared.

$(document).ready(function() {

   $('#firstName').attr('data-bind','value: firstName, valueUpdate: "afterkeydown"');
   $('#lastName').attr('data-bind','value: lastName, valueUpdate: "afterkeydown"');
   $('#fullName').attr('data-bind', 'text: fullName');
 
   var validations = new MvvmValidations();

   validations.required(viewModel.firstName);
   $('#firstNameValidation')
   .attr('data-bind','visible: firstName.hasError, text: firstName.validationMessage');

   validations.required(viewModel.lastName, "Last name is required."); 
   $('#lastNameValidation')
   .attr('data-bind','visible: lastName.hasError, text: lastName.validationMessage');

   viewModel.saveName = function() {
      if (viewModel.firstName.hasError() || viewModel.lastName.hasError()) {
         alert('Errors exist.'); 
         return false;
      }
      alert('Looks good!');
      return true;
   };

   $('form').attr('data-bind', 'submit: saveName'); 
 
   ko.applyBindings(viewModel);

});

You can view the end result and download the source here: http://apps.jeremylikness.com/samples/knockout-mvvm/mvvm.html

Quod Erat Demonstrandum

So what have we achieved? I think quite a bit. This format has allowed me to build out a website using data-binding. The source HTML is clean and can be edited easily by a designer. While I muck around with the DOM at runtime, this is done programmatically and doesn’t require that I invade the HTML or CSS. The JavaScript is separate, reusable, and testable.

The thing I haven’t shown is how this fits into the MVC framework. In the framework you’ll likely go ahead and use some of those helper methods to specify the path to the JavaScript but you should be able to maintain a nice, clean HTML core. And if the view models seem like a lot of work, you’re not thinking about the bigger picture. With a strongly-typed view (one that correlates to a typed model) you can easily create a view helper that emits the necessary JavaScript for the view model. You could probably even emit the code to generate the bindings, and the only step you would need to take as a developer would be to write the controller to return the model and apply any validates specific to the view.

At the end of the day, I’m a believer that MVVM can work in MVC if we remember that HTML is not XAML and approach the code the right way.

January 22, 02:52 PM

I created a quick video to help you get started with using Jounce. The video starts with a blank slate, steps through installation of Jounce and the creation of a sample view model for a simple contact record that includes validation.

You can access the video directly at http://vimeo.com/jeremylikness/jounce-getting-started, or view it below:

Jounce: Getting Started from Jeremy Likness on Vimeo.

January 21, 06:47 PM

I'm pleased to announce the official release of Jounce 2.0 for Silverlight 5. There are quite a number of new features available that I'll review in this post. Most significantly, of course, the code base has been updated specifically to target Silverlight 5. A number of bug fixes, feature requests, and Silverlight 5 features have been added. The DLL for Jounce is still just under 100 KB for release so it remains nimble and lightweight.

There are two ways you can install the latest. Zip over to Jounce at CodePlex to download the binaries and/or the full source. Or, jump into NuGet and install the Jounce package. The package is set up to wire in a default application. To get this functionality, follow these simple steps:

  1. Create a new Silverlight application. I recommend the basic "Silverlight Application" template as I haven't tested with any others, and it doesn't matter if you host it in a web site and/or choose to use WCF RIA services.
  2. Delete the App.xaml and MainPage.xaml files. Trust me on this one.
  3. Jump into the package manager console and type Install-Package Jounce.
  4. Hold down CTRL and press F5 and you should see a welcome message. That's it. You are ready to write your Jounce application.

What's New

The code base is now CLS compliant.

The application service used to wire Jounce now exposes some configuration properties. You can use this to have Jounce ignore unhandled exceptions (by default, it will intercept these and publish them as a message instead) and also to set the debug level. These used to be parsed from the parameters from the object tag but obviously this did not make sense for OOB applications.

When dynamically loading XAP files (i.e. extension or plugin modules) you can specify a callback that Jounce will call to report progress. This allows you to have more control over the extension points and display a progress message to the end user for example.

The processing of the XAP file URL was updated to allow query strings. This is a common method to dynamically serve up XAP files and/or to manage updates for OOB applications. Jounce used to choke on this but the code was updated to gracefully handle this when you specify the URL to the XAP to download.

You no longer have to derive your view model from the BaseViewModel class. The only requirement for the framework to work is for you to implement the IViewModel interface. This will help developers who wanted to provide their own base class services and found it difficult due to the face you cannot derive from more than one base class (hey, I managed to sneak in a basic interview question).

You can specify an option using metadata to automatically call Deactivate on your view model when the corresponding view is unloaded (i.e. if the Unloaded event fires). This allows you to perform clean up automatically when the view goes out of scope.

You can now map a view to a view model in three ways. You can export a ViewModelRoute, you can fluently bind them using a new interface, and you can specify the view model in XAML. The new MapToViewModel custom markup extension allows you to specify the view model name, whether you want a shared or non-shared copy, and whether the Deactivate method should be called when the view is unloaded. This makes it possible to use templates that bind to new instances of view models.

There is additional support for the OOB windows. You can append parameters to the navigation payload or use some fluent extension methods to specify the title and size of a view and have it loaded into a separate window instead of a region. You can also raise events with a title to set the title of the HTML page (in browser) or OOB application (out of browser). To further support OOB, there are additional attributes you can query on the base view model to determine if the application is running out of browser and whether or not it is installed on the user machine.

There is a new class available called CustomType that allows you to construct a dynamic type that is bindable to view models. For example, you might parse a JSON object and use this type to build up the object. It features methods to add new properties and fetch them and will also act as a dictionary with an indexer. It uses an underlying helper class that takes advantage of Silverlight 5's ICustomTypeProvider. You can use the source as a template to build your own custom types (or derive from it instead).

I will update documentation and examples as I can moving forward. My book, Designing Silverlight Business Applications, has many examples of building applications using Jounce including WCF RIA. Thanks everyone for their patience and support of this project!

January 07, 06:34 PM

In 1983 author James Martin published a book called Managing the Data-Base Environment. It’s interesting the term database is hyphenated in the title; it hadn’t quite settled down as a mainstream term yet. I have not read this book myself, but my understanding is that he presented the concept of the “CRUD Matrix” for engineering how an application performs Create, Read, Update, and Delete operations against the database. Regardless of how the term was first coined, it has gained popularity and is in widespread use today.

CRUD is a model that has existed for decades. A large number of software systems can be classified as a simple combination of CRUD + validation. This is why so many scaffold frameworks provide nearly the same pattern: list records, select record, view detail, edit or delete, and validate a bit along the way. If you are working on an application that follows the pattern of view data, pull it in, do stuff with it, then push it back out, you have an amazing number of options to build it quickly and easily with little ritual or ceremony involved. I see this approach quite often in the development of consumer-facing applications. One track focuses on the engine to present the content to the consumer while the backend system to configure and set up content is quickly generated using a data-driven tool.

If all software operated in CRUD mode many of us might not be employed because it would be so easy to pull CRUD instances out of the assembly line. Software can be quite complex, however, and often models more complex business processes that introduce workflows and state machines that aren’t easily captured with the traditional CRUD model. This fact has led to movements like DDD or Domain-Driven Design, which according to the community website is not a framework or technology but a “way of thinking and a set of priorities.” You focus on the business model and domain, paying attention to important details such as having a common vocabulary that everyone can use to describe the requirements without ambiguity. The source for this concept is defined in the popular “blue book” by Eric Evans called Domain-Driven Design.

A set of new patterns for manipulating data has also emerged to challenge the traditional CRUD model. You can go back to Bertrand Meyer’s Command Query Separation and then examine more recent Command Query Responsibility Segregation (CQRS) pattern by Greg Young to start digging into these principles. A number of implementations exist, including the concept of Event Sourcing. All of these are great patterns to learn and understand as part of your software development toolbox.

While the paradigm shift away from traditional CRUD approaches is refreshing, it can also be problematic. There is always the risk of falling victim to the “flavor of the day.” When I began building Silverlight applications, I was reluctant to fully embrace the MVVM pattern because it was consistently hyped as “the way to go” without very much substance around why it was the way to go. I kept sorting through the catchy phrases like “decoupled code” and “SOLID principles” trying to find the value and bottom line for using this pattern, but it wasn’t until I implemented it myself and observed it in practice through several projects that I was able to finally decide it made sense. My teams were able to develop software faster through parallel workflows and the fact that I could engage an entire design team at the same time I was building the application rather than forcing the project into a sequential workflow was the real benefit I found in addition to the support for testing.

I’ve watched a similar trend with CQRS. Like MVVM, many people are declaring it “too complex” when in fact a proper implementation can be quite simple. Just like the MVVM cops appeared one day and starting writing tickets when developers didn’t completely eliminate their code-behind files, I see some CQRS police saying “if you’re not doing it this way, it’s not CQRS.” In many cases that may be correct, but I think it also undermines the spirit of the pattern. In some cases the pure implementation is exactly what is needed … but is it a new rule that everything must go this route?

I think you’ll find the strongest proponents and advocates for the pattern will be the first to say you should use the right tool for the right job. In my book about designing LOB Silverlight applications I added a controller class to an application that is mostly based on the MVVM model. I also include examples with logic in the code-behind. To some this may seem like sacrilege but in fact these cases were the right tool for the right job: they solved the problem while keeping it simple without compromising the ability to test the application.

I learned about the danger of “either-or” thinking back when I was a personal trainer and had an online coaching practice. I found many clients would get stuck in the either-or mentality. For example, “either I completely eliminate soda or my diet is blown.” Rather than, say, cutting back to just one glass a day for awhile. When traveling, I’d hear, “I can’t get my steamed chicken breast and broccoli so I’m just going to get a big pile of junk from a fast food restaurant” instead of looking for healthier options. “The only thing we had to eat was pizza.” Well, sometimes that happens – but instead of eating fifteen slices, why not just eat one? When I taught clients it is okay to compromise – if your workout calls for free weights but your hotel only has dumbbells, go ahead and train with what you have and get a workout done rather than using it as an excuse to sit in the hot tub for an hour – they had tremendous breakthroughs and were able to achieve a true lifestyle change rather than getting stuck in a diet cycle that was doomed to fail and send them back into old habits.

What does this have to do with software? I think quite a bit. You don’t have to take an either-or approach to building applications, either. For example, it’s not a question of using the entire Prism library or Enterprise Library in an application. It’s perfectly valid to pull out the parts you need – maybe the command implementation from Prism and the logging application block from the Enterprise Library – without overcomplicating the project. When you are looking at patterns, it’s fine to create something that is a hybrid if it fits the needs of your application.

Back to CQRS. I think Microsoft has provided some incredible tools for exposing data as services. With the combination of the Entity Framework and WCF Data Services I can create a set of REST-based services within minutes that are consumable by Silverlight, Windows 8 applications, iPads, iPhones, Windows Phones, RIM devices and Android phones and tablets. It’s just that easy. Unfortunately, while the tools also support CRUD operations (and even provide places you can hook into for validation) it doesn’t always integrate well with a domain-driven approach to the application design. That means it’s off the table, right? CQRS is about having different databases, right?

I’d say, “Wrong” on both counts. If the model works well for querying data, configure it to allow queries and get your read operations up and running in minutes. Sometimes over 80% of your application may be about querying and displaying data, so why not keep it simple and expose it in a way that is easy to expand to other platforms when and if needed?

But what about updates?

The updates don’t have to follow the same set of interfaces if you don’t want them to. It’s perfectly valid to expose a REST interface or even a RPC-based interface that takes commands rather than “update operations.” Why not? You may have a workflow engine backed by state machines and queues that implement Event Sourcing, and that still doesn’t mean you can’t expose the read interface for your data using WCF Data Services out of the box.

My point is that CQRS provides what I think is a very valuable insight: that how you read and query data is probably very different from how you manage, update, and manipulate data. You don’t have to have a picture-perfect implementation of CQRS to take advantage of this concept – it may be as simple as looking at a different set of interfaces and implementing them using different technologies in the stack. I’ve built implementations based on this philosophy that still have one database and one data model using the Entity Framework but provide multiple implementation paths. They allow me to quickly and easily update the model while keeping the code simple and easy to both understand and maintain.

There are some exciting new patterns and approaches to building software that developers should be aware of, but it’s important to look at these as new tools, not new toolboxes. During decades of enterprise software development I’ve rarely watched the toolbox change – it’s almost always been about adding new tools and throwing old ones out. I still see applications that will benefit from the traditional CRUD model and get overly complicated when someone tries to force them into something different. To make a long blog post short: patterns should not be used to define your software, but rather to help solve the problems your software addresses.

December 28, 04:07 PM

About a week ago, I purchased a Samsung Series 7 Slate PC to learn more about the Windows 8 operating system and to test applications I will be developing primarily with C# and Xaml. The laptop ships with Windows 7 installed, but I quickly wiped the existing install and overlaid it with Windows 8. The process for the most part went smoothly. I had to acquire some Windows 7 drivers and install them in compatibility mode in order for the tablet to recognize orientation changes, and I still cannot get the hardware Windows start button or the accelerometer to work. I expected some issues like this as Windows 8 is still a preview OS.

I’ve used the combination of the slate and the operating system quite heavily over the past week and I wanted to take the time to share my impressions in a post while they are still fresh. I’m trying to focus this review more on the OS itself and will call out where I think there are substantial hardware differences.

Summary

Overall, I like it. I’ll preface that with the statement that I am a developer so my opinion is certainly biased compared to what consumers might think. The OS provides the perfect balance between a “total slate experience” which I consider to be watching movies, casual browsing, email, and news readers, and “power user features” like developing software or drilling into a complex Excel spreadsheet. All it takes is a simple external keyboard to efficiently write books and articles and even build software. While the new OS is in beta form and there are not many native applications to choose from, the backwards compatibility makes it possible to install any number of existing touch solutions.

Let me break down where this opinion comes from. I’ll start with the cons.

The Bad

  • Price – this is what I believe still stands as the greatest barrier to general adoption by consumers. The price point is just too high. The idea it can run all of Windows may be appealing to businesses, but not to the average consumer who is comparing this against Android tablets, iPads, and newcomers like the Kindle Fire. If you pay a competitive price for a Windows slate today, you get an inferior product. The Samsung performs well but also is priced well above the nearest competition at well over $1,000.
  • Power – unfortunately I have yet to work with an Atom-based slate that performs well. My standard is to pull up Netflix and run a high definition movie full screen. On a Windows tablet this does several things. First, it loads the Silverlight plug-in and extends the browser environment, and second, it tests the combination of processing that takes place in the Netflix app and the graphics processing happening through the hardware. Unfortunately most of the devices fail miserably for this, and you have to go to an i-series chip. That gives you the power, but means a thicker tablet with a fan and vents.
  • Battery – this ties into the issues listed previously. While the battery is certainly longer than a lot of lap tops – I was watching full screen movies in HD and it lasted hours without draining – it does not go anywhere near the 8 – 10 hours users experience with competing tablets. I believe this is due mainly to the processor architecture and while the alternate system-on-chip processors probably will break this barrier, they will need to perform far better than what I’ve seen so far to make the experience worthwhile.
  • Start Menu – I like the start menu. The concept of live tiles is great, because it turns the start menu into an interactive, “at a glance” dashboard. However, it is not without flaws. First, “grouping” tiles together really doesn’t do anything for me except maybe organize them visually. I want a functional way to group so I can drill in. The idea is as few taps and swipes as possible, which means drilling down, not swiping across. Second, everything ends up as a tile. This may be fine for me, a developer, who knows how to unpin and organize but will be overwhelming to the average consumer. If an install like Office drops fifteen apps, why not organize into a folder by default and have the folder appear on the start menu, and let me drill down and bring common applications back to the top as needed? After installing everything I needed to make the slate productive for me – Office, Live Essentials, etc. – the start menu became so huge I found myself doing nothing but swiping and swiping to get to what I needed.
  • Task Switching – Give me a break. Two experiences? The side swipe is fun to demo and cool when you have two applications, but come on, who really only ever runs two applications? After loading up about five or six applications, continuously swiping across to find what I want is ridiculous. What’s worse, there is no integration with the desktop applications. If you have Explorer, Word, and Outlook running, you get one swipe for “Desktop” and then must ALT+TAB to go between your desktop apps, then either swipe or hit the start button to get back into the Metro applications. Not a good experience. Why not provide an aero-like view or cover flow style preview of the applications when I swipe so I can quickly tap on the one I want? Even a grid of thumbs would be preferable to multiple manual swipes.
  • Consistency – While I like the features and customization options that are available, it’s a little weird that half of the control panel is Metro and the other half dumps you to the desktop and back into the familiar Windows 7 dialogs. Why not finish the experience and make it consistent? You also are shifted to the desktop every time you launch a desktop application, which annoyed me at first but I found I quickly got used to and didn’t mind as much – I’m more irritated about the lame experience trying to swap tasks
  • Ribbons – I get it. The ribbon is the Microsoft UI widget of the future. It’s appearing everywhere. I like the ribbon, and it makes sense in a lot of applications. While I resisted the newer Office releases in the beginning because of the new interface, after using it for years now I’ve come to enjoy it. But here’s a news flash: it’s not the same on a slate. On a touch-based device I want to have context where I touch. That means if I’m navigating the file system, I want to be able to tap on a file or folder and right there see my options and quickly tap through. It’s not a smooth experience to tap down there and then look up there to the ribbon and then find the right place on the ribbon to tap. May have worked well on the desktop, not so fun on the slate. This is weird too because it gives the impression of OS schizophrenia. In the “Metro” portion I have an experience highly tailored to touch that feels right, responsive, and is enjoyable. In the file system explorer for the same OS, suddenly I’m forced to a completely different paradigm that doesn’t feel natural at all. Was it two entirely different teams working on these features? Why are they so different? I don’t buy that it’s because “it’s part of the desktop experience” – no, it’s not. Anything I can reach in my slate is part of the slate experience, whether or not it happens to fall into what was the traditional desktop.

The Good

  • Boot Time – while some may say competitive slates boot quickly, the fact that this boots so fast and provides full-blown Windows capabilities to me is amazing. My slate literally boots in seconds – that’s from a complete shut down. It is fantastic and I no longer dread turning on my machine because I have to figure out something to kill time while it’s booting – it’s that fast.
  • Windows – some people argue this is not a feature and may be a detriment to slates, but I disagree. The fact it is full-blown Windows and not a trimmed-down version is why many customers want a Windows-based slate. It was a key driver for the project I did with Rooms-to-Go. I love it. I installed Office and can easily navigate through Word documents, PowerPoint, and Excel. Sure, sometimes it requires using a keyboard, but the option is there. It gives me my built-in Windows security, allows me to use policies and gives me access to a ton of software that simply isn’t available on competing slates.
  • Backwards Compatibility – while this is just a beta the backwards compatibility so far has been outstanding. I’ve not had an issue installing any Windows 7 productivity software I wish to use. Even drivers for the Slate that aren’t yet available in Windows were successfully installed using compatibility mode. My Amazon Kindle for PC application works beautifully so there’s no need to pick up the hardware, I’ve got my “Kindle” right here. I’ve also had a lot of fun playing with the applications that ship with the Microsoft Touch Pack for Windows 7 that uses Microsoft Surface technology.
  • Silverlight – there was a lot of fuss about Silverlight and it being a dead-end but I’m happy to share it is not only fully supported on the slate, but shines. Some of the best applications I have aren’t written for Windows 8; they are written in Silverlight and run fine as Out-of-Browser (OOB) applications on the slate. Some that stand out are the USA Today Windows Touch application, Mosaic by Tribune, and Telerik’s Facedeck Silverlight Client for Facebook. Oh, did I mention I can just chill at night with headphones and watch my favorite Netflix movies in full screen high definition?
  • Metro – I like Metro. There are things that I believe could be improved, but to me the advantages include:
    • Live Tiles create a true “dashboard” and at-a-glance experience, showing me insights without having to open an application. The tiles just need a better way to organize them.
    • The Metro guidelines (no pop-ups, overlapping windows, etc.) make for a very crisp, clean, enjoyable experience. I am able to easily navigate between applications and they are very responsive. The task switching must be improved, however, and better integrated with the desktop experience.
    • Charms and Application Bars to me make sense and once you understand the gestures make it very easy and consistent to navigate within applications. I really found the slow swipe from the right to get a full menu is something I use a lot, and enjoy the at-a-glance signal, battery, and time in addition to quick-jumps to other areas.
  • Keyboard – the Windows 8 keyboard is awesome. It’s nice and big and easy to type. I have long, complicated passwords and tapping them out is a breeze. My only gripe is the fact that you have to switch to get the numeric keyboard which can slow that down. The highlights and sound provide just the right amount of feedback to make the typing feel natural. The split keyboard is awesome for some major thumb-typing while grasping the sides of the tablet.
  • Pen and Handwriting Recognition – the pen is very powerful. I wanted to spend some time with family while I was editing the final chapters of my Designing Silverlight Business Applications book, so I settled down in the family room with my slate and pen. To my surprise, I was able to be very productive. It was easy to highlight with the pen, and the handwriting recognition was superb – I very rarely had to correct it’s interpretation and my handwriting is abysmal. I was able to have a productive, casual editing session without lugging around a laptop or even pulling out a keyboard. The combination of handwriting and touch makes for a very powerful and productive experience.
  • Search – while I still feel the tiles could be better organized in the start menu, I love the integrated search. It’s fast and easy to use and the fact you can search within a context and even pass searches to other applications is awesome (sorry, can’t think of a better way to say it).
  • IE10 – this may be strange coming from someone who listed Silverlight as an advantage when the IE10 Metro implementation does not allow plug-ins, but let’s face it: 2011 was the year of HTML5 and it is rapidly growing with adoption. I have no qualms about switching to my desktop IE version to run Silverlight applications when most of them are OOB applications that I can launch with a single touch from the start menu anyway. For most web sites, the built-in IE10 browser is all I need. It provides a great browsing experience, renders well, and provides all of the interaction I need. I use the built-in browser often and enjoy the browsing experience – I’ve even started to use YouTube in HTML5 mode although not all videos are available and you have less control over the experience. I especially like being able to pin sites from IE10 to my start menu.

As you can see, there are a lot of pros to weigh against the cons. In summary, I’m very pleased with where the slate experience is going but I’m also concerned. I’m a power user – a developer – so I like falling back to heavy desktop applications, don’t mind doing a little extra to get around, and also am used to shelling out more dollars for my toys than average consumers might be willing to. I think the biggest obstacle to overcome is providing performance at a lower cost to increase value and get rid of fans and fat form factors. The Metro experience needs a bit of work before I think my grandmother, grandfather, or niece will be as comfortable with it as they are grabbing an iPad, but I don’t think it’s an impossible task. I’m very excited to see the upcoming beta release that is rumored for February 2012 to see how well Microsoft listened and what steps they were willing to take to improve the quality of the product.

December 10, 11:03 AM

It is very exciting to see the release of Silverlight 5 today, despite all of the rumors flying around the Web. Read the original release announcement from the Silverlight Team here. This is proof positive the team made a commitment to release a new version by the end of the year and stuck to it. This release offers major functionality over prior releases and is something I believe has the potential to revolutionize development for line of business applications, or I wouldn't be writing a book about it. You can download the release here (note that sometimes the servers may take time to synchronize, so if you are not seeing the link, wait a little awhile and refresh ... it will eventually appear for you).

My blog has been covering this for quite some time so I thought it would make sense to recap the coverage I've already provided as well as address some myths vs. facts about this release.

First, a summary of articles I've posted that relate to Silverlight 5:

I will also be releasing a new version of my Jounce MVVM+MEF Framework that fully supports the new capabilities of Silverlight 5 over the next few weeks. You can download the latest source to preview this functionality and I'll consolidate into a 2.0 release probably right after the holidays.

Let's tackle some myths:

Myth: Silverlight is dead.

Fact: Silverlight 5 has just been released. The team has been working hard to implement new features and address issues uncovered through internal and external builds like the beta and release candidates. This release contains significant functionality that make it an ideal platform for building Line of Business applications. Microsoft has also promised to support this version through 2021. That's quite a bit of life!

Myth: Silverlight has no Future.

Fact: We're not sure if Silverlight will have a future release, as Microsoft has not formally addressed this and that is definitely a possibility. That doesn't mean it doesn't have a future. There are plenty of cases where the current version will meet the demands of users sufficiently to warrant future development. The next IDE slated for release, Visual Studio 11, has Silverlight support so the tools are not going away any time soon. Silverlight runs perfectly fine on the new Windows 8 desktop so applications developed using this version will not be obsolete when users move to Windows 8, although by all predictions Windows 7 is going to be around for a long, long time. The biggest enemy of Silverlight right now is not capability nor support, but speculation and rumor.

Myth: The Silverlight team gave up on Mac OSX, this release is for Windows/Internet Explorer only.

Fact: Silverlight 5 is fully supported on Mac OSX and across multiple browsers. The new 3D features rely on DirectX and therefore are not available on the Mac OSX platform, and p/Invoke/COM obviously does not make sense because there is no counterpart. All of the core features including interactivity, printing, etc. are all fully supported as demonstrated by the release candidate (RC). You can see the full list of supported browsers and platforms here.

Myth: Silverlight is no longer the optimal choice for platform reach

Fact: I believe this to be true when you extend reach to smartphones. For desktop applications that will traditionally run on Mac OSX, Windows, and Linux, I still see Silverlight 5 as the viable option for the first two. Obviously lack of Linux support rules that out but I have not found that to be an issue for line of business applications. Most businesses are still putting their heavy applications on Windows with a smaller percentage on Mac OSX and Silverlight provides phenomenal capabilities to build the application once and have it run on both platforms, even out-of-browser in occassionally disconnected scenarios. Silverlight is only a viable target for smartphones on the Windows Phone 7 platform. I don't believe this removes Silverlight as a player as it depends on the level of native touch you want for your application. A high-touch application will likely require developing with Silverlight for Windows Phone, Objective-C for iOS devices and Java for Android unless you are using a tool that provides multi-targeting like the Mono suite. On the other hand, if you can get away with less native touch and functionality, HTML5 is certainly a good option for building a mobile footprint once and having it function consistently across those surfaces. Keep in mind however that this does not mean you can build it once and have it run fine on your desktop targets - you'll still be developing different screens. The ability of Silverlight to connect to existing services like REST and WCF end points still makes it a very viable option for the desktop presentation layer even if the mobile footprints are written using an HTML5-based solution.

Conclusion

It's out, it's loaded with features, and it still has plenty of life left in it. Go out and grab the latest version of Silverlight and see for yourself! I'm interested in all comments and feedback below. Thanks!

November 20, 12:00 PM

While writing Chapter 14 of my book, Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series) I focused on an area that is quite common with line of business applications: extremely large data sets. In the example I generated almost 1,000,000 contact rows to illustrate how they would be managed by the Silverlight client. Like many software problems, there are many solutions; here is an excerpt of the three I demonstrated in the book.

All of these solutions use the Entity Framework for data access. How that data access is projected to the client is illustrated bythree different patterns: OData (the straight services, not the checkbox on the WCF RIA Services tab), WCF RIA Services, and using the MVVM pattern. To simplify the examples I'm only focused on reads here. Writes do add a layer of complexity and change tracking, but I argue that the problem to solve there is not how to manage a large data set because anything the user actually interacts with is going to be a smaller order of magnitude.

RESTful OData

It's extremely easy to expose an OData end point from a .NET web application. You can simply add a new WCF Data Service and then define what it has access to. In this example I have a Contact table that looks like this:

After generating the data model, the Entity Framework provides this in my ContactModel space:

The underlying context that was generated is called ContactEntities so for my OData service I can simply point to the underlying context and specify which collections are available and what access rights the client should have:

public class ContactOData : DataService<ContactsEntities>
{
    public static void InitializeService(DataServiceConfiguration config)
    {            
        config.SetEntitySetAccessRule("Contacts", EntitySetRights.AllRead);
        config.SetEntitySetPageSize("Contacts", 20);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }
}

Note I've specified a page size of 20 records so that the service doesn't return all 1,000,000 records at once. When I hit the service endpoint, I get this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<service 
   xml:base="http://localhost:59389/ContactOData.svc/" 
   xmlns:atom="http://www.w3.org/2005/Atom" 
   xmlns:app="http://www.w3.org/2007/app" 
   >
  <workspace>
    <atom:title>Default</atom:title>
    <collection href="Contacts">
      <atom:title>Contacts</atom:title>
    </collection>
  </workspace>
</service>

This is all a client needs to begin navigating entities as the location of the first collection, Contacts, is clearly specified. We can now navigate to the contacts and receive something like this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed 
   xml:base="http://localhost:59389/ContactOData.svc/" 
   xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" 
   xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" 
   >
  <title type="text">Contacts</title>
  <id>http://localhost:59389/ContactOData.svc/Contacts</id>
  <updated>2011-11-20T16:24:05Z</updated>
  <link rel="self" title="Contacts" href="Contacts" />
  <entry>
    <id>http://localhost:59389/ContactOData.svc/Contacts(1)</id>
    <title type="text"></title>
    <updated>2011-11-20T16:24:05Z</updated>
    <author>
      <name />
    </author>
    <link rel="edit" title="Contact" href="Contacts(1)" />
    <category term="ContactsModel.Contact" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <content type="application/xml">
      <m:properties>
        <d:Id m:type="Edm.Int32">1</d:Id>
        <d:LastName>Alford</d:LastName>
        <d:FirstName>Lucius</d:FirstName>
        <d:Address>Ap #363-9702 Sit Rd.</d:Address>
        <d:City>Jordan Valley</d:City>
        <d:State>CO</d:State>
        <d:Email>mi.eleifend.egestas@mauriserateget.com</d:Email>
      </m:properties>
    </content>
  </entry>
  ...
  <link rel="next" href="http://localhost:59389/ContactOData.svc/Contacts?$skiptoken=20" />
</feed>

Notice that it follows the standard Atom format. Every entry has a clear location including where to go to post updates ("edit"). The full data set includes 20 entries and then specifies a link to grab the next page.

Adding this to the Silverlight client is easy. You can add a service reference, discover it in the current solution and the client will be wired for you automatically. Using a DataGrid that auto-generates the columns, I can write the following code behind:

public partial class ODataClient
{
    private readonly DataServiceCollection<Contact> _contacts;
    private readonly ContactsEntities _context;
    private DataServiceQueryContinuation<Contact> _nextPage;

    public ODataClient()
    {
        InitializeComponent(); 
        _context = new ContactsEntities(new Uri("../ContactOData.svc", UriKind.Relative));
        _contacts = new DataServiceCollection<Contact>();
        _contacts.LoadCompleted += ContactsLoadCompleted;
        var query = _context.Contacts.IncludeTotalCount();
        _contacts.LoadAsync(query);
    }

    void ContactsLoadCompleted(object sender, LoadCompletedEventArgs e)
    {
        _nextPage = _contacts.Continuation;

        if (_nextPage == null)
        {
            NextPage.IsEnabled = false;
        }

        TotalCount.Text = e.QueryOperationResponse.TotalCount.ToString();
        Count.Text = _contacts.Count.ToString();
        dgContacts.ItemsSource = _contacts;
        dgContacts.UpdateLayout();            
    }

    void Button_Click(object sender, RoutedEventArgs e)
    {
        _contacts.LoadNextPartialSetAsync();
    }
}

The fields hold references to the service. It is instantiated with a relative path to the end point. The query is extended to include a total count of records so it can be used to calculate page sizes, and the link to the next page is retrieved and stored for the continuation. When the user clicks the button to load the next block of records, the continuation is called to fetch the next page. The grid and button look like this:

The example is a quick-and-dirty way to parse the OData stream but can be extended to include a proper paging control (instead of simply expanding the grid) as well as edit and update functionality. Now I'll show you how to do the same thing using WCF RIA. The obvious advantage with WCF RIA is that the code projection removes most of the manual steps you need to take.

WCF RIA Services

The domain service for WCF RIA simply maps operations like queries to the corresponding LINQ-to-Entities commands. This example is read-only so the full implementation looks like this:

[EnableClientAccess]
public class ContactService : LinqToEntitiesDomainService<ContactsEntities>
{       
    public IQueryable<Contact> GetContacts()
    {
        return ObjectContext.Contacts.OrderBy(c => c.Id);
    }
}

The service derives from the context for the contact database and the query simply orders the items to allow paging (the result set must be deterministic for paging to work). That's it on the server side. A metadata class is also generated that you can use to apply data annotations to specify column names, validations, etc.

The client automatically has the WCF RIA classes "projected" which is a fancy way of saying the code is generated for the client. In fact, WCF RIA handles so much plubming that the WCF RIA client doesn't have to have a single line of code-behind. Instead, you can drop in a domain data source:

<riaControls:DomainDataSource 
   AutoLoad="true" 
   d:DesignData="{d:DesignInstance Web:Contact, CreateList=true}"                             
   Height="0" 
   Name="contactDataSource" 
   QueryName="GetContacts" 
   Width="0"
   LoadSize="60" 
   PageSize="20">
    <riaControls:DomainDataSource.DomainContext>
        <Web:ContactContext/>
    </riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource> 

By convention, ContactService is renamed to ContactContext on the client. The domain data service uses context as its data source. It is given some design-time data to generate the grid properly, the query to get the list of contacts is specified along with how many records to pre-fetch and how many to show on a page. A DataGrid simply binds to this as the data source along with a DataPager:

<sdk:DataGrid AutoGenerateColumns="True" 
   ItemsSource="{Binding ElementName=contactDataSource, Path=Data}"/>
<sdk:DataPager 
   Source="{Binding ElementName=contactDataSource, Path=Data}"/>

And that is it! It will handle computing total records, managing pages, and generating the grid. The result looks like this:

That provides what I would call the ultimate rapid development experience. It can literally take just five minutes to create the Entity Framework model, map the domain service, then drop the domain data source and grid controls on the client to have a fully functional application. Of course, as a developer you may want more control over how the application works and perhaps need to make sure this fits within your existing patterns. The most popular pattern for Silverlight development is Model-View-ViewModel (MVVM) so here is a quick view model to make it work:

MVVM

Instead of relying on WCF RIA you can abstract the data access layer using a pattern such as repository. This isn't a full implementation but the simple interface looks like this:

public interface IRepository
{
    void ProcessPage(int page, int pageSize, 
       Action<IEnumerable<Contact>> callback);
    int GetTotalPages(int pageSize);
}

Now you can use a mock to test access to the repository and even swap layers if or when it is necessary. Here is an implementation that works directly with WCF RIA:

public class Repository : IRepository
{
    private int _totalCount;
    private readonly ContactContext _contactContext = new ContactContext();

    public Repository()
    {
        var query = (
                        from c
                            in _contactContext.GetContactsQuery()
                        select c).Take(1);
        query.IncludeTotalCount = true;
        _contactContext.Load(
            query,
            callback => { _totalCount = callback.TotalEntityCount; }, null);
    }

    public void ProcessPage(int page, int pageSize, 
        Action<IEnumerable<Contact>> callback)
    {
        var take = pageSize;
        var skip = pageSize*(page - 1);
        var query = (from c in _contactContext.GetContactsQuery()
                        select c).Skip(skip).Take(take);
        query.IncludeTotalCount = true;
        _contactContext.Load(
            query,
            cb =>
                {
                    _totalCount = cb.TotalEntityCount;
                    callback(cb.Entities);
                }, null);
    }

    public int GetTotalPages(int pageSize)
    {
        return (_totalCount/pageSize) + 1;
    }
}

Note when the repository is created, it queries for a single item just to grab the full count for computing the page size. This is updated each subsequent call for a page. The call to grab the page computes how many records to skip and take for a page and then executes the query.

A simple view model can be constructed that uses the repository:

public class ViewModel : INotifyPropertyChanged
{
    private List<Contact> _contacts = new List<Contact>();
    private readonly IRepository _repository;

    public int CurrentPage { get; set; }

    public int TotalPages { get; set; }

    public IActionCommand NextPage { get; set; }

    public IActionCommand PreviousPage { get; set; }

    public IEnumerable<Contact> Contacts
    {
        get
        {
            if (_contacts.Count == 0)
            {
                Refresh();
            }

            return _contacts;
        }

        set { _contacts = new List<Contact>(value); }
    }
}

It exposes current page, total pages, commands to paginate and a list of the current contacts. The constructor sets up the initial conditions and sets a dummy page and page size in the design view:

public ViewModel()
{
    Contacts = new List<Contact>();
    NextPage = new ActionCommand<object>(obj => GoToNextPage(),
                                            obj => CurrentPage < TotalPages);
    PreviousPage = new ActionCommand<object>(obj => GoToPreviousPage(),
                                            obj => CurrentPage > 1);

    if (!DesignerProperties.IsInDesignTool)
    {
        CurrentPage = 1;
        _repository = new Repository();                
    }
    else
    {
        CurrentPage = 2;
        TotalPages = 10;
    }
}

The Refresh method fetches the current page:

private void Refresh()
{
    _repository.ProcessPage(
        CurrentPage,
        20,
        cb =>
            {
                TotalPages = _repository.GetTotalPages(20);
                _contacts = new List<Contact>(cb);
                RaiseChanges();
            });
}       

The commands simply change the current page and call refresh. For example, the command to advance by one page:

private void GoToNextPage()
{
    CurrentPage++;
    Refresh();
}

Now the view model can be bound to a grid. In this example, the current page and page count are used to construct a very simple paging control. All of the information you need to make a full-blown control is available. The MVVM-based view looks like this:

The ease with which it is possible to navigate a large data set from the client is one of the reasons I believe Silverlight is still a strong player in the Line of Business application space. More details and the full source code for this example will be available when my book publishes. As of this writing on November 20, 2011 it is discounted over 40% on Amazon when you pre-order a copy from here. Thanks!

October 21, 03:22 PM

One of the reasons I prefer to manage navigation as an event, rather than a strongly typed interface or handler, is because it allows for so much flexibility and extensibility in the navigation pipeline. In my Jounce framework, for example, the basic navigation event simply wires up an instance of a view to a view model and makes no presumptions about where that view belongs - it leaves positioning the view to the developer. The region manager simply listens for navigation events and passes the views off to region adapters without worrying about how they are wired, so it automatically handles the view simply by extending the pipeline by listening for the message as well. This same model makes it incredibly simple to place views in child windows using the new Silverlight 5 Out-of-Browser feature.

The first thing I'll do is create a controller to listen to navigation messages. It will expect a specific parameter to be passed that indicates when the view should be passed to a window. If that parameter exists, it will use parameters for height, width, and title to spin up the new window. A more complete implementation would store those literals as constants. Here is the shell for the class that implements the listener and subscribes to it:

[Export]
public class WindowController : IEventSink<ViewNavigationArgs>,
                                IPartImportsSatisfiedNotification
{
    [Import]
    public IEventAggregator EventAggregator { get; set; }

    [Import]
    public IViewModelRouter Router { get; set; }
    
    public void OnImportsSatisfied()
    {
        EventAggregator.SubscribeOnDispatcher(this);
    }

Now the handler. The handler will check the parameters for a special "OpenInWindow" parameter that must be set to true. It will only respond when that's the case, and everything else goes through the normal view routing. Because the project uses region management, there is no conflict because these views will not be routed to specific regions. First, if the parameter doesn't exist, the method simply returns. Note the use of the Jounce extension methods that conveniently cast the parameter to a specific type:

public void HandleEvent(ViewNavigationArgs publishedEvent)
{
    var parms = publishedEvent.ViewParameters;
    if (!parms.ContainsKey("OpenInWindow") ||
        !parms.ParameterValue<bool>("OpenInWindow"))
    {
        return;
    }
}

Next, the router is used to get the view model that is mapped to the view, then spin up a non-shared instance of the view and view model. This allows multiple instances to be created and therefore supports multiple windows with the same view/view model combination. The method to get the view takes an object for a parameter that it will set to the data context of the view. Jounce is smart enough to recognize when that object is a Jounce view model, and will take the additional steps of wiring in visual states and calling the InitializeVm and ActivateView methods on the view model. Notice that the parameters are passed into the view model as well - Jounce will pass these in when it attaches the view model to the view.

var viewModelTag = Router.GetViewModelTagForView(
    publishedEvent.ViewType);
var viewModel = Router.GetNonSharedViewModel(viewModelTag);
var view = Router.GetNonSharedView(
    publishedEvent.ViewType,
    viewModel,
    publishedEvent.ViewParameters 
    as Dictionary<string, object>);

Finally, the window is opened with the view set as the content:

new Window
        {
            Title = parms.ParameterValue<string>("WindowTitle"),
            Width = parms.ParameterValue<int>("WindowWidth"),
            Height = parms.ParameterValue<int>("WindowHeight"),
            Content = view,
            Visibility = Visibility.Visible
        };

That's all there is to it. The controller must be imported somewhere to begin listening for events. Then you can simply export the view with a tag like [ExportAsView("MyView")] and publish the navigation using the Jounce extension methods to turn the view tag into a navigation event and add parameters:

var window = "MyView".AsViewNavigationArgs()
    .AddNamedParameter("OpenInWindow", true)
    .AddNamedParameter("WindowTitle", "My View Title")
    .AddNamedParameter("WindowHeight", 300)
    .AddNamedParameter("WindowWidth", 600);
EventAggregator.Publish(window);

Of course you can get even more clever with how you obtain the title or set the sizes, and now opening a child window is not only as easy as publishing an event, but also fully testable in your view models because you can mock the controller for testing.This technique is demonstrated in detail in the chapter about OOB applications in Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series).

October 11, 10:07 PM

If you've worked with the Region Management pattern before, one source of frustration can be the lack of a design-time view. While you can compose individual views to be designer-friendly, the aggregate views that mark regions often end up devoid of anything useful. A simple little trick, however, can change that.

You may be familiar with creating design-friendly view models, but the extensions for Blend work the same with views. For example, consider a main page that has a layout divided into regions that are marked by content controls, like this:

<ContentControl  VerticalAlignment="Center" Margin="20 0 0 0" region:ExportAsRegion.RegionName="SortRegion"/>

There may be one or many views that can fit in the content control, but having it completely empty just doesn't make a good design experience as you cannot tell how components will fit together. With just a little tweak, however, you can change that. Consider this approach instead:

<ContentControl  d:DataContext="{d:DesignInstance Views:SortView,IsDesignTimeCreatable=True}" Content="{Binding}"
VerticalAlignment="Center" Margin="20 0 0 0" region:ExportAsRegion.RegionName="SortRegion"/>

This simple change has done a few things. First, it binds an instance of a reference view to the data context of the control. The binding will only be invoked in the designer and will not be impacted during runtime. Second, the content control is set to the binding, which is the view in the designer, causing it to render the content. With just that simple tweak you now can see how a view will fit into the region!

The view is created directly and is not recursively wired into the design-time experience, so any design-time data within the referenced view will not appear. To get around that you'll need to create a mock view instead and create an instance of that. If the view isn't activated right away, the content control will end up hosting whatever it inherits from the data context of its parents, which may have undesired side effects, but in most cases you will likely activate the view that routes to the region before any artifacts are visible to the end user. If you need to, you can also manually set the data context (the "real" data-context, not the design-time one) to {x:Null} to prevent it from inheriting anything at runtime.

Finally, there is always the option to use a custom markup extension if you really need a more robust view. For me, the trade-off of making a simple tweak is worthwhile.

Here's the design-time view of a small control, showing sample data:

Here's the main page with nothing but regions and design-time views. While the design-time data isn't wired, the views fall into place and I can get a sense of the overall layout (click to see a larger image):

And finally this is the same application at runtime:

So now you don't have to suffer from regions turning their backs on your designer. Enjoy!

October 07, 03:58 PM

A common problem encountered in Silverlight applications is how to set the focus properly when transitioning between controls. For example, in the reference application I'm writing for the book Designing Silverlight Business Applications there is the option to either edit an existing record or create a new one. The result of clicking the appropriate button is a panel overlay that zooms into view. Obviously, it makes sense once the panel is rendered to set the focus to the first field so the user can simply begin entering information.

If the control was managed by adding and removing it from the visual tree, the solution would be simple. This is the perfect example I have of not resorting to exotic solutions to a simple problem. The focus problem is not a business problem, it is a user interface problem. It's perfectly valid to wire a loaded event to the control, name the field that requires focus, and call the Focus method on that field when the parent control is loaded. This is an example where even with MVVM, it just doesn't make sense to solve the problem in the view model when it is so simple to add the code-behind. This doesn't change my ability to have a design-time data or to test my view model. It also works well because if I reuse the same control, the loaded event will still fire every time it is added back to the visual tree.

I mentioned this would be simple if the control was managed based on adding and/or removing it ... but that's not how I manage it. Instead, I use the Jounce framework to position it in a region and show or hide it by changing the visual state. What's nice about this is that I can have a state based on the action that the view model is invoked with, for example "New" for a new item, "Edit" to edit an existing item, and "Closed" when the view should go away. These actions are all handled by setting the visual state, so there is no convuluted logic to set visibility properties or wire any other logic. The visual state is wired as a delegate by Jounce, so when I test my view models I can simply mock the delegate and confirm the transition is set without actually loading a view. I can also set different types of animations, such as zooming the control from the "new" button for one mode and having it fade in from the grid in the other mode.

The problem with this approach is that the control never leaves the visual tree. Everything is managed by visual states, so the "Closed" state simply sets the visibility to collapsed, which keeps it in the visual tree but just ignores any rendering or hit testing logic. So how can I effectively set the focus based on a visual state transition?

I've read some interesting solutions that create a special "reverse behavior" that wires to the control and can be data-bound to a property on the view model. The view model can simply set the property and the data-binding will force the action to happen. Personally, I think this is a fine approach but I don't see the need for my view model to have to understand that part of the UI concern is setting a focus. I wanted to approach it from a UI-centric view and only involve the view model if needed.

It turns out the solution is quite simple. All I need to do is create a control to help manage the focus. Call it the "focus helper" and start with a dependency property that points to another control:

public class FocusHelper : Control
{
    public static readonly DependencyProperty TargetElementProperty =
        DependencyProperty.Register(
            "TargetElement",
            typeof (Control),
            typeof (FocusHelper),
            null);
       
    public Control TargetElement
    {
        get { return (Control) GetValue(TargetElementProperty); }
        set { SetValue(TargetElementProperty, value); }            
    }

}

The reason this helper derives from Control is because I want to be able to place it inside a grid. The next thing I'll do is expose a property to set the focus. First, the details of the property itself:

public static readonly DependencyProperty SetFocusProperty =
    DependencyProperty.Register(
        "SetFocus",
        typeof(bool),
        typeof(FocusHelper),
        new PropertyMetadata(false, FocusChanged));

public bool SetFocus
{
    get { return (bool) GetValue(SetFocusProperty); }
    set { SetValue(SetFocusProperty, value);}
}

You'll notice that I set the property metadata to invoke a callback whenever the property changes. In that call, I want to see if I have a control set. If I do, then I'll simply call the Focus method for that control, then reset the flag back to false so it can fire again if it is set in the future;

private static void FocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var targetElement = d.GetValue(TargetElementProperty) as Control;
    if (targetElement == null || e.NewValue == null || (!((bool) e.NewValue)))
    {
        return;
    }
    targetElement.Focus();
    d.SetValue(SetFocusProperty, false);
}

Now I've got a handy control that will fire the focus method on a target element whenever its own SetFocus property is set to true. It's easy to wire it to whatever input control I want, in this case a TextBox called "Title":

<Behaviors:FocusHelper x:Name="FocusHelper" 
       TargetElement="{Binding ElementName=Title}"/>
<TextBox x:Name="Title" Text="{Binding Title,Mode=TwoWay}"/>

Doing the binding this way also makes it Blend-friendly. If the focused element needs to change, the designer will be able to click on the binding and target the property all through the designer without touching the Xaml. The last step is to update the visual state. When the control is shown, the visibility is set to "Visible." I simply add another entry to the storyboard that sets the focus property to "true":

<VisualState x:Name="New">
    <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" 
                     Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0:0:0">
                <DiscreteObjectKeyFrame.Value>
                    <Visibility>Visible</Visibility>
                </DiscreteObjectKeyFrame.Value>
            </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusHelper" 
                      Storyboard.TargetProperty="(FocusHelper.SetFocus)">
                <DiscreteObjectKeyFrame KeyTime="0:0:0">
                    <DiscreteObjectKeyFrame.Value>
                        <System:Boolean>true</System:Boolean>
                    </DiscreteObjectKeyFrame.Value>
                </DiscreteObjectKeyFrame>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
</VisualState>

And that's it ... now any time I set the control to a visual state that makes it appear, the focus is set to the input control of my choice and the user is able to start typing or tabbing between fields right away. To learn more about the application, order your copy of Designing Silverlight Business Applications and read how it was constructed with access to the full source code.

September 30, 11:33 AM

Several weeks ago, I tweeted that a lot of people appear to be making their software far more complex than it needs to be. I was asked to elaborate and share details. The comment was prompted by reading dozens of forum posts by desperate developers in over their heads trying to apply enormous and complex frameworks to applications that really could use simple, straightforward solutions. I've witnessed this in projects I've taken over and worked with other developers and of course am guilty of making these same mistakes myself in the past. After years of working with line of business Silverlight applications, and speaking with several of my colleagues, what I thought might be a "Top 5" turned out to be a "Top 10" list. This is not necessarily in a particular order, but here are the ten most common mistakes I see developers make when they tackle enterprise Silverlight applications (and many of these apply to applications in general, regardless of the framework).

1. YAGNI

YAGNI is a fun acronym that stands for, "You aren't going to need it." You've probably suffered a bit from not following YAGNI and that is one mistake I've definitely been guilty of in the past. YAGNI is why my Jounce framework is so lightweight, because I don't want to have another bloated framework with a dozen features when most people will only ever use one or two. YAGNI is violated by the framework you build that has this awesome policy-based logging engine that allows dynamic configuration and multiple types of logs ... even though in production you always dump it to the same rolling text file. YAGNI is violated by the complex workflow you wrote using the Windows Workflow Engine ... when you could have accomplished the same thing with a dozen lines of C# code without having to spin up a workflow process. Many of the other items here evolve around YAGNI.

Learn how to avoid these mistakes in my new book, Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series)

A good sign that YAGNI is being violated is when the team spends three months building the "application framework" without showing a single screen. It has to be built just right with a validation engine, a configurable business rules engine, an XSLT engine and your own data access adapter. The problem is that trying to reach too far ahead into the project is a recipe for disaster. Not only does it introduce a bulk of code that may not be used and adds unnecessary complexity, but many times as the project progresses you'll find you guessed wrong and now have to go back and rewrite the code. I had a boss once who would throw up his hands in exasperation and say, "No, don't ask me for another refactoring." Often users only think they know what they want, and building software too far into the future means disappointment when they figure out they want something different after testing the earlier versions of the code.

Well-written software follows the SOLID principles. Your software should be made of small, compact building blocks. You don't have to boil the ocean. Instead, assume you aren't going to need it. That doesn't mean the logger or rules engine will never come into play, it just means you defer that piece of the software puzzle until it is relevant and comes into focus. Often you will find the users weren't really sure of what they really wanted, and waiting to place the feature until the software has been proven will save you lots of cycles and unnecessary overhead. Instead of pulling in the Enterprise Library, just implement an ILogger interface. You can always put the Enterprise Library behind it or refactor it later, but you'll often find that simple implementation that writes to the debug window is all you'll ever need.

2. Sledgehammer Framework Syndrome

This syndrome is something I see quite a bit with the Prism framework. I see a lot of questions about how to scratch your left ear by reaching around your back with your right arm using five layers of indirection. Contrary to what some people have suggested, I am a huge fan of Prism and in fact give quite a bit of credit to Prism concepts in Jounce. The problem is that while Prism provides guidance for a lot of features, few people learn to choose what features are relevant and most simply suck in the entire framework and then go looking for excuses to use the features. You don't have to replace all of your method calls with an event aggregator message and an application with five menu items doesn't always have to be chopped into five separate modules. I can't tell you how many projects I've seen pull in the Enterprise Library to use the exception handling block only to find there are only two classes that actually implement it and the rest do the same old try ... catch ... throw routine. Understand the framework you are using, and use only the parts that are relevant and make sense. If the source is available, don't even compile the features you aren't going to need ... there it is, YAGNI again.

The problem with pulling in the whole framework is what many of you have experienced. You jump into a new code base and find out there are one million lines of code but it just seems weird when the application only has a dozen pages. You started to work on a feature and find entire project libraries that don't appear to be used. You ask someone on the team about it, and they shrug and say, "It's working now ... we're afraid if we pull out that project, something might be broken that we won't learn about until after it's been in production for 6 months." So the code stays ... which is Not A Good Thing™.

3. Everything is Dynamic

The first question I often get about Jounce is "how do I load a dynamic XAP" and then there is that stare like I've grown a third eye when I ask "Do you really need to load the XAP dynamically?" There are a few good reasons to load a XAP dynamically in a Silverlight application. One is plug-in extensibility — when you don't know what add-ons may be created in the future, handling the model through dynamic XAP files is a great way to code for what you don't know. Unfortunately, many developers know exactly what their system will need and still try to code everything dynamic. "Why?" I ask. "Because it is decoupled." "But why is that good?" "Because you told me to follow the SOLID principles." The SOLID principles say a lot about clean separation of concerns, but they certainly don't dictate the need to decouple an application so much that you can't even tell what it is supposed to load.

Following SOLID means you can build the application as a set of compiled projects first, and then refactor modules into separate XAP files if and when they are needed. I mentioned one reason being extensibility. The other is managing the memory footprint. Why have the claims module referenced in your XAP file if you aren't going to use it? The thing is, there isn't much of a difference between delaying the creation of the claim view and the claim view model versus adding the complexity of loading it from a separate XAP file. If you profile the memory and resources, you'll find that most satellite XAP files end up being about 1% of the total size of the application. The main application is loaded with resources like images and fonts and brushes and controls, while the satellite XAP files are lightweight views composed of the existing controls and view models. Instead of making something dynamic just because it's cool, why not build the application as an integrated piece and then tackle the dynamic XAP loading only if and when it's needed?

4. Must ... Have ... Cache

Caches are great, aren't they? They just automatically speed everything up and make the world a better place by reducing the load on the network. That sounds good, but it's a tough sell for someone who actually profiles their applications and is looking to improve performance. Many operations, even with seemingly large amounts of data, end up having a negligible impact on network traffic. What's worse, a cache layer adds a layer of complexity to the application and another level of indirection. In Silverlight, the main option for a cache is isolated storage. Writes to isolated storage are slower than slugs on ice due to the layer between the isolated storage abstraction and the local file system.. Often you will find that your application is taking more time to compute whether or not a cached item has expired and de-serializing it from isolated storage than it would have taken to simply request the object from the database over the network. Obviously, there are times when a cache is required such as when you want the application to work in offline mode. The key is to build the cache based on need, and sometimes you may find that you aren't going to need it. As always, run a performance analysis and measure a baseline with and without the cache and decide based on those results whether or not the cache is necessary — don't just add one because you assume it will speed things up.

5. Optimistic Pessimistic Bipolar Synchronization

Synchronization is a problem that has been solved. It's not rocket science and there are great examples of different scenarios that deal with concurrency. Many applications store data at a user scope, so the "concurrency" really happens between the user and, well, the user. If you are writing an application that works offline and synchronizes to the server when it comes online, be practical about the scenarios you address. I've seen models that tried to address "What if the user went offline on their phone and updated the record, then updated the same record on their other offline phone then they went to their desktop in offline mode and updated the same record but the time stamp on the machine is off, and now both go online - what do we do?!" The reality is that scenario has about a 1 in 1,000,000 likelihood. Most users simply aren't offline that much and when they are, it's an intermittent exception case. Field agents who work in rural areas will be offline more often, but chances are they are using your application on one offline device, not multiples. It simply doesn't make sense to create extremely complex code to solve the least likely problem in the system, especially when it's something that can be solved with some simple user interaction. Sometimes it makes more sense to simply ask the user, "You have multiple offline updates. Synch with your phone or your desktop?" rather than trying to produce a complex algorithm that analyzes all of the changes and magically constructs the target record.

6. 500 Projects

I'm a big fan of planning your projects carefully. For example, it often does not make sense to include your interfaces in the same project as your implementations. Why? Because it forces a dependency. If you keep your interfaces (contracts) in a separate project, it is possible to reference them across application layers, between test and production systems, and even experiment with different implementations. I've seen this taken to the extreme, however, with applications that contain hundreds of projects and every little item is separated out. This creates a convoluted mass of dependencies and building the project can take ages. Often the separation isn't even needed because groups of classes are often going to be updated and shipped together.

A better strategy is to keep a solid namespace convention in place. Make sure that your folder structure matches your namespaces and create a folder for models, contracts, data access, etc. Using this approach enables you to keep your types in separate containers based on namespaces, which in turn makes it easy to refactor them if you decide that you do need a project. If you have a project called MyProject with a folder called Model and a class called Widget, the class should live in the MyProject.Model namespace. If you find you need to move it to a separate project, you can create a project called MyProject.Model, move the class to it and update references, and you're done - just recompile the application and it will work just fine.

Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series)

7. No Code Behind!

This is one that amazes me sometimes. Developers will swear MVVM means "no code behind" and then go to elaborate lengths to avoid any code-behind at all. Let's break this down for a minute. XAML is simply declarative markup for object graphs - it allows you to instantiate types and classes, set properties and inject behaviors. Code-behind is simply an extension of those types and the host class that contains them. The idea of MVVM is to separate concerns - keep your presentation logic and view-specific behaviors separate from your application model so you can test components in isolation and reuse components across platforms (for example, Windows Phone 7 vs. the new WinRT on Windows 8). Having business logic in your code-behind is probably NOT the right idea because then you have to spin up a view just to engage that logic. What about something completely view-specific, however? For example, if you want to kick off a storyboard after a component in the view is loaded, does that really have to end up in a view model somewhere? Why? It's view-only logic and doesn't impact the rest of the application. I think it's fine to keep concerns separated, but if you find you are spending 2 hours scouring forums, writing code and adding odd behaviors just so you can take some UI code and shove it into a view model, you're probably doing it wrong. Code-behind is perfectly fine when it makes sense and contains code that is specific to the view and not business logic. A great example of this is navigation on Windows Phone. Because of the navigation hooks, some actions simply make sense to write in the code-behind for the view.

8. Coat of Many Colors

Have you ever worked on a system where your classes wear coats of many colors? For example, you have a data base table that is mapped to an Entity Framework class, which then gets shoved inside a "business class" with additional behaviors, that is then moved into a lightweight Data Transfer Object (DTO) to send over the wire, is received using the proxy version of the DTO generated by the service client, and then pushed into yet another Silverlight class? This is way too much work just to move bits over the wire. Modern versions of the Entity Framework allow you to create true POCO classes for your entities and simply map them to the underlying data model. Silverlight produces portable code that you can share between the client and server projects, so when you define a service you can specify that the service reuses the type and de-serializes to the original class instead of a proxy object. WCF RIA Services will handle all of the plumbing for sharing entities between the client and the server for you. You know you are a victim of this problem if you ask someone to add a new entity into the mix and they moan for 10 minutes because they know it's going to take forever to build the various incarnations of the object. When there is too much ritual and ceremony involved with moving a simple entity from the server to the Silverlight client, it's time to step back and re-evaluate. In some cases it might make sense to keep the entities but use code-generation techniques like T4 templates to simplify the repetive tasks, but in many cases you can probably get away with reusing the same class across your entire stack by separating your models into a lightweight project that you reference from both sides of the network pond.

9. Navigation Schizophrenia

Are you building a web site in Silverlight, or an application? The presence of the navigation framework has led many projects down the path of using URL-driven navigation for line of business applications., To me, this is a complete disconnect. Do I use URLs in Excel? What does the "back" button mean in Word? The point is that some applications are well-suited to a navigation paradigm similar to what exists on the web. There is a concept of moving forward and "going back." Many line of business applications are framed differently with nested menus, multiple areas to dock panels and complex graphs, grids, and other drill-downs. It just doesn't make sense to try to force a web-browser paradigm on an application just because it is delivered over the web. Sometimes you have no choice - for example, navigation is an intrinsic part of the Windows Phone experience, and that's fine. Just make sure you are writing navigation based on what your application needs, rather than forcing a style of navigation on your application simply because there is a template for it.

10. Everything is Aggregated

The final issue is one that I've seen a few times and is quite disturbing. If you are publishing an event using the event aggregator pattern, and receiving the same event on the same class that published it, there's something wrong. That's a lot of effort to talk to yourself. The event aggregator is a great pattern that solves a lot of problems, but it shouldn't be forced to solve every problem. I've always been a fan of allowing classes communicate with peers through interfaces. I don't see an issue with understanding there is a view model that handles the details for a query, so it's OK to expose an interface to that view model and send it information instead of using the event aggregator. I still expose events on objects as well. For example, if I have a repository that is going to raise a notification when the collection changes, I'll likely expose that as an event and not as a published message. Why? Because for that change to be interesting, the consumer needs to explicitly understand the repository and have an established relationship. The event aggregator pattern works great when you have messages to publish that may have multiple subscribers, impact parts of the system that may not be explicitly aware of the class publishing the message, and when you have a plug-in model that requires messages to cross application boundaries. Specific messages that are typically shared between two entities should be written with that explicit conversation in mind. In some cases you want the coupling to show the dependency because it is important enough that the application won't work well without it. There is nothing wrong with using the event aggregator, just understand the implications of the indirection you are introducing and determine when a message is really an API call, a local notification, or a global broadcast.

Conclusion

I love writing line of business software. I've been doing it for well over a decade across a variety of languages ranging from C++, Java, VB6, JavaScript and XSLT (yes, I called XSLT a language, if you've worked with systems driven by XSLT you know what I mean) ... and I've been guilty of most of the items I listed here. One thing I learned quickly was that most people equate "enterprise software" to "large, clumsy, complex and difficult to maintain software" and that doesn't have to be the case. The real breakthrough for me happened when I started to focus on the tenants of SOLID software design as well as DRY (don't repeat yourself) and YAGNI. I learned to focus on simple building-block elements and working with what I know and not spending too much time worrying about what I don't know. I think you'll find that keeping the solution simple and straightforward creates higher quality software in a shorter amount of time than over-engineering it and going with all of the "cool features" that might not really be needed. If there is nothing else you take away from this article, I hope you learn two things: first, don't code it unless you know you need it, and second, don't assume - measure, spike, and analyze, but never build a feature because you THINK it will benefit the system, only build it when you can PROVE that it will.

Want to avoid these mistakes? Read about lessons learned from over a decade of enterprise application experience coupled with hands-on development of dozens of line of business Silverlight applications in my new book, Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series).

September 15, 10:57 AM

Once again speculation and worry has developers around the world biting their fingers and lamenting the end of a new era. It almost seems developers want to stick a fork in their Silverlight development because so many are latching onto the hype wagon, calling .NET "legacy" and refusing to see the bigger picture. Microsoft announces a new run-time called "Metro" that is not based on .NET, and suddenly .NET is dead — even though anyone can download the bits for the new operating system, install it, and see for themselves that .NET is alive and well. There happen to be two modes for the application, one in a new "Metro" environment and one in a more "desktop" environment. Microsoft's own Visual Studio is NOT a Metro app so I don't buy the line that this is just a staged coup d'etat. Microsoft announces that there are going to be two version of Internet Explorer: a "Metro" version with no plug-ins, and a desktop version that supports them. I downloaded Silverlight, installed it, and even loaded our Silverlight tablet Rooms to Go Application. It installed fine, appeared on the start menu for Windows 8 and launched without an issue ... but the headlines are reading "Microsoft abandons plug-ins."

First, let me say that I believe Silverlight is alive and well. I'm not saying that because I'm writing a book. People who know me understand I don't get emotionally invested in projects and try to force something to happen when it's not meant to be. I'm not basing this on mere speculation. "What if" doesn't buy me anything. Don't get wrong: I know "what if" is real because it tumbles stocks and cancels contracts, so it does have an impact, but instead of adding to the hysteria I prefer to look at the facts. I know that Windows 8 is not going to be the de facto operating system over night. I know that even when it does, I will be able to build and deploy Silverlight applications to it. I know customers will still have applications to support. I also know I work on a lot of Silverlight applications that simply won't work with the new "Metro" interface and require a more immersive UI and model, and that the guidelines for Metro will probably force those to be written in a traditional stack anyway. I know that a new version of Silverlight is coming out at the end of the year if Microsoft makes their drop target, and I know companies have already begun developing applications that take advantage of its features. But just in case the world is really ending and .NET, Silverlight, and all of those other technologies are truly legacy as of today, what will really happen? I asked my followers on Twitter just what it is that would be missing, and here's what I found out:

Multi-platform and OSX Support

Let's be real here. The only "real" multi-platform support Silverlight has right now is between the Mac OSX and Windows. There is a fledgling presence on Linux but that's hasn't impacted any deals that I'm aware of. The cross-browser story is better because between the two platforms, there is solid compatibility across FireFox, Chrome, Internet Explorer, and Safari. I believe this is a very valid point, as I've done many projects where the customer was most interested in the fact that Silverlight could easily target both platforms with one maintained code base. Of course, the original dream was for this reach to be extended but those hopes were largely dashed by the surge in popularity of the iPad that refused to run the plug-in. While this is a very important aspect of Silverlight, I don't buy that Windows 8 impacts this at all. Windows 8 is an operating system that will run new applications and boasts a new version of a web browser. It also runs the traditional browser and we've confirmed it fully supports Silverlight. So what is missing? The changes to Windows 8 don't remove the ability to drop Silverlight applications on to Mac or existing Windows machines, let alone the next version. It seems the only thing that could negatively impact this point would be lack of features (i.e. I'm missing something that I was expecting to come in a future version) or simply self-fulfilling prophecy, i.e. developers complain so much about it going away that people believe them and pull the plug.

Deployment and web-based Xaml Delivery

This is another sweet spot for Silverlight. The deployment strategy is insanely simple, and many large corporations embrace the easy of installation. This is a double-edged sword however, because for every shop that enjoys the fact that users can navigate to a web page and download the latest version of their application, there is another shop with complicated security policies that must make significant changes to their infrastructure in order to allow the plugin and make Silverlight applications available to employees. This really gets back to the traditional decisions used to drive technology and I don't see how Silverlight is really the primary ingredient. If you want to reach Macs and Windows machines, you will still have that option. If you need a different type of reach or want to take advantage of new innovations, the decision is the same it has always been: either build specific to the platforms you are targeting, with the trade-off that you must now have several teams and versions of the product but it provides a seamless, native experience, or compromise by using a technology like HTML5. That same trade-off existed with the previous version of HTML, it's just that Silverlight development was superior in many cases. I still see cases where HTML5 development is too painful compared to Silverlight, but what it were actually easier to build and deploy HTML5 apps with the same featureset as the Silverlight version? Why on earth would you even want to stick with Silverlight in that scenario?

Community

When I was younger and programmed the Commodore 64, there was a great Commodore community in the St. Petersburg, Florida area. We'd meet up, show each other how to crack open the bread box and solder the little red RadioShack reset button, then swap assembly snippets and chat about the latest VIC chip register hack. When the Commodore began to wane in popularity, people moved onto other platforms and built community around those. Ironically, there is still a strong, growing Commodore 64 community. I'm pretty sure community is more about the individuals in the community than the technology that drives it. Silverlight has a great community. If Silverlight goes away, that community will evolve. (OK, so there are always one or two who can't move on and are still stuck on Information Society breaking up and refuse to program on anything other than an Amiga).

Income

This is like community. First, let me say I know the financial impact of decisions is very real. Speculation about technology causes contracts to get canceled and people to lose jobs. However, if you believe your income is based on the success of Silverlight you are making a very, very big mistake. I remember when I received my fitness and sports nutrition certifications so I could coach people to lose weight. Many of the other "graduates" felt they should research what the pay ranges for trainers were, start at the lowest rate and work their way up. I felt like I should get paid what I was worth, not what the average income was, and had some success working with people so I started at the high end of the range and built a practice around that. My income wasn't based on the latest diet fad or exercise scam, it was based on results. When people lost weight and kept it off, they told others, and my practice grew. It was the value of my service that determined my rates, not industry averages or trends. Software development is the same way. Skilled developers provide value, the customer perceives that value, and they continue to deliver the best possible solutions based on the right technology for the job. If that technology changes, they change with it. Of course, if you want to focus all of your energy on complaining about how horrible it is that Microsoft shifts their strategies and let everyone know how much time and money you invested in learning dead technologies, you're welcome to. Complain away. The people I know who are successful in this industry move on. I'm not saying it's a good thing when you find a contract canceled because of a shift in technology, I'm saying you can either focus on the one that got away or figure out how to make sure it doesn't happen with the next one. Your choice.

P/Invoke

Really? "I don't want Silverlight to go away because it makes sense to run an abstraction layer dependent on a browser so I can go through another abstraction layer to talk back to native code." I just don't get it — is p/Invoke a vaid reason to worry about Silverlight's future? There's no equivalent on Mac OSX so you aren't doing it for cross platform. I'm not sure why you're doing it, really. I like programming in Silverlight: it's fast and it's easy, and p/Invoke opens up options. With the new development platform I can skip the p/Invoke, call the WinRT layer directly and save myself the overhead of importing DLLs and creating obscure structures or learning about how to marshal. To me this one just says, "If you're going heavy p/Invoke maybe it makes sense to look at Visual Studio 2011 and native applications instead."

C# Web App

I don't agree with this one at all. If you are bulding a web site, I think going with the web technologies is key - if I want an application, I'll build it. If I want a rich web site, I'll build it — but different approaches and different tools. Rich web applications still have nuances like page navigation, browser back buttons, and compability that make them different than applications. When I write Silverlight, I'm not writing a web application. I'm writing an application that is easily delivered over the web. That's why I don't use the navigation framework, because I don't think customers are used to navigating desktop applications using URLs. So if it's a web site I want to build and I want to use C#, why not MVC instead? If it's an application, let me use C# by all means ... and as I mentioned above, I may just lose the ease of deploying it over the web. Oh, by the way, did you notice that MVC 4 preview was released? Weird: it's not written in Metro, doesn't create Metro applications, yet Microsoft is still developing it and I don't hear people crying that MVC is dead.

Line of Business Applications

One key thing I see most people missing is that Windows 8 is two separate, distinct systems. Just launch the Visual Studio 2011 to see what I mean. That is not a Metro application. I like Metro, it works great on my phone and think it is the right way to build tablet-based applications, but there are just some things like development environments that don't and won't make sense. If you build for Metro you MUST follow the rules of the sand box, and you are limited. If you jump outside of that, it's back to the traditional stack. So I don't see this shifting gears. Personally the reason why I like Silverlight for line of business applications is because of Xaml and C#. I don't see that changing. I've converted a few applications to Windows 8 as well as walked through the examples and the gap is not huge. It's there, but not huge.

Bottom Line

I see myself having a choice. If I want to develop line of business applications that run on Mac OSX and are delivered over the web, I can develop Silverlight 5 applications. Regardless of whether someone labels that "legacy" it will be supported through 2020 (when the HTML5 spec will finally get ratified) and it will run on my target environments. If I'm building a rich, interactive line of business application, I'm going to want it in that environment. If I'm looking for a user-friendly, touch-first tablet interface, Metro doesn't change things for me. Today without Windows 8 my options are HTML5 or writing native iOS, Java, and Silverlight for Windows. With Windows 8, those options simply shift to HTML or native iOs, Java, and XAML/C#/WinRT. For many years to come, most of my customers will still be on Windows 7 and even Windows XP so guess what: Silverlight and WPF will still be our best options.

Silverlight development will be alive and strong, with official support for at least a decade even if no new version is in the pipeline, and longer if there is one. Even if it is the last version, though, as I'm writing my book I see that 90% of the topics covered are going to be the relevant to developing in the new Windows 8 runtime. Here's something that won't come as a surprise to seasoned developers: even if it does go away, there is no way it will ever happen overnight. As long as there is speculation, it's still around. When there is no more speculation, i.e. we know for a fact there is no vNext, there will be plenty of time to transition.

What's my point? My point is this: there are always people who are going to shout that the sky is falling and the world is coming to an end and air all of their woes to the world. The reality is we all have the same hours in the day and we can do with them as we choose. While I've been accused of being a blind, passionate follower of Silverlight for my optimism and enthusaism, I think they've got it wrong. I'm just optimistic and enthusiastic in spite of Silverlight. If it goes away I will adapt and continue to provide value where I can because at the end of the day I'm a developer and Silverlight is a tool in my arsenal. To me, moaning, whining, and complaining is a waste of time. If something's broke, it isn't going to fix itself. I'd like to see more posts on solutions and options moving forward rather than "Hey, I've got a flat, so let's sit on the side of the road, point at it and talk about all of the things that went wrong with my day."

That's my opinion, and not necessarily the opinion of my employer, and I'm sticking to it. What are your thoughts? Please sound off with comments below.

September 16, 02:12 PM

If you are trying to follow the hash tag for the //BUILD conference you are probably dizzy by now. I don't blame you for trying to sort through all the messages about standing in line for the toilet or what someone is having for breakfast. I thought it might be a good time to step back and pull together what you need to know.

Hopefully this helps you sort through the firehose of information. Happy Windows 8!

September 13, 02:21 PM

Yesterday I shared my predictions for Windows 8 at the Build conference. Today I can say that the keynote exceeded my expectations. There were a lot of amazing announcements that I'm excited to share with you. First, let's recap my predictions:

  • Microsoft will focus on Windows 8 as the platform for multiple devices and specifically address the tablet/slate competition space. To be convincing they'll need to address speed and responsiveness, but likely they'll focus on:
    • The richness of the OS - it's not just a big phone, but the full Windows enchilada
    • Security and policies that are lacking in iPad
    • The new HTML5+JavaScript option for development to draw in the developers who traditionally don't work with the Microsoft stack
    • Some lip service to writing it once and running it everywhere whether it's the desktop, laptop, or slate
    • The touch-first features of the new OS
  • Microsoft will emphasize that managed code and Silverlight are not dead and will be fully supported on Windows 8. I don't see the death of Silverlight any time soon (again, these are my predictions ... it will be interesting to see what really happens)
  • They almost have to address the community of developers concerned about managed code and emphasize that it is not going away. I'm guessing they'll talk about how managed code will work with Windows 8 and perhaps reveal some details about Xaml and C# either as Silverlight or something new for developing apps that target Windows 8
  • Microsoft will also address the unmanaged coders and focus on how C++ is coming back to front and center on the new platform, and likely cite some performance examples of why native code is important

I would say I hit the mark fairly close, in fact I underestimated what would be revealed. The main theme for the keynote was bold and re-imagined. While these words were repeated so many times they became a bit cliché, I would say they accomplished both.

The key points the keynote focused on were form factors, mobility, connectivity and sharing, and that services are intrinsic in modern applications. The keynote was divided into four distinct areas, and I'll cover those each.

The Windows 8 Experience

The new experience boasts a smaller memory foot print "up front" and small goodies like a gesture-based login. The main screen is touch-centric but not touch-specific and works fine with the keyboard and mouse. There is a new format that I'll call "clipboard plus" for integration between applications. This is incredible because a "photo chooser" can easily take you into Facebook for example to select social media pictures, without you coding a line of integration. The integration points are called "charms" and are consistent between apps. An example of a charm is integrated search that allows you to pass the single search phrase to multiple applications and get results based on Bing, social media, your file system or whatever else you like.

Building the Applications

I was worried we might not hear about the framework today, but I was wrong. The shell has been re-organized to feature a WinRT layer that supplies object-based APIs that are exposed to any language of your choice - C, C++, C#, VB, and of course the much-hyped JavaScript. A Visual Studio 2011 demo showed a photo application built with a few dozen lines of code using a new JavaScript, HTML5-based project. The project was then opened in Expression Blend which has been extended to support HTML5 just as well as it handles XAML. For those who thought it all would become HTML5, they then pulled down a Silverlight application and built it for the new platform. Just a few tweaks turned it into a native Metro application with full integration. XAML is right on top of the stack proving that the core Silverlight technologies are still very much a part of Windows 8.

The new application store is integrated directly into the development platform and allows direct publishing of applications. Sinofsky described as being as simple as "ordering a pizza." There is a visualization of the steps within the process and developers will have full access to the tools used to analyze and validate the applications that are published.

The most impressive feature I saw was the ability to take one code base and very easily and quickly build to the desktop, to Silverlight, and to the Windows Phone. This is exactly what people have been looking for and what addresses the unfounded fears that Silverlight technology would go away.

Hardware

I mentioned that one thing Build would need to address is the iPad. I think they did that well by not only showcasing some amazing UI features that make the iPad feel old, but by showcasing the hardware as well. The boot is ultra fast, taking only seconds. The bootstrapper includes malware detection and they showed an infected USB boot drive get halted because it contained a virus. A new "connected standby" mode wakes up periodically to process timer and network based addressed and then idles the power. All applications are hardware accelerated out of the box for the richest possible experience. Devices can be extended with miniature applets that integrate directly into your existing applications - for example, a print dialog that doesn't require you to "go somewhere else" to set up the printer settings. We saw super-thin laptops that were actually thinner than the legacy CAT-5 and USB connectors.

Integrated into the OS are options to refresh the system and remove malware and adware, as well as a command-line option to create a snapshot of the baseline and use that to restore the machine. There is an improved task manager, improved multi-monitor support, and Hyper-V built into the client. The onscreen keyboard is also very welcome and enables you to use a tablet to remote into a development machine and work (and no, I doubt I would be doing that very often).

Windows Live Integration

I did not expect them to address the iCloud but they did that through Windows LIve. There are settings to automatically synchronize between PCs and cloud-base email that automatically integrates across all devices. There are shared calendars, shared photos, and other repositories that synchronize to the cloud seamlessly from applications. A share charm allows you to integrate all of these items including between applications and to the cloud. You can also use the cloud to remote back to your devices. The key here is using the Live id to integrate all of the devices from your desktop and laptop to your Windows Phone and slate devices. This comes with a new API to make it very easy to integrate into your applications.

Conclusions

I am very excited about what I heard today. We can finally move on with the conversations about Silverlight. We will be able to use our investment in C# and XAML technology moving forward while allowing HTML5 and JavaScript developers to join the platform as well. The new platform looks exciting and responsive with a lot of features that put the customer experience first. I think these new devices and the new OS can absolutely compete with the likes of iPad because they provide an enhanced touch experience while carrying forward all of the security policies and features as well as supporting all of the legacy applications that came with Windows 7 and the 450 million people who have installed it. I believe this is a very exciting time and there is incredible opportunity now to build the next generation of applications using our existing knowledge and investment in Microsoft technologies.

Don't Forget to Download the Preview!

The preview, including the OS for both 32-bit and 64-bit, along with development tools will be available after 8pm PST on Tuesday, 9/13 at this link: http://dev.windows.com/.

September 12, 01:56 PM

Tomorrow is the start of the major event that has been hyped as heralding the most significant changes to Windows in the past 15 years (the last was when Windows 95 was announced). There has been a lot of speculation around what will happen tomorrow. Some people claim it will be the death of Silverlight and even managed code, while others hope to see news about the next version of the Windows Phone operating system. While I am not able to attend the event, I will be watching the keynotes closely, collaborating with my associates in the field who are at the conference, and blogging my insights over the next few days.

I've been asked by many customers, fellow developers and Twitter followers to share my thoughts on the Build Conference and, as a Silverlight MVP, what I think about the future of Silverlight. I obviously have a stake in its future as I'm about 2/3 of the way through writing a book about building enterprise applications using Silverlight. So what are my thoughts?

Personally, I think there has been far too much read into the focus on HTML5 and JavaScript. I may be proven wrong, but based on what I've seen (and this is all public knowledge as I have no "insider information" about Windows 8) I believe the following will happen:

  • Microsoft will focus on Windows 8 as the platform for multiple devices and specifically address the tablet/slate competition space. To be convincing they'll need to address speed and responsiveness, but likely they'll focus on:
    • The richness of the OS - it's not just a big phone, but the full Windows enchilada
    • Security and policies that are lacking in iPad
    • The new HTML5+JavaScript option for development to draw in the developers who traditionally don't work with the Microsoft stack
    • Some lip service to writing it once and running it everywhere whether it's the desktop, laptop, or slate
    • The touch-first features of the new OS
  • Microsoft will emphasize that managed code and Silverlight are not dead and will be fully supported on Windows 8. I don't see the death of Silverlight any time soon (again, these are my predictions ... it will be interesting to see what really happens)
  • They almost have to address the community of developers concerned about managed code and emphasize that it is not going away. I'm guessing they'll talk about how managed code will work with Windows 8 and perhaps reveal some details about Xaml and C# either as Silverlight or something new for developing apps that target Windows 8
  • Microsoft will also address the unmanaged coders and focus on how C++ is coming back to front and center on the new platform, and likely cite some performance examples of why native code is important

Those are my predictions, for what they're worth. I wanted to post these today so I could take a look back over the next few days to see if I was close or completely missed the mark. I'm looking forward to an exciting conference and sharing my thoughts with you as it unfolds!

September 12, 09:37 AM

I've been building enterprise applications for more than a decade now, and have specialized in Silverlight line of business applications for the past several years. The term "enterprise" seems to inspire images of complex, large, difficult-to-maintain software systems but a well-written system doesn't have to suffer from the extra complexity. One question I receive over and over again is what a good resource is to learn best practices for building Silverlight applications that target line of business. The market is just now starting to come out with books and tutorials that address these topics but for the longest time you had to scour to find most of your information in blog posts or tweets. I decided to take on two projects to fill two very specific gaps and I'm excited to share the details with you in this blog post.

The first project I completed reaches past Silverlight and addresses a framework I believe was game-changing when introduced with .NET 4.0: the Managed Extensibility Framework (MEF). I partnered with Addison-Wesley to produce a LiveLessons video series and ended with over 4 hours covering the fundamentals of MEF.

I learned about the Managed Extensibility Framework (MEF) when it was in early preview. The first project that I used it for that went to production was the 2010 Winter Olympics in Vancouver. It helped our team build out reporting modules quickly and easily. It did not take long for me to discover how powerful it was for Silverlight applications. I have since used it in projects ranging from SharePoint WebPart integration to the slate application our company developed for Rooms to Go.

One of the more popular posts on my blog was the 10 reasons to use the Managed Extensibility Framework article I wrote in April of 2010. MEF is also the foundation for the MVVM framework I wrote and released as the open source project Jounce. While I've found it to be a powerful framework that is bundled as part of the runtime (it's not a third-party add-on, but shipped with everything else when you installed .NET and Silverlight) there has been one nagging problem: lack of documentation.

I can't tell you how many times I've been asked where I learned about the framework (through blog posts) or where I found best practices (trial, error, and talking to others who used the framework) and what the best book about MEF is to buy (I don't know). So when Addison-Wesley (Pearson) approached me about a video tutorial as part of their LiveLessons Series to cover fundamentals of the framework, I was ecstatic.


For several months I spent a few hours after work and over the weekends building sample projects, recording screen casts, and putting together a curriculum that I felt would provide developes with everything they need to know to be proficient with using MEF. I wanted to be sure you learned when to use it and when not to use it. My goal was to share all of the problems I've faced building enterprise software that MEF was able to solve, and package the recipes I've used to solve common problems.

The end result is the Fundamentals of the Managed Extensibility Framework. Feel free to click on the link and take a peek at the product, but I also want to be sure you know about the free sample that covers Lesson 7 about Silverlight. It is an excerpt from the full lesson but will give you insights into how the screen casts and lessons work to decide if it's presented in a way suited to your learning style. I am very excited about what I was able to cover. Click here to watch the free sample.

The program starts by guiding you through a reference application that uses most of the features of MEF, including discovery, lifetime management, extensibility, and metadata. I then go into the details of imports and exports, parts, catalogs, and containers. I focus specifically on discovery, extensibility using a plug-in model, and provide samples for understanding how MEF manages the lifetime of objects. I cover collections, recomposition, composition batches, and debugging then focus on both flavors of metadata (weakly and strongly typed). I have a full lesson dedicated to the specific uses of MEF in Silverlight, and conclude with a set of recipes that demonstrate common problems I've solved in real world projects using MEF.

You can also watch the course as part of your Safari books online subscription.

I hope this helps fill a much-needed gap in documentation and tutorials about the Managed Extensibility Framework. For those of you who do invest in the tutorial, I would greatly appreciate you sharing your honest comments and feedback using the comments at the end of this post. That will help me learn how to make it better and more importantly help others decide what value they may gain from the tutorial . Watch the 20-minute sampler here and take a look at the full package here. Access the tutorial through Safari Books online at this link.

September 09, 07:57 AM

Silverlight is a popular platform for building enterprise applications because of its ease of delivery via the web and consistency across browsers and platforms. Most of the existing guidance is simple with introductory examples and basic content for building applications. Enterprise developers need a resource that provides a set of repeatable best practices and patterns to empower them to quickly and efficiently build line of business solutions using Silverlight. I wanted to tap into my years of experience building large commercial applications using Silverlight to provide the solutions to common and advanced scenarios that are often encountered when architecting software solutions. While I've tried to cover some of that through my blog, my readers have been asking for something far more in-depth and comprehensive.

A common complaint I receive from developers at large, via blog comments and at user group meetings, is that they cannot find a substantial resource that provides best practices and patterns for building large, scalable, modular Silverlight applications in the enterprise. I wanted to tackle advanced topics such as methods to move data across the wire, ways of sharing behavior between the client and the server, when to build modular extensions that load on demand and how to debug and profile Silverlight applications. The end result thanks to Addison-Wesley is a book that will not only provide a step-by-step approach with rich code examples for each topic, but will relate the solutions to actual case studies of production enterprise applications that the I have worked with. The book focuses on Silverlight 5 which will be released at the end of 2011. Silverlight has remained backwards compatible since version 3 and therefore any concepts or techniques should be relevant for future versions of the product as well. I also set out to provide valuable alternative perspectives for seasoned Silverlight developers.

I'm very excited to announce Designing Silverlight Business Applications: Best Practices for Using Silverlight Effectively in the Enterprise (Microsoft .NET Development Series)— a reference book with mini-tutorials that provides rich code examples, application frameworks, and case studies. It will include a rich glossary and set of references for existing tools and resources to supplement the information provided. A set of source projects supplements the book and will be hosted on the publisher web site for easy access and download by the reader.

While this book will not be available until early 2012, I wanted to share with you the opportunity to help influence how it is written and what topics are covered. Safari Books has a program called "Rough Cuts" that allows me to publish drafts of the book before they are published. You can read the text, receive updates as the book evolves and provide feedback to me about the book so I can help make it the best possible product when it goes to market. It is for the readers of the blog that I took on the project to write this book and I hope you will take the opportunity to read, provide feedback, and help me evolve this book to fit your needs for writing quality Silverlight code for line of business applications.

You can access the Rough Cuts version of the book online at this link. Even if you're not interested in the program, I suggest trying the link because it provides some limited previews of the existing chapters. For those of you interested, the current table of contents looks like this:

  1. Introduction
  2. Getting Started
  3. Introduction to XAML
  4. Advanced XAML
  5. The Visual State Manager
  6. Data-binding
  7. Model-View-ViewModel (MVVM)
  8. The Managed Extensibility Framework (MEF)
  9. Testing
  10. Navigation
  11. The Service Layer
  12. Persistence and State Management
  13. Out-of-Browser Applications
  14. Silverlight in the Enterprise
  15. Debugging and Performance Optimization

I'm excited to be a part of the project and to share it with you. I can't tell you how many times I've been asked via e-mail or at a user's group "So when are you going to write a book about this?" The answer is, "Right now!" Preview the free excerpts and participate in feedback as I write and edit the final chapters at Safari Rough Cuts online.

September 06, 07:08 AM

One feature I employ often in Silverlight projects is the ability to share a model between the client and the server. When you expose a model using a WCF service, you can consume it on the Silverlight side and indicate you want to reuse types in a referenced assembly, rather than having the proxy types generated. At first glance this seems ideal because you can truly project behavior such as validation to the client without maintaining separate copies of the type in question. Upon further inspection, however, there can be some unexpected side effects.

Consider the following class that is defined in a standalone Silverlight assembly but shared on the server by adding it as a linked file:

[DataContract]
public class SimpleModel
{
    public SimpleModel()
    {
        NonMemberProperty = "This was initialized within the constructor.";
    }

    private string _field = "This is an initialized field.";

    public string NonMemberProperty { get; set; }
        
    [DataMember]
    public string MemberProperty { get; set; }
        
    public string Field
    {
        get { return _field; }
    }
}

I've purposefully packed a few different examples to help illustrate what is happening. It should be very clear what will happen when you instantiate the class. The field will be initialized to expose a value, the non-member will be given a value, and the member property (the one tagged as a data member) is initialized to the default value of null.

Now you can expose the model using a web service. Just add a new "Silverlight-enabled Web Service" to your web project, and give it a very simple operation to fetch a new instance of the model:

[ServiceContract(Namespace = "http://jeremylikness.com/examples/")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SimpleService
{
    [OperationContract]
    public SimpleModel GetSimpleModel()
    {
        var simpleModel = new SimpleModel
                                {
                                    MemberProperty = "This was initialized by the service."
                                };
        return simpleModel;
    }
}

What happens now? On the server, you'll get a new object that now has three fully populated properties - the field (which returns the value initialized on the internal field), the non-member property, and the member property. So far, so good.

Flip over to the Silverlight client side. Create a grid that has rows and columns for the labels and the values. Embed an instance of the model like this:

<Grid.DataContext>
    <Model:SimpleModel/>
</Grid.DataContext>

And then you can easily data-bind the values like this:

<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Field}" 
            Style="{StaticResource ValueStyle}"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding NonMemberProperty}" 
            Style="{StaticResource ValueStyle}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding MemberProperty}" 
            Style="{StaticResource ValueStyle}"/>

Add a button for the user to click. We'll forget MVVM for now (heck, our model didn't even implement property change notification) and just implement a code behind. Right now the model should create an instance in the designer and show you the two initialized fields — something like this:

If you do nothing in the code-behind you should still be able to run the application and see the initialized values. Now let's get down to the wire.

Add a service reference, only make sure you specify that it re-uses types. You get to the dialog by clicking on the "advanced" button when adding a new service. It should look something like this:

This ensures that the service will return the actual type represented by the model, rather than generating a proxy type that lives in the namespace of the service itself. You get to have the full type with all of the methods and functions you've defined, even if they aren't being sent over the wire. Now that's handy, right?

In the code behind for the button click, simply fetch the instance generated on the server and update the data context:

private void Button_Click(object sender, RoutedEventArgs e)
{
    ((Button) sender).IsEnabled = false;
    var client = new ServiceReference.SimpleServiceClient();
    client.GetSimpleModelCompleted += _ClientGetSimpleModelCompleted;
    client.GetSimpleModelAsync();
}

void _ClientGetSimpleModelCompleted(object sender, ServiceReference.GetSimpleModelCompletedEventArgs e)
{
    btnLoad.IsEnabled = true;
    LayoutRoot.DataContext = e.Result;            
}

Not too complicated, right?

If you run the application and click the load button, the code-behind will call the service and fetch a new instance. When the instance is bound to the data context, however, you may notice something strange. The property that was flagged as a data member and was set on the server comes through just fine, but the other properties are empty. How can that be? Even though you didn't tag them as data members, they should have been set when the type was constructed. The field property doesn't even have a setter.

This is as expected, but what about the other two properties? The answer is well-documented but often overlooked. If you read the documentation for the data contract serializer, or the XML object serializer that it is based on, you'll find a small but important sentence that explains: "When instantiating the target object during deserialization, the DataContractSerializer does not call the constructor of the target object." That explains the non-member property. When the serializers create the type, they by pass the normal type system. This makes sense because you are expecting to reconstruct the type based on the contract, so the properties not passed in the contract aren't really relevant. The type is built from the ground-up by setting the properties that were serialized, but no other initialization code is called.

If you're wondering about the field, it's the same problem. While the C# language allows you to initialize fields as a convenience, the code is actually moved into the constructor for the type. If you decompile the DLL for the model used in this example, this is what the decompiled constructor will look like:

public SimpleModel()
{
 this._field = "This is an initialized field.";
 base();
 this.NonMemberProperty = "This was initialized within the constructor.";
}

As you can see, the compiler conveniently moved the field initialization into the constructor. All of the initialized fields will be called from the start of the constructor before calling into the base object constructor and then handling the code you specify.

So what's the point? It is very important that you understand the implications of sharing types between the server and the client, especially when there are behaviors you are expecting. If you have certain properties that are initialized in the constructor, you can't expect them to be available when addressing the instances on the client. One way to deal with this is to move initialization logic into a separate method and call it from the constructor but expose it so you can call it elsewhere as well. This may work in some cases but often the reason for putting code into the constructor is to hide the implementation details of how the type is initialized from the consumer. If that's the case, it's probably better to make sure all of your exposed properties and methods handle initialization appropriately without a dependency on the constructor. For example, remove the initialization code for the field and replace the property code with this:

get { return _field ?? (_field = "This was initialized in the getter."); }

Now the field will be initialized on first access and never initialized again, but it will work equally well regardless of how it is instantiated. Another way to keep the initialization details private is to track the initialization state with a private field. Booleans default to false so the field will have that value whether the type was created with a call to its constructor or not. Your code can check the value of this field and call the initialization logic the first time it is needed.

Sharing types between the client and the server is a powerful feature that Silverlight provides. It is important that you understand the nuances of how it works so that you can construct your classes to behave consistently and don't fall victim to unexpected behaviors on the client because the constructors were never called for your types.

Download the sample solution here.

September 01, 06:05 PM

One enhancement that quietly slipped into the Silverlight 5 RC is the inclusion of Tasks. This is not the full-blown Task Parallel Library (TPL) to my knowledge (as it lacks the Parallel class and extensions) but it does provide Task, its related factories, and the functionality to chain and monitor tasks. The purpose of the library is to simplify asynchronous methods.

This post will show you an example of using the library. I'm not presenting this as a best practice, but only as a thought exercise to show you the use of the Task library in a visual way. The program computes the factorials of several numbers, but uses task continuation to ensure only one web service call is made at a time (thus simulating a sequential asynchronous workflow). You can modify the example to fire all threads simultaneously.

First, a simple service in the web project to compute the factorial:

[ServiceContract(Namespace = "http://jeremylikness.com/examples/")]
[SilverlightFaultBehavior]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SimpleService
{
    [OperationContract]
    public long Factorial(int value)
    {
        long result = value;
        while (--value > 0)
        {
            result *= value;
        }
        return result;
    }       
}

Add the service reference to the Silverlight project. Next, create a simple class in the Silverlight project to hold the value and the result that implements property change notifications:

public class Factorial : INotifyPropertyChanged 
{
    private int _value;
    public int Value
    {
        get { return _value; }
        set
        {
            _value = value;
            RaisePropertyChange("Value");
        }
    }

    private long _result;
    public long Result
    {
        get { return _result; }
        set
        {
            _result = value;
            RaisePropertyChange("Result");
        }
    }

    protected void RaisePropertyChange(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

The main page holds a button to fire off the calls and a list box to show the results:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ListBox Grid.Row="1" x:Name="FactorialList">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Value}"/>
                    <TextBlock Text="!="/>
                    <TextBlock Text="{Binding Result}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Click="_BtnFactorClick" x:Name="btnFactor" IsEnabled="False" 
            Content="Factor" HorizontalAlignment="Left"
            VerticalAlignment="Top" Margin="10"/>
</Grid>

In the code-behind for the main page, hold a list of the Factorial objects:

private readonly List<Factorial> _factorials;

Then populate it with the numbers 1 through 20 and bind it to the list box - at this point you can run the application and see the list of numbers to be factored:

public MainPage()
{
    InitializeComponent();

    _factorials = new List<Factorial>();
            
    for (var x = 0; x < 20; x++)
    {
        _factorials.Add(new Factorial {Value = x + 1});
    }

    FactorialList.ItemsSource = _factorials;
}

Add the code to create a channel for the service. Use this instead of the proxy client so you can take advantage of the asynchronous programming model (APM) and use the begin/end methods. The task library provides a way to conveniently convert an APM call to a task. This example simply builds the path to the service using the location of the XAP to ensure it always points to the correct URL:

var source = Application.Current.Host.Source;
var uriBuilder = new UriBuilder(source.Scheme, source.Host, source.Port, "/SimpleService.svc");

var channelFactory = new ChannelFactory<SimpleServiceChannel>(
    new BasicHttpBinding(), new EndpointAddress(uriBuilder.Uri));

var channel = channelFactory.CreateChannel();

At the top of the code-behind for the main page, add a list of tasks that return a long (the return type of the service):

private readonly List<Task<long>> _tasks; 

Create a method to return a task. The task factory launches the task immediately. In this example, you want one task to complete before firing the next. Therefore, the task factory call is wrapped in another task to kick it off. The task that is created directly will not launch until you explicitly invoke it. This method will return a task that is primed to return the result of the service call when it is invoked:

private Task<long> _CreateFactorialTask(int idx, SimpleService channel)
{
    return new Task<long>(() => Task<long>.Factory.FromAsync(
        channel.BeginFactorial,
        channel.EndFactorial,
        _factorials[idx].Value,
        null).Result);
}

If you want the threads to all fire simultaneously (to the extent the thread pool allows) simply remove the Task wrapper and return the result of the factory call directly.

Notice that the factory takes the form of "begin method" then "end method" followed by the parameters that are passed in. The last parameter is a state object that you don't need for this example. When the results return, they aren't guaranteed to return on the UI thread, so create a method to safely dispatch them when needed:

private void _SafeInvoke(Action action)
{
    if (Dispatcher.CheckAccess())
    {
        action();
    }
    else
    {
        Dispatcher.BeginInvoke(action);
    }
}

Now you can create the task list. Place this code after creating the factorial list. All the code does is create a list of task objects, and marks each one to continue by updating the result and then launching the next task in line. An additional method ensures the very last result is obtained, and then the button to kick off the process is enabled:

_tasks = new List<Task<long>>();

for (var count = 0; count < _factorials.Count; count++)
{
    _tasks.Add(_CreateFactorialTask(count, channel));

    if (count <= 0) continue;

    var localCount = count;
    _tasks[localCount - 1].ContinueWith(
        taskCompleted =>
            {
                _SafeInvoke(
                    () => 
                        _factorials[localCount - 1].Result = taskCompleted.Result);
                _tasks[localCount].Start();
                return _tasks[localCount];
            });
}

_tasks[_tasks.Count - 1].ContinueWith(
    taskCompleted =>
    _SafeInvoke(() =>
                _factorials[_factorials.Count - 1].Result = taskCompleted.Result));

btnFactor.IsEnabled = true;

If you know why the count is copied to the localCount variable, good job! If not, no worries. The tasks are being created using lambda expressions with anonymous methods, so the locally scoped variable is used to capture the value of the variable. This is referred to as a "closure" and you can learn more about it here.

Now you can run the application and the tasks will be queued up, but not running. The last step is to kick off the workflow. All that is required is to start the first task. Because the tasks were linked, each task will complete, update the results, then kick off a new task that will generate the next web service call. When you click the button, you should see the factorials updating in order.

private void _BtnFactorClick(object sender, RoutedEventArgs e)
{
    btnFactor.IsEnabled = false;
    _tasks[0].Start();
}

This example just scratched the surface of what is possible. You can convert event-based tasks using a task completion source, orchestrate groups of tasks to launch in parallel and wait for them to finish, and even nest tasks inside of other tasks. This is a very powerful and welcome addition to the Silverlight tool box!

Download the source here.

September 01, 01:19 PM

It's exciting to see the progress of Silverlight 5 toward the final release that has been slated towards the end of the year. Today, the Silverlight Team announced the release of the Silverlight 5 Release Candidate. While it does not yet have a go-live license, it integrates many new features that were not available with the beta release, including the new PivotViewer integration and vector-based printing.

One of the new features included with the Silverlight 5 RC is the ability to interact with Platform Invocation Services, or PInvoke for short. This functionality allows managed code, like your Silverlight application, to make calls to unmanaged code like the C++ code that exists in DLLs on your system. PInvoke can be quite complex and covers a lot of different scenarios, so I've focused on a simple scenario to help you get started. You can learn more about PInvoke by reading this MSDN tutorial.

In this post, I will show you how to build a Silverlight Out-of-Browser (OOB) application that uses the native DLLs on your machine to play "beeps." With modern versions of Windows 7, the beeps have evolved into complex sounds that you can assign to various functions. Create a new Silverlight application called "PInvoke," set it to run out of browser and be sure to check the box that indicates it requires elevated trust.

Take a look at the MessageBeep function. It is documented here. The first thing you'll notice is that the type of beep or sound to play is not very friendly as it is passed in as an unsigned integer. Based on the documentation, you can create the following enumeration to simplify things and expose a few key types:

public enum BeepTypes : uint
{
    Ok = 0x00000000,
    Error = 0x00000010,
    Warning = 0x00000030,
    Information = 0x00000040
}

To make it easy to take a string and cast it to the enumeration value, add this extension method as well:

public static class BeepTypeExtensions
{
    public static BeepTypes AsBeepTypeEnum(this string beepType)
    {
        BeepTypes beepTypeEnum;
        return Enum.TryParse(beepType, true, out beepTypeEnum)
                    ? beepTypeEnum
                    : BeepTypes.Error;
    }
}

It is always good practice to encapsulate your calls to unmanaged code in a managed class. This limits the exposure and dependency on PInvoke. It also allows you to write more portable code because you can implement the calls in managed code or simply stub out empty methods for targets that don't support the PInvoke implementation. Here is a simple contract to play a sound:

public interface ISoundPlayer
{
    void PlaySound(BeepTypes type);
}

Now for the implementation. Create a class called SoundPlayer. The documentation gives you the message signature and the DLL that the method is located in. Bridging to the method in this example is very easy. First, include a using statement for System.Runtime.InteropServices. This is where the PInvoke bridge lives. Next, simply define the message signature as a static extern and import the DLL:

[DllImport("User32.dll")]
private static extern Boolean MessageBeep(UInt32 beepType);

Implement the contract and call the method you just imported using PInvoke:

public void PlaySound(BeepTypes type)
{
    if (!MessageBeep((UInt32) type))
    {
        throw new Exception("Beep failed!");
    }
}

That's all there is to it! Now wire up some Xaml in the main page to host four buttons:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <Button x:Name="Ok" Content="OK" Grid.Row="0" Grid.Column="0"  Click="Button_Click"/>
    <Button x:Name="Error" Content="Error" Grid.Row="0" Grid.Column="1"  Click="Button_Click"/>
    <Button x:Name="Warning" Content="Warning" Grid.Row="1" Grid.Column="0"  Click="Button_Click"/>
    <Button x:Name="Information" Content="Information" Grid.Row="1" Grid.Column="1"  Click="Button_Click"/>
</Grid>

Make sure that the name of the button matches the name of the enum. In the code-behind for the main page, create an instance of the sound player:

private readonly ISoundPlayer _soundPlayer = new SoundPlayer();

Now you can implement the button click event. Simply cast the name of the button to the enumeration and call the method on your managed class:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var button = sender as Button;
    if (button == null)
    {
        return;
    }
    _soundPlayer.PlaySound(button.Name.AsBeepTypeEnum());
}

That's it! Run the application in OOB mode and you will be able to press the buttons and hear your default Windows sounds play. If you change your theme or override the sounds, the application will play the correct sounds because it is bridging to the unmanaged code and asking the operating system to play the sound rather than trying to play it from a resource embedded within the Silverlight application.

Hopefully this light example will help you get started. PInvoke has a number of uses from interfacing directly with USB ports to enumerating drives and devices on the host system. It certainly opens the door to a new realm of possibilities with Silverlight.

Download the sample solution here (but remember, it requires that you install the Silverlight 5 RC first!).

August 31, 08:07 AM

There was a great conversation on Twitter today about properties and fields. The discussion was about whether it makes sense to expose variables as fields and not bother with the overhead of properties. After all, it's quick and easy and you can always change it later, right? One participant suggested there could be design "assumptions / deficiencies / violations / smells" from using properties instead of fields, and someone else pointed out that the intermediate language, or IL, for properties is larger and will take more nanoseconds to process.

So what's the word?

First, I'll make a call to action for you to use the comments section below because I'm curious if anyone has ever had an issue with an application because their properties were too slow. I'm not talking about a property that fires some exotic validation routine that performs asynchronous server operations and crunches numbers approaching infinity before completing. I'm talking a simple property with a backing field and possibly a property change notification. It's highly unlikely the few extra IL codes or nanoseconds spent ever presented any tangible problems just because the implementation was a property and not a field.

So what does the property buy us?

First, it's important to note that just because a property looks like a field to the outside world doesn't mean that it is interchangeable. Changing a field to a property is a breaking change and requires all of your code to be recompiled. That's an expensive operation, and one that should immediately call out to the advantage of using a property from the start. Even though the language allows properties and fields to appear the same, the underlying IL is different. Consider the code to access a field:

ldfld string [MyExample]MyExample.MyClass::SomeVariable
Compared to the code to access the same "field" when it is exposed as a property:
callvirt instance string [MyExample]MyExample.MyClass::get_SomeVariable()

As you can see, the property provides the language convenience of looking like a field but underneath is still a method.

Personally, I believe the best description of the benefits of properties is in Jeffrey Richter's CLR via C#. Chapter 10 covers properties. I obviously don't want to reveal too much because every serious developer should have this book in their library, but I'll summarize a few key points:

  • It's easy to corrupt a field because there is no validation whatsoever (Jeffrey gives the example of assigning a negative age)
  • Properties provide data encapsulation
  • Properties have the benefit of allowing data to be validated and cleansed, and can throw exceptions when something is wrong
  • Properties can perform other actions such as interacting with a cache or triggering a notification
  • Properties can participate in data-binding, fields cannot

Jeffrey's book goes on to make several very insightful comparisons between properties and fields to help you determine the pros and cons for your particular situation. The bottom line is that good design choices are seldom related to reducing the number of keystrokes to complete a class. There are many factors involved and while it is a bit more code to expose a public property, I tend to follow Jeffrey's strong suggestion that all fields should be private, and access to them restricted through methods. Properties have the dual advantage of being special-purpose methods that can perform several tasks when obtaining or presenting a value, while presenting themselves with an interface that looks like a simple field.

September 10, 11:29 PM

On August 6th I gave a presentation for ReMix South about tablet development with Silverlight. It was a fun presentation to give. I presented using a Motion Computing CL900 to demonstrate the difference between standard applications and ones that are touch-optimized. I also spoke quite a bit about why Silverlight was the strategic choice for a company we had a very successful slate project with (see the Rooms to Go case study here). The project showcased in this talk was written using my Jounce MVVM with MEF framework for building Silverlight line of business applications.

There is a phrase I blogged about earlier called the "consumerization of IT" that is creating some interesting enterprise trends. An IDC survey of 3,000 respondants showed that 95% used devices they personally purchased in their place of work. Workers purchase smart phones and/or tablets and bring them in to use. This is coupled with a strong surge in demand Natural User Interfaces (NUI) as evidenced not only by sales of tablets and slates, but even gaming interfaces like Microsoft's own Kinect technology.

The video for the session is below (hard to see the slides, though). Direct link to the video is here. I've uploaded the slide deck along with the sample applications and source code. Slate and tablet development is a very exciting space for Silverlight and will get even more interesting when we learn the details of Windows 8 in just a few short weeks.

Tablet Development with Silverlight - Jeremy Likness from ReMIX South on Vimeo.

August 15, 07:04 PM

I've been using the Silverlight 5 beta for some time now with no issues, so it was a surprise when I came across a project that did not work. It was definitely a backwards compatibility issue because it would run fine in Silverlight 4, but once installed the version 5 runtime, no luck. I started digging deeper and found the culprit. The problem is easy to reproduce. Create a simple command:

public class SelectCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        if (parameter != null)
        {
            MessageBox.Show(parameter.ToString());
        }
    }

    public event EventHandler CanExecuteChanged;
}

Then a view model (read-only so it doesn't have to implement property change notification):

public class ViewModel
{
    private ICommand _selectCommand;

    public List<string> Items
    {
        get { return new List<string> {"one", "two", "three", "four"}; }
    }

    public ICommand SelectedCommand
    {
        get { return _selectCommand ?? (_selectCommand = new SelectCommand()); }
    }
}

Now for the Xaml. Here is the rub ... in Silverlight 4, there is no such thing as ancestor binding to easily reference elements higher in the visual tree. It is a common pattern to have a view model with a collection bound to a list, and a command to operate against items in the list. The rub is that the data template for the items is scoped to the item itself, not the parent view model.

There are a number of ways to resolve this, such as using element name binding, but one hack was to stick a content control in the resource dictionary and use it to hold the parent data context. Take a look at this Xaml:

<UserControl.DataContext>
    <DataBindingIssue:ViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.Resources>
        <ContentControl x:Key="BindingContent" Content="{Binding}"/>
    </Grid.Resources>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown">
                            <i:InvokeCommandAction Command="{Binding Source={StaticResource BindingContent}, Path=Content.SelectedCommand}"
                                                    CommandParameter="{Binding}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBlock>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

If you compile the example (put the grid in the main page and add the classes described earlier) and run it in Silverlight 4, it works no problem. The content control which is really designed to display UI is being hacked to hold the data context, and then the items can reference back to the control and use the content to bind to the command. When you click on an item in the list, you get a nice message box displaying the value.

This example is not so friendly when run in Silverlight 5. The clicks simply don't happen. You can even convert the project to a Silverlight 5 one, remove and re-add the reference to the System.Windows.Interactivity namespace, and it will still not register clicks. If you debug, you'll find that the trigger does fire. It is passed the command parameter with the value of the item in the list ... but the command is null, so there is nothing for it to call.

Why is that? What happened? If you know the history of Silverlight, since version 3.0 the team has made a monumental effort to keep the versions backwards-compatible. When going to Silverlight 5, you don't get a special Silverlight 4 runtime - you get a 5 runtime that supports all of the Silverlight 4 features. This is obviously a problem for this example because the code breaks.

I filed this as a bug for the Silverlight team to consider in case others have used this technique and need the compatibility, but the "true bug" is in the code itself. This is an example of a hack or an exploitation of a bug that allows something to happen, but isn't necessarily the intended behavior. For all I know the bug was fixed in Silverlight 5. If you dive into the Silverlight documentation for resource dictionaries, you'll find this little nugget:

In order for an object to be defined in and accessed from a ResourceDictionary, the object must be able to be shared ... Any object that is derived from the UIElement type is inherently not shareable, unless it is generated from a control template.

In a nutshell, a content control really doesn't belong in a resource dictionary. Actually, if you think about it, the entire thing is a bit of a hack because a content control is designed to be part of the visual tree and in this example, it's being used simply to marshall a data context.

A better approach would be to create a class that is specifically intended to hold onto the reference. That class is easy enough to create and can even keep the same Content property:

public class DataContextBinder : DependencyObject
{
    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register(
            "Content",
            typeof(object),
            typeof(DataContextBinder),
            new PropertyMetadata(null));

    public object Content
    {
        get { return GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }
}

That is a simple class that is a dependency object (not a UIElement) and can hold any other type of object. It's not intended for the visual tree and is entirely shareable. And, sure enough, if you replace the content control in the previous example with the data context binder, the code runs fine in both Silverlight 4 and Silverlight 5.

Just another reason to take extra effort to play by the rules and learn what a control expects, so you don't suffer from a "hack" that gets called out in a later version.

August 12, 12:14 PM

I'm not a big fan of attribute-based validation because I find there are often complex requirements that involve asynchronous operations that often break the attribute model. I prefer more fluent validation using rules that can be shared between the client and server and can handle asynchronous scenarios.

For those times when I do have to use a class with attribute validations, it doesn't make sense to ignore them and throw in an entirely new model. Many developers are aware that you can create a "magic" form using the DataForm control, or a "magic" grid with the DataGrid control, and they will automatically honor validation attributes. If you are using your own view models and wiring your own forms, you can still take advantage of data annotations but it requires a little extra work.

In this example I'll use WCF RIA services because it can wire the example up quickly, it automatically projects the data annotations, and because I get a lot of people who ask me for examples using WCF RIA. The example here will work just as well if you use your own POCO classes with annotations in a shared library and send them across the wire with a REST service using JSON.

First, a simple class to encapsulate some data that is decorated with the annotations:

public class Contact
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string FirstName { get; set; }
        
    public string LastName { get; set; }

    [Required]
    [RegularExpression(@"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$", 
        ErrorMessage = "Email is invalid.")]
    public string Email { get; set; }
}

Next, a simple domain service that exposes what WCF RIA wants to think it is talking to a database layer. Note I am stubbing the CRUD to allow for edits on the client but don't really care about processing them for this example. The one query always returns an example with my information in it.

[EnableClientAccess()]
public class ContactDomainService : DomainService
{
    public Contact GetContact(int contactId)
    {
        return new Contact
                    {
                        Id = contactId,
                        FirstName = "Jeremy",
                        LastName = "Likness",
                        Email = "jeremy@jeremylikness.com"
                    };
    }

    [Insert]
    public void InsertContact(Contact contact)
    {
            
    }

    [Delete]
    public void DeleteContact(Contact contact)
    {
            
    }

    [Update]
    public void UpdateContact(Contact contact)
    {
            
    }
}

This is where the beauty of WCF RIA services comes into play, and I won't deny it: build the application, and you're ready to go with grabbing and manipulating the data on the client. Before you build the view model you can create a helper class that uses the data annotations validation to process the attributes on the entity. While I wouldn't normally overload the same class to also take on the work of a command, the helper will also implement ICommand to demonstrate how it can be used to also control whether or not the user is able to save the form based on validations (this keeps the example simple - normally I would have a second command class that interacts with the validation helper).

The bulk of the class is straightforward. It is typed to a class that implements property change notification, and registers for this (it also exposes a method to release the registration to avoid issues with memory leaks). Whenever a property changes, it uses reflection to grab the value and then passes all of the information over to the data annotations validation class. That class will throw an exception if the validation fails, and the helper traps this and uses it to keep track of properties that have validation errors before re-throwing it for the Silverlight validation system to use. I'm keeping it simple here and using strings but you can tweak it based on this post.

public class ValidationHelper<T> : ICommand where T : class, INotifyPropertyChanged
{
    private readonly T _instance;

    private readonly Dictionary<string,bool>  _hasErrors 
        = new Dictionary<string, bool>();

    public ValidationHelper(T instance)
    {
        _instance = instance;
        _instance.PropertyChanged += _InstancePropertyChanged;
    }

    public void Release()
    {
        if (_instance != null)
        {
            _instance.PropertyChanged -= _InstancePropertyChanged;
        }
    }

    private void _InstancePropertyChanged(object sender, PropertyChangedEventArgs e)
    {

        _hasErrors[e.PropertyName] = false;            

        var value =
            typeof (T)
                .GetProperty(e.PropertyName)
                .GetGetMethod()
                .Invoke(_instance, null);
            
        try
        {
            Validator.ValidateProperty(
                value,
                new ValidationContext(_instance, null, null)
                    {
                        MemberName = e.PropertyName
                    });
        }
        catch
        {
            _hasErrors[e.PropertyName] = true;
            throw;
        }
        finally
        {
            RaiseCanExecuteChange();
        }
    }
}

The implementation of the command interface takes one more step. Because a user might change some text and then click submit before validation fires, the command implementation will validate the entire object before determining whether or not it is safe to submit. The command is conditioned by the existence of any errors in the error dictionary. Note that the execute methods uses a different approach that doesn't throw exceptions and simply flags the individual errors generated by the call.

public bool CanExecute(object parameter)
{
    return _hasErrors.Keys.All(key => !_hasErrors[key]);
}

public void Execute(object parameter)
{
    var errors = new List<ValidationResult>();

    if (Validator.TryValidateObject(
        _instance,
        new ValidationContext(_instance, null, null),
        errors))
    {
        MessageBox.Show("Success!");
    }
    else
    {
        foreach (var member in errors.SelectMany(error => error.MemberNames))
        {
            _hasErrors[member] = true;
        }
        RaiseCanExecuteChange();
    }
}

The view model keeps an instance of the validation helper and tracks changes to the current contact, spinning up a new helper as needed. It also exposes an edit flag to disable editing while it is loading the data.

public class MainViewModel : INotifyPropertyChanged
{
    private ValidationHelper<Contact> _helper;
    private Contact _contact;

    private readonly string[] _properties = 
        new[] {"FirstName", "LastName", "Email"};

    protected Contact CurrentContact
    {
        get { return _contact; }
        set
        {
            if (_helper != null)
            {
                _helper.Release();
                _helper = null;
            }

            _contact = value;

            if (_contact != null)
            {
                CanEdit = true;
                _helper = new ValidationHelper<Contact>(value);
                RaisePropertyChange("SaveCommand");
            }

            RaisePropertyChange("Contact");
            foreach(var property in _properties)
            {
                RaisePropertyChange(property);
            }
        }
    }

    private bool _canEdit;
    public bool CanEdit
    {
        get { return _canEdit; }
        set
        {
            _canEdit = value;
            RaisePropertyChange("CanEdit");
        }
    }
}

It exposes the validation helper as a command and also projects all of the properties on the underlying contact object:

public ICommand SaveCommand
{
    get { return _helper; }
}        

public string FirstName
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.FirstName; }
    set { CurrentContact.FirstName = value; }
}

public string LastName
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.LastName; }
    set { CurrentContact.LastName = value; }
}

public string Email
{
    get { return CurrentContact == null ? string.Empty : CurrentContact.Email; }
    set { CurrentContact.Email = value; }
}

In the constructor, it either creates a design-time instance or uses WCF RIA services to load an instance of the contact record:

public MainViewModel()
{
    if (DesignerProperties.IsInDesignTool)
    {
        CurrentContact = new Contact
                        {
                            Id = 1,
                            Email = "jeremy@jeremylikness.com",
                            FirstName = "Jeremy",
                            LastName = "Likness"
                        };
        return;
    }

    var ctx = new ContactDomainContext();

    var query = ctx.GetContactQuery(1);
    ctx.Load(
        query,
        contact =>
            {
                CurrentContact = contact.Entities.Single();
            },
        null);
}

The Xaml to wire this up is straightforward - here is an example combination of a label and a text box:

<TextBlock Text="Last Name:" Grid.Row="1"/>
<TextBox Text="{Binding Path=LastName, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" 
            IsEnabled="{Binding Path=CanEdit}"
            Grid.Row="1"
            Grid.Column="1"/>

That's it - run the application and edit the fields. You'll see all of the attribute validations come across nicely. If you delete the first name, then click the submit button without tabbing out of the field, the validations will still fire and the submit button will disable itself until you fix the error. As you can see, it's very straightforward to tap into existing attribute-based validations. If you are implementing one of the newer interfaces like INotifyDataErrorInfo, you can use the "try" methods on the validator to avoid throwing exceptions, and parse the results to set errros on the underlying interface instead.

You can download the source for this example here (don't forget to set the web project as the startup project and the aspx page as the start page).

July 29, 09:52 PM

Sometimes I love how a little reflection can work magic. In this case I was building what I'll call a "non-intrusive" validation system. The project contains entities that are generated by templates, and it would be extremely difficult to crack open those templates to put in a lot of custom validation code. So I decided to approach it using a helper class that would attach to the generated entities.

As always, I work backwards. I like to have readable, fluent interfaces, so I decide what I want them to look like and then implement the classes and interfaces to make them work. In this case the entities implemented INotifyPropertyChanged and IDataErrorInfo. This makes it easy on the validation class because if it needs to validate a property, it can simply hook into the property change notification and pick up the new value for validation. Problem solved.

The validation mechanism ended up looking like this:

myClass.GetValidationHelper()
   .WithValidation<FieldIsRequired>(()=>MyField)
   .WithValidation<FieldIsInRange>(()=>MyField,0,999) 

So, how do we get there? I'm not going to give you all of the code but I'll touch on a few salient points. First, creating a common interface for validations makes it easy for the validation helper to parse through a dictionary (i.e. if property "x" comes in, run all validations for "x"). Implementing the validators with a constructor makes it easy to pass parameters. In the case of the FieldIsInRange there is actually a constructor that takes the minimum and maximum values. When you use reflection, you pass in parameters and it finds the matching constructor for you. This means I can have an extension method like this:

public static ValidationHelper WithValidation<TValidator, TProperty>(
   this ValidationHelper helper,
   Expression<Func<TProperty>> propertyExpression,
   params object[] args)
   where TValidator : IMyValidator

And I can simply pass the arguments through to reflection and it will match the appropriate constructor like this:

var validator = (TValidator)Activator
    .CreateInstance(typeof(TValidator), args);

The first parameter after the "extension" property of the helper is a property expression. You may find it is familiar because that's the guidance that Prism provides for strongly-typed property names and has been the topic of much debate. I settled on that format for my Jounce framework and while I initially used it to get property names, it actually comes in very handy for validation.

I won't rehash extracting the property name because it's been done. There are lots of debates over the relative performance of different methods. Here's a hint: for me, most of my property change notification is so I know when the user changes a field. Last time I checked, a user can't type fast enough to make my property changes fire so often that I'm really going to lose sleep over milliseconds here or there. I'd rather have something that is strongly typed so I don't have refactoring nightmares and put some of that plumbing in than have something that is convuluted to implement and code but saves me a tiny fraction of time that the user won't even notice.

You can see the source code in the ExtractPropertyName method by navigating to the BaseNotify class in Jounce - here is a direct link to the source for your viewing pleasure.

In the validation engine, we get an added benefit. What's passed in with this format:

CallSomeMethod(()=>myEntity.MyProperty);

Has a specific signature. It's an expression that contains a function that returns a property, and looks like this: Expression<Func<TProperty>>. Pretty cool. So we can walk the expression tree and get the property name. Once the property change notification fires, we can inspect the arguments for the event and see the property name, and if it is one we want to validate it, we go ahead and perform the validation. But of course, to validate it, we need to get the value. How do we do it?

Often I see the solution og taking the property name that's been extracted from the expression and then using reflection to find the getter and invoking it, like this:

var value = (TProperty) typeof(T)
                  .GetProperty(propertyName)
                  .GetGetMethod()
                  .Invoke( instance, null );

That will work, but it's like tying your arms into a pretzel and reaching around your back to scratch your nose. Doesn't really make sense when you've got the expression already — what was passed in? It's a function that resolves the value! So we use some expression magic to run the lambda expression.

Given the propertyExpression passed in with the signature Expression<Func<TProperty>>, all you have to do is compile the body of the expression. The following code will extract the value, first by compiling the function to a lambda expression, then by calling the lambda expression:

var lambdaExpression = Expression.Lambda<Func<TProperty>>(
   propertyExpression.Body).Compile(); 
var value = (TProperty) lambdaExpression(); 

Now you can pass that value (which was resolved to the most current value of the property, without using reflection) into the validation routines. One of those validation routines is a generic routine to compare values. Why write this multiple times when the framework provides a nice IComparable interface for things that can be compared? The framework I built works with strings, so my first challenge was parsing the strings to the target type before comparing them. This is where we can have some fun.

Here is the code to parse any string to any type ... provided the type supports the TryParse method. First, you get the type and you create a variable to hold the output of the parse call:

public static bool TryParse(string input, out T value) 
{
   var type = typeof(T); 
   value = default(T); 
   ...
}

Next, you build the parameters to the call. You want the method with the signature that takes a string type for the first parameter, and a reference to the type for the output parameter. Here's where it is important to know your C# and your CLR. The "out" keyword is enforced by the compiler, and is a language construct. The framework knows nothing about it. To the framework, it's simply a reference type. You might not know that you can create special types that are tagged as "reference" - read the documentation here for more information. If you suffix a type name with an ampersand (&) you are flagging that type to be passed by reference.

So, here's the rest of the method down to the call:

var parameters = new[]
{
   typeof(string),
   System.Type.GetType(string.Format("{0}&", type.FullName))
};

var method = type.GetMethod(
   "TryParse",
   parameters);

if (method == null)
{
   return false;
}

var invokeParameters = new object[] { input, value };
var returnValue = (bool) method.Invoke(null, invokeParameters);

Now comes just a slight trick that will cause problems if you're not aware of it. You tagged the parameter as a reference type, but most of the time your comparisons will be dealing with value types (integers, decimals, etc.) so what happens in the call is that the types are boxed. It's a common mistake to make that call above and assume your value will now be populated if the returnValue is true. Imagine your frustration when you run this and it is always set to the default value instead! What gives? It turns out the call does update the reference — but not the one you provided. It updates the reference in the array you passed in!

The last step in the global TryParse method is therefore to pull that value back out and return the result:

public static bool TryParse(string input, out T value) 
{
   ...
   if (returnValue)
   {
      value = (T)invokeParameters[1];
   }

   return returnValue;
}

And there you have it ... the generic try parse. Now if you wan to compare the values, you can cast to IComparable and simply use:

public int ParseAndCompare(string valueOne, string valueTwo) 
   where T: IComparable 
{
   T parsedOne, parsedTwo;
   if (TryParse(valueOne, out parsedOne) && 
       TryParse(valueTwo, out parsedTwo))
   {
       return parsedOne.CompareTo(parsedTwo);
   }

   throw new ArgumentException("One of the values didn't parse.");
}

I will admit the details of the implementation can get a little bit complex if you're not familiar with expression trees or reflection. However, the beauty of this approach is that the core pieces are not likely to change much as the basic infrastructure to build the validations on top of. The payoff is enormous, because now a developer can write a new validation by implementing a simple interface and then add the validation using the fluent syntax I showed earlier. That makes the code both readable and easy to maintain.

Profile

Experienced Enterprise Web Applications Architect
Computer Software | Greater Atlanta Area, US

Summary

I am a Microsoft-focused (Windows 8 Metro, ASP.NET MVC, and Silverlight) developer, architect and technical project manager with sales and entrepreneurial experience, a passion for mentoring and public speaking, and a strong social media presence.

In July 2010 I was honored to receive the Microsoft(r) Most Valuable Professional (MVP) award for my work with Silverlight. I was named Silverlight MVP of the year in 2010 and received my second MVP award for 2011.

Professionally I serve as a senior consultant and project manager for Wintellect backed by 15 years of experience developing enterprise applications. I have worked with software in multiple vertical industries including insurance, health and wellness, supply chain management, and mobility. My primary focus for the past decade has been building highly scalable Web-based solutions using the Microsoft technology stack, most recently with a focus on Silverlight and WCF.

Prior to Wintellect, I was director of information technology and served as development manager and architect for AirWatch, LLC, where I helped the company grow and solidify its position as one of the leading wireless technology solution providers in the United States by managing the development of their product portfolio, which includes public HotSpot solutions and a management console for enterprise grade wireless networks, mobile devices, and their consumers.

A fluent Spanish speaker, I served as director of information technology for Hispanicare, where I architected a multilingual content management system for the company's Hispanic-focused online diet program.

I accepted my role there after serving as development manager for Manhattan Associates, a software company that provides supply chain management solutions.
Specialties: Rich Internet Applications (RIA), MVC (3, 4), Silverlight, Windows 8 Metro, Managed Extensibility Framework (MEF), Prism (CAG/CAL), Windows Phone Development, Model-View-ViewModel Pattern (MVVM), WCF, WCF RIA, ASP.NET, AJAX, JQuery, Database Development (MySQL, SQL/2000, SQL/2005, SQL/2008), Team Foundation System (TFS), VSTS with automated testing and code coverage, Line of Business Commercial Enterprise Applications built on Microsoft Technologies, Software Architecture, Project Management.

Experience

  • Oct 2009 - Present
    Senior Consultant/Technical Project Manager / Wintellect
    Senior consultant and technical project manager building highly scalable enterprise solutions using the Microsoft stack. Primary focus has been C#, Silverlight, ASP.NET, and Windows Phone 7/Mango development and building composite, dynamic, modular Silverlight applications using Jounce, the Prism Composite Application Guidance (CAG/CAL) and the Managed Extensibility Framework (MEF) with WCF RIA using the Model-View-ViewModel pattern (MVVM).

    Project hightlights:

    Rooms to Go Silverlight Slate Application - our company was hired to build a slate-based point of sale application in Silverlight to run on a ruggedized slate device. We used the MVVM pattern to build the application. The system runs on slate PCs, portable devices that have no lid or keyboard hardware and are slim, lightweight, and easy to carry. The slate PCs run the Windows 7 operating system, have an estimated battery life of eight hours, and are designed to replace fixed kiosks. View the full online Microsoft case study here:
    http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=4000010773

    Microsoft 2010 Vancouver Winter Olympics - used Silverlight 3, ASP. NET, C# Windows Services and the Managed Extensibility Framework (MEF) to build an internal health monitoring system with a realtime dashboard and enabled on-demand remote configuration changes for IIS Smooth Streaming servers that delivered the live and archived Olympic content. See the case study and Silverlight team blog post:
    http://wintellect.com/Consulting/Case-Studies/2010-Winter-Olympic-Health-Monitoring-System
    http://team.silverlight.net/customer-evidence/vancouver-olympics-ndash-how-rsquo-d-we-do-that/

    Microsoft Looking Glass - For Microsoft's Social Network Analytics and Marketing tool I redesigned the architecture of the Silverlight client to support the MVVM pattern with the Managed Extensibility Framework (MEF) and migrated fully to Silverlight 4.
    http://wintellect.com/Consulting/Case-Studies/Looking-Glass
  • Jan 2006 - Oct 2009
    Director IT/Architect / Wandering WiFi, LLC
    I partnered with Chairman Alan Dabbiere (former CEO of Manhattan Associates, NASDAQ: MANH) and CEO John Marshall to build the corporate network infrastructure and scale it to support growth while extending our operations into geographically disparate data centers. I visited customer sites, configured and deployed wireless networks and provided 24/7 technical customer service support. I established proprietary content filtering mechanisms, outgoing spam management, and custom hotspot solutions while extending the core product line and growing the development team.

    My focus then shifted to scaling the development organization by increasing resources and improving technology: hiring and managing dozens of IT professionals in networking, operations, technical support, installation and development; implementing and enforcing software development lifecycle methodologies; introducing and configuring Team Foundation Server for ticket and incident tracking, performance metrics, source control, automated builds and unit testing; integrating with Sharepoint for standards, documentation, and best practices and formalizing internal training and onboarding process.

    I finally served primarily in a development management capacity over the flagship wireless management application, streamlining the software development lifecycle and overseeing integration with Sharepoint and Team Foundation System. The application was N-Tier on the .NET Framework 3.5 stack using C# with a service-oriented (SOA) architecture and Rich Internet Application (RIA) console with AJAX and Silverlight. I invested as much time hands-to-keyboard coding and testing as I did with designing, managing infrastructure, mentoring team members and growing the organization.

    .NET Framework 3.5; WCF; C#; Silverlight, AJAX, Mobile Devices, Wi-Fi (802.11x); SQL 2005/2008; Windows Server 2003/2008; Visual Studio 2008 with Team Foundation Server (TFS); SharePoint; JQuery
  • Jun 2004 - Mar 2009
    Founder and Author / Lose Fat, Not Faith
    Built content rich website; designed graphics, layouts, articles, advertisements, fitness tools, etc. My NaturalPhysiques.com website was ranked in the top percentile of all websites (per Alexa ranking with 3,000+ unique daily visitors) prior to sale. Developed digital and hardcopy products ranging from CDs to books. Created residual income through sales of affiliate products, advertising, and other channels. Created top 10 search enginge rankings with high demand terms including "lose fat," "fat loss," "weight loss podcast," to generate daily qualified leads through organic non-paid search queries.

    As a Certified Trainer and Specialist in Performance Nutrition and a life coach, consulted with clients to assist them with releasing fat. Produced multimedia (web pages, interactive tools, CDs) as well as telephone-based and live seminars to educate people about steps they can take to improve their health and lifestyle.

    MySQL, PHP, SEO, Nucleus CMS, Coppermine, ClickBank
  • Oct 2005 - Dec 2005
    Senior VB6/ASP Consultant / Veredus
    Three month contract supporting PriceWaterhouse Cooper's "Comperio" document management suite. Analyzed ASP pages for vulnerability to injection attacks and modified application to increase security based on audits. Built tools to facilitate replication between staged servers. Extended interace with search plug-in to improve full text search capabilities.
  • Oct 2005 - Dec 2005
    Senior VB6/ASP Consultant / PricewaterhouseCoopers
    See Veredus job description
  • Jun 2002 - Apr 2004
    Director IT / DrTango
    Reporting directly to the CEO, Roberto Estrada, and EVP (Dr. Dirk Schroeder), I managed and developed a major upgrade to web-based weight management software called MiDieta/MyDiet. Renovated the architecture to support separate database, business logic, and presentation tiers, built a CMS to allow nutrition editors to update data without requiring software revisions, designed a cache system to improve performance and scalability, built an image service and billing module to support marketing campaigns, created a customer relationship management module to track client activity and provide feedback mechanisms such as rating systems and referrals. Built the business and increased organizational capacity by introducing policies and procedures relating to disaster recovery, coding standards and guidelines, hardware and software procurement, purchase order requests, and implementation methodology. Initiated automated change request system and introduced revision control software.

    SQL 2000; VisualBasic (VB) 6.0; COM; XML/XSLT; ADO; JavaScript; HTML; DHTML
  • 1997 - 2002
    Development Manager / Manhattan Associates
    After being hired by and working directly with founding partner and Vice President Ponnambalam Muthiah on the flagship PkMS product, I transitioned from the midrange iSeries platform side to become technical lead over a team of 4 developers building a multi-lingual, XML-based, distributed Internet transaction for supply chain visibility. The supported databases included iSeries (AS/400 - DB2/400), SQL/2000, and Oracle. IIS 5.0 using a combination of Visual Basic 6.0 and ATL COM+, VBScript, JavaScript, DHTML, T-SQL, XML, and XSLT. Automated several key phases of developoment lifecycle. Used ticket and revision tracking software (StarBase’s StarTeam) to automate progression of code from unit testing through the Quality Assurance (QA) environment and out to production servers. Used automation features of InstallShield™ software to package web updates for distribution to clients. Delivered a web-based tool to monitor inventory over geographically separated warehouses for customer. Involved polling separate iSeries databases and merging the data with SQL/2000 views to provide a global inventory perspective. Optimized database views for high performance and scalability.
  • Jun 1998 - Dec 2000
    Freelance Technology Writer / Penton Media
    Freelance author of various articles including "The Exterminator's Guide," a guide to troubleshooting technology (June 1, 1998) and "Calling the Plays: Strategies for Successful IS Team Management" (April 1, 1999).
  • 1996 - 1997
    System Analyst / CareCentric
    System Analyst, was formerly called "Simione Central"
  • Feb 1994 - Jun 1996
    Programmer Analyst / Bankers Insurance Company
    Designed, developed, and tested insurance software using RPG on the AS/400.

Additional Information

Honors:
Microsoft Most Valuable Professional (MVP) - Silverlight - July 2010
abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz