Lately in the blogosphere and on Twitter there's been a lot of talk about what Silverlight 3 can or can't do. The goal of this article is to talk through some of the pros and cons I've personally encountered while building a real-world, enterprise-scale timesheet and job management application for an electrical contracting company.
The application my company is building has a lot of different screens, integrates with the back-end database using Windows Communication Foundation (WCF), uses a printing solution (see smartwebcontrols.com for more details) that we created, and relies on several of the key features Silverlight 3 has to offer. The existing application used by the client was written using Access Forms and is being ported to Silverlight 3, along with a lot of new functionality.
Let's start by going through what I personally feel are the pros and cons that Silverlight brings to the table for line of business (LOB) applications, and then talk about some of the interesting things you can build.
Silverlight 3 Pros
Here are some of the pros I've found in working on the LOB application mentioned earlier:
Excellent data binding support. This changes how you look at building applications and allows you to write data-centric code instead of control-centric code, as with normal web applications. There's a lot I could cover here, but I wrote an article about the benefits of Silverlight data binding, so please refer to that article for more information.
Server code and client code can written in the same language. Business and validation rules can be shared between the client and server code base, which definitely makes applications more maintainable into the future. This is important not only for maintenance, but also for getting more developers involved that may not have experience with ASP.NET or other web technologies.
A rich set of controls. I really like the controls available with the Silverlight SDK and in the Silverlight Toolkit (codeplex.com/Silverlight). For example, the new DataForm control in Silverlight 3 simplifies the process of capturing data from end users. There are a few controls mentioned later in the article that can test your patience, though, when you're building a more involved application.
Support for just about any type of animation or effect you want. You don't need that functionality in a LOB app? I beg to differ. You can get quite creative with how data is displayed with Silverlight and not be limited to simple slide, sizing, or opacity animations. I'll show an example of what I call the "card flow" interface later in this article and show how it allows managers to get to timecards faster and easier than before.
Excellent designer support through Expression Blend 3. Visual Studio 2008 is great for coding, but doesn't provide any design-time features for Silverlight 3. That's not a big deal, since you can use Expression Blend 3 (which provides a great WYSIWYG environment for designing your applications). The new SketchFlow application can even be used to prototype applications upfront and get customer feedback more quickly and easily than in the past.
Easy-to-integrate distributed data using WCF, ASMX, REST, ADO.NET Data Services, .NET RIA Services, and more. The application that I'm working on leverages WCF as well as some dynamic code (see my blog post "Simplifying the Process of Calling a WCF Service from Silverlight") on the client side to make calls to the service. It works great and FaultExceptions can even be handled now with Silverlight 3.
Desktop-style application with a web deployment model. Get the responsiveness of a desktop application that can be deployed right through the browser and even run on Macs.
Support for styling of controls. Silverlight 3 now allows styles to be changed on the fly and styles to be based on other styles. If you don't like how a control currently looks, you can completely change it by using styles and control templates.
Out-of-browser support. This was a key reason why my client chose Silverlight 3. They have a lot of remote workers that don't always have access to the Internet and needed to be able to enter timesheets even when disconnected, then sync them later once a given employee has connectivity.
Support for behaviors. Behaviors are very, very useful in Silverlight applications. I needed to add mouse wheel scroll capabilities to a ScrollViewer control to simplify scrolling in a screen and did it within minutes by using a behavior created by Andrea Boschin.
Manipulate pixels using WriteableBitmap. This tool (blois.us/blog/2009/07/explode.html) can be used to create some very cool effects, some which may not be applicable to LOB applications but are quite creative nonetheless. I'm using it mainly to fill the printing hole mentioned in the cons section below.
Support for storing local data through isolated storage. By using isolated storage you can cache data, store data when no network connectivity is available, and more.
Support for navigation. Silverlight 3 has a new navigation application template in Visual Studio that makes creating an application with multiple pages quite easy. Each "page" can be linked to directly through deep linking and has built-in support for history. If the client hits the back or forward button in the browser they're taken to the appropriate Silverlight application page. The navigation framework allows code to be placed into separate pages (or user controls) and then loaded as a particular link or menu item is clicked. It's a great feature that can really reduce the amount of code you have to write, especially compared to Silverlight 2.
Silverlight 3 Cons
Both the client and I are very happy with how things are going with the application, but there have been some challenges along the way. Following are some of the areas where Silverlight 3 is missing the mark when it comes to LOB applications.
No printing support. Microsoft is working hard on this for future versions of Silverlight, but if you can't wait until then it's definitely something to be aware of. We knew about this going into the project, so it was supposed to be a non-issue since we could pop-up HTML overlays or open new browser windows that could be printed. But, for one particular screen the lack of printing support is proving to be a challenge since it turns out the end user always prints the screen as they're doing payroll work, and the screen is quite complex.
Binding data to controls such as a ComboBox. Nested ComboBox controls are harder to use than they should be in some scenarios. I use a lot of ComboBox controls that are nested in DataGrid or ListBox rows in the application. While I have it working fine now, the ComboBox control itself really needs a SelectedValue and ValueMember property for situations where unique keys are returned from databases, as well as a way to more easily bind its ItemsSource to collections that may be defined outside of the current DataContext. All of this can be done by writing code, but if you want to handle the majority of it declaratively in XAML it can be challenging in some cases, especially once you start breaking parts of a page into user controls. I ended up enhancing some code Rocky Lhotka blogged about and created my own ComboBox control that simplifies things a lot and works quite well when it's nested in DataGrid and ListBox controls.
Lack of built-in support for commanding. Commanding is when the ability to call a method within an object directly from XAML as an event fires instead of going through a code-behind file. For example, when a button is clicked, the click event can call directly into a ViewModel object that acts on the event. By using commanding, you can make your applications more testable and keep code more clean overall. Frameworks such as Prism (codeplex.com/CompositeWPF) along with several others (check out Laurent Bugnion's MVVM Light framework at galasoft.ch/mvvm/sample1) have been released that support simple button commanding and provide a code framework that can be used to build other types of commands.
The application I'm working on handles just about every event in the book (click, mouseenter, mouseleave, rowloaded, lostfocus, gotfocus, and others). Writing custom code just to handle events didn't make sense, so we simplified things to handle the event in the code-behind and then notify our ViewModel object that something happened. If you want to handle events directly in the code-behind file, this is a non-issue for you, but if you want to handle them in another class it can be more challenging than it should be.
Learning curve. There is certainly a learning curve associated with building Silverlight applications, especially if you're coming from building standard web applications. However, I think that's the case with any technology. I had already built several demo applications with Silverlight, co-authored a book and several articles on it, and still ran into a few challenges with Model-View ViewModel (MVVM) architecture choices along the way. I think it boils down to experience though, so I list this one simply so that people know they will spend some time learning. If you enjoy learning new things, you'll love Silverlight once you get into the habit of using it.
No built-in support for displaying Reporting Services reports within Silverlight. This isn't a huge issue in my opinion, since a report can be brought up in a separate browser window or displayed using an HTML overlay. However, if you need to display the report directly in Silverlight, there isn't any built-in way to do that in Silverlight 3. Third-party vendors have come to the rescue though: Perpetuum Software (perpetuumsoft.com) now has a product that can integrate reports directly into Silverlight.
The client has to have the Silverlight plugin installed. I personally don't view this as much of a con for internal enterprise LOB applications, since it's fairly easy for a PC manager to push out Silverlight to client PCs in many environments. If the application will be run externally, then installation of the plug-in on each client has to be considered as the application roll-out is planned.
Sharing service types between proxy objects needs to be enhanced. When the LOB project I mentioned earlier was initially started, I wanted to use ADO.NET Data Services for some things and WCF for others. The problem is that if both services reference the same type (such as a Customer type), then both generated proxy objects will contain a copy of that type, which ultimately bloats the XAP size and leads to having to reference types by namespace instead of a using statement at the top of the code file. Although proxies can share code libraries from other projects (that's an option in the proxy generation wizard), my server-side types use .NET language features not available in Silverlight class libraries so type sharing won't work there. It's something to keep in mind as you decide how you'll get data into your application.
There are definitely more pros than I've listed and probably a few more cons, although I honestly can't think of many more that I've had to deal with. The bottom line is that all of the pieces are there to build powerful LOB applications that are built using existing .NET languages. You can make the applications look however you'd like and not have to worry if they'll look good across different browsers. Figure 1 shows a picture of a payroll screen in the early stages of development.
Figure 2 shows what the screen looks like after applying a few styles to the controls and adding support for things like inline editing of data.
Some of the more "fun" features in Silverlight 3 can also be put to good use in LOB applications. I needed to create a way for warehouse managers to easily manage multiple time cards for employees. I ended up going with what I call a "card flow" interface (similar to cover flow in iTunes) to display the time cards. The end user can use the mouse wheel to quickly navigate through different cards. The selected card will slide to the middle with a nice animation and the others are angled using perspective 3D. Figure 3 shows what the "card flow" interface looks like.
Ready for Prime Time?
Is Silverlight 3 ready for enterprise-level LOB applications? Having worked with the framework nearly every day for the past four months in a real-world scenario, my short answer is "Yes!" I don't say that because I've succumbed to indoctrination—I say it because I feel it offers many benefits that enterprise applications can benefit from. I truly enjoy working with the framework and think it can do a lot of powerful things.
Dan Wahlin, a Microsoft MVP for ASP.NET and XML web services, founded the XML for ASP.NET Developers website and The Wahlin Group (www.TheWahlinGroup.com), which specializes in .NET, Silverlight, and SharePoint consulting and training solutions.