Wednesday, September 28, 2011

The Top 10 Over-Engineering Mistakes in Silverlight Applications

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).

Jeremy Likness

Thursday, September 15, 2011

If Silverlight is Dead...

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.

Jeremy Likness

Wednesday, September 14, 2011

Windows 8: What you Need to Know

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!

Jeremy Likness

Tuesday, September 13, 2011

Windows 8 and Build Day 1 Keynote Thoughts

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/.

Jeremy Likness

Monday, September 12, 2011

My Windows 8 Build Predictions

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!

Jeremy Likness

Fundamentals of the Managed Extensibility Framework

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.

Jeremy Likness

Friday, September 9, 2011

Silverlight Enterprise Application Development

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.

Jeremy Likness

Tuesday, September 6, 2011

Data Contracts and Behaviors over the Wire

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.

Jeremy Likness

Thursday, September 1, 2011

Silverlight 5 RC - Using the Task Parallel Library (TPL)

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.

Jeremy Likness

Silverlight 5 RC Released - Using PInvoke

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!).

Jeremy Likness