Thursday, January 31, 2013

Book Review: Async in C# 5.0

I recently finished reading Async in C# 5.0 by Alex Davies (Amazon Link).  This is quite a short book (at 92 pages), but it contains quite a bit of useful information in that space.

The book covers that "async" and "await" keywords that were added in C# 5.0.  Because the new functionality is based around the Task Asynchronous Pattern (TAP), the book spends quite a bit of time talking about Tasks (which were added in C# 4.0).

With that said, if you are brand new to Tasks, then this book is probably not the best place to start.  It quickly covers the different asynchronous patterns that were available before async/await, but this is more of a reminder than an introduction.  There's not quite enough for someone who is not already familiar with these patterns.

The book has 15 chapters, which means that each chapter is fairly short (just 5 or 6 pages for many of them).  But there is enough information in each to be useful.  Some interesting examples include the following:
  • Writing Asynchronous Code Manually
  • Writing Async Methods
  • What await Actually Does
  • The Task-Based Asynchronous Pattern
  • Utilities for Async Code (including cancellation and progress reporting)
  • Exceptions in Async Code
  • Async in ASP.NET Applications
  • Async in WinRT Applications
An example of one of the shorter chapters is "Unit Testing Async Code".  This is just 2 pages long.  But in those two pages, it covers the problems with testing async code with a traditional unit test -- mainly, that since async methods return immediately, the test will actually complete before the asynchronous part is finished (and will always return "successful").  There are basically 2 approaches: (1) force the test code to run synchronously, or (2) let the unit test return a Task type (rather than void) -- MSTest (as well as some other testing frameworks) have been updated to support async tests that return Task.

In addition to showing how to use async and await in your own code, the book also covers some of the inner workings.  This includes a look at the methods that are generated by the compiler (with some simplified IL samples) and also how the stack is maintained and reported during debugging.

There are quite a few good tidbits -- such as how to create async wrapper methods to add functionality -- that make this book a good read.

It's short, it's cheap, and it contains quite a bit of useful information.  Well worth the read (especially useful is you've got a bit of Task-based programming under your belt).

Happy Coding!

Sunday, January 27, 2013

BackgroundWorker Component Compared to .NET Tasks

There are a lot of questions as to whether the BackgroundWorker component should be used for new applications.  If you've read my previous articles (such as this one), you know my opinion on the subject.  To summarize, the BackgroundWorker is an easy-to-use component that works very well for putting a single method into the background while keeping the UI responsive.

In .NET 4.0, we got Tasks.  Tasks are much more powerful than the BackgroundWorker (orders of magnitude more powerful) and have much more flexibility as well.  In .NET 4.5, we got a way to report progress in Tasks (through the IProgress interface).

A Comparison
Personally, I've been working with Tasks a bit more in my code.  And based on this, I thought I would revisit  my BackgroundWorker sample and rewrite it (with the same functionality) using Task instead.  The result is almost the same amount of code (just a few lines different).  I purposefully wrote comparable code so that we could compare the two approaches.

The Initial Code
Our baseline application will be the BackgroundWorker w/ MVVM project that was reviewed a while back.  This application was chosen as a baseline because all of the BackgroundWorker functionality is confined to the ViewModel (in ProcessViewModel.cs).  This makes it easier to swap out the functionality using Tasks.  I'm only going to cover the differences in the ViewModel here; if you want a better idea of the entire project, see the article mentioned above.  The source code for both projects can be downloaded in a single solution here: http://www.jeremybytes.com/Demos.aspx#KYUIR.

I did make a few updates to the UI.  This is primarily because my development machine is using Windows 8, and the previous color scheme didn't look quite right.  Here is the application in action:


As a reminder, we want to support cancellation and progress (progress includes both a percentage for the progress bar and a message for the output textbox.

So, let's start comparing the code!

Fields and Properties
The Fields of the ViewModel are almost the same.  First, the BackgroundWorker fields:

Now, the Task fields:


As we can see, the difference is that the BackgroundWorker field (_worker) has been removed and a CancellationTokenSource (_cancelTokenSource) has been added.  We'll talk a bit about the CancellationTokenSource in just a bit.  We need this in order to support cancellation of our Task.

The Properties are the same in both projects.  Our properties are used for data binding in the UI (the goo that makes the MVVM pattern work).  Since our UI hasn't changed, the public interface of the ViewModel does not need to change either.

The Constructor
Next, we'll take a look at the constructors.  In our BackgroundWorker project, the constructor sets up our component:


But in the Task project, we don't need this initialization.  We've actually moved some of this functionality down a bit.  But we're left with an empty constructor:


Starting the Process
Now that we've got our basic pieces in place, let's take a look at starting our long-running process.  The StartProcess method is fired when clicking the Start button in the UI.  This kicks things off.

Here is the StartProcess method from the BackgroundWorker project:


And here is the StartProcess from the Task project:


There are several similarities between these.  First, we see that the Output property is cleared out.  Then we see that the StartEnabled and CancelEnabled properties are set -- these properties are databound the the IsEnabled properties of the buttons.  We also instantiate the ProcessModel object (_model) if it has not already been created.  As a reminder, the ProcessModel object contains our long-running process and is the Model part of our Model-View-ViewModel.

Now the differences.  First, notice that we need to instantiate a CancellationTokenSource.  This is the private field that we noted above, and we'll be using this to cancel the process.  We'll talk about cancellation a bit more below.

Next, rather than starting the BackgroundWorker (with RunWorkerAsync), we call a method called DoWorkAsync.  This method returns a task.  We can see that it takes our _model as a parameter (just like the BackgroundWorker), but it also takes a CancellationToken as well as a Progress object.  The Progress object simply implements the IProgress<T> interface, and we'll talk a bit more about this later.

The last piece of our StartProcess method is to add a ContinueWith to our task.  This is the equivalent of hooking up an event to the BackgroundWorker's RunWorkerCompleted event.  When the task has completed, the TaskComplete method will run (and we'll see this below as well).

Cancellation
To actually cancel the process, we use the CancelProcess method.  This does not immediately stop any running processes, it simply sets a flag to indicate that things should be cancelled (if possible).

For the BackgroundWorker, we just call the CancelAsync method on the component itself:


For Tasks, we call Cancel on the CancellationTokenSource:


So, let's talk a bit about cancellation.  For the BackgroundWorker, cancellation is baked into the component, and we just need to call the CancelAsync method.  For Tasks, we need to create a CancellationToken and pass it to the task itself (we'll see how it's used in just a bit).  One of the interesting things about a CancellationToken is that you can't just create one directly.  This is why we have an internal field that is a CancellationTokenSource.  The CancellationTokenSource manages a CancellationToken.  We can use the Token property to get this token (which is exactly what we do in our call to DoWorkAsync above).  We can also set that token to a cancelled state by calling the Cancel method on the CancellationTokenSource.  Notice that we are not setting any properties on the token itself; in fact, we're not allowed to directly update the state of the token.

The Long-Running Process
Now we'll take a look at our long-running process.  This happens in the DoWork event of the BackgroundWorker:


As a quick reminder, this method loops through the Model (which implements IEnumerable).  First, it handles whether the process should be cancelled.  Then it calculates the progress percentage and returns a string for progress display.  Finally, if it gets to the end of the loop without cancellation, it returns the current iteration value.

We'll see that we have very similar code in the DoWorkAsync method in our Task project:


The first thing to note is that we have a custom ProgressObject that contains 2 properties.  This will allow us to report both a percentage complete as well as a message.  Notice that our DoWorkAsync takes a parameter of type IProgress<ProgressObject>.  This lets us know what type of object to expect when the progress is reported.  Note that IProgress<T> is available in .NET 4.5; if you are using .NET 4.0, then you need to report progress manually.

So, let's walk through the DoWorkAsync method.  First, notice that it returns Task<int>.  Because it returns a task, we can use ContinueWith to determine what to do after the task completes -- and this is exactly what we did in the StartProcess method above.

For parameters, DoWorkAsync takes a ProcessModel (our model for doing work), a CancellationToken, and an IProgress<T>.

Since we need to return a Task, we need to create one.  This is done through the Task.Factory.StartNew() method.  The version of the method that we're using takes 2 parameters: a Func<int> (since integer is our ultimate return type) and a CancellationToken.  For the first parameter, we're just using a lambda expression to in-line the code.  We could have made this a separate method, but I included it here so that it would look more similar to the BackgroundWorker version.

Inside the lambda expression, we are doing the same thing as in the BackgroundWorker.DoWork event: we loop through the model.  Inside the loop, we first check for cancellation.  Since we are using a CancellationToken, we just need to call ThrowIfCancellationRequested.  This will throw an OperationCanceledException if IsCancellationRequested is true on the token.  Since we passed the token as part of the StartNew method, the exception will be automatically handled and the IsCanceled property of the Task will be set to true.

Next, we calculate the progress.  The calculation is the same as the BackgroundWorker method.  The difference is that to report the progress, we need to create a new ProgressObject (our custom object to hold the percentage and the message), and then call the Report method on our progress object.

And finally (at the end of the lambda expression), we return the value of the last iteration (an integer).

So, we can see that this part is just a bit different.  It's not really more complicated, but we do need to understand Tasks well in order to get all of these pieces to fit together.

Reporting Progress
Updating the progress bar and message for the UI is similar between the projects.  Here is the UpdateProgress method from the BackgroundWorker project:


As a reminder, the ProgressChanged event fires on the BackgroundWorker whenever the ReportProgress method is called.  The event arguments for the event include the ProgressPercentage (which is an integer) as well as the UserState (an object).  Since the UserState is of type object, we can put whatever we like into it.  In this case, we put a string that is displayed in the output box, but we can put a more complex object in there if we like.

The UpdateProgress from the Task project is similar:


Here we can see that our custom ProgressObject is used as our parameter.  This method is called whenever the Report method is called on the Progress object.  This callback was hooked up when we originally created the Progress object in our StartProcess method:


Notice that when we "new" up the Progress object, we pass the UpdateProgress method as a parameter.  This acts as the event handler whenever progress is reported.

We do get some extra flexibility and type-safety with this methodology.  First, our Progress uses a generic type.  This type is ProcessObject in our case, but if we only wanted a percentage, we could have specified Progress<int> (and not worry about a custom object type).  Because we have a generic type, we don't have to worry about casting and will get compile-time errors if we try to use the types incorrectly.  (For more advantages to using Generics, you can look up T, Earl Grey, Hot: Generics in .NET.)

Completing the Process
Our final step is to determine what happens after our long-running process has completed.  Here is the code from the BackgroundWorker project:


Here, we check for an error condition, check the cancelled state, and have our "success" code which puts the result into our Output box and resets the progress bar.  Whatever the completion state, we reset the enabled properties of our buttons.

And from the Task project:


We can see that this code is almost identical.  Our parameter is a Task<int>.  Since it is a Task, we can check the IsFaulted state (to see if there were any exceptions), check the IsCanceled property, and then use the IsCompleted property for our "success" state.

Should I Use BackgroundWorker or Task?
So, we've seen some similarities and some differences between using the BackgroundWorker component and using a Task.  When we look at the total amount of code, the files are very similar (197 lines of code in the BackgroundWorker and 194 lines of code in the Task).

In writing the Task project, I purposely tried to line up the methods with the BackgroundWorker project.  This was to facilitate a side-by-side comparison.  But using either project, we can reduce the amount of code with lambda expressions and other in-line coding techniques.  But the goal wasn't to create the most compact code; it was to compare techniques.

Advantage BackgroundWorker
The BackgroundWorker component has several advantages for this scenario (and I want to emphasize "for this scenario").  First, the BackgroundWorker is easy for a developer to pick up.  As has been mentioned in previous articles, since the BackgroundWorker has a limited number of properties, methods, and events, it is very approachable.  Also, most developers have been working with events already, and so the programming style will seem familiar.

In contrast, there is a steeper learning curve regarding Task.  We need to understand how to construct a Task (the static Factory is just one way to do this) and how to pass in a CancellationToken and IProgress object.  These are both non-obvious (meaning, I never would have guessed that I needed a CancellationTokenSource -- my instinct was to try to use the CancellationToken directly).  We also need to understand what it means when we pass Tasks as parameters and return values.  So, a bit more effort is required.

One other thing to consider is the cancellation process.  With the BackgroundWorker, we raise a flag and then set the Cancel property on the event argument.  With the Task, the cancellation process throws an exception, and exceptions are relatively expensive.  Unfortunately, throwing an exception is the standard way of making sure the Task's IsCanceled property is set to true.  Since IsCanceled is read-only, it cannot be set directly.  So, we get a bit of a performance hit with the cancellation process for Task.  It's probably not enough for us to worry about in most cases (definitely not in this scenario), but it is something to be aware of.

Advantage Task
Tasks are extremely flexible and powerful.  We only touched on a very small part of what Task can be used for; there is much more (such as parallel operations).  And once we start using Task more frequently we can better understand how to take advantage of the async and await keywords that we have in .NET 4.5.

[Update Jan 2015: If you want to take a closer look at Task, be sure to check out the article series here: Exploring Task, Await, and Asynchronous Methods]

The Verdict
The BackgroundWorker is a specialized component.  It is very good at taking a single process and moving it off of the UI thread.  It is also very easy to take advantage of cancellation and progress reporting.

For this scenario, I would lean toward using the BackgroundWorker component -- this is because I like to use the most precise tool that I can.  And this scenario is just what the BackgroundWorker was designed for.

With that said, I am using Task more and more in my code in various scenarios.  It is extremely powerful and flexible.  I am a bit disappointed to see that Task is not 100% compatible with WinRT (although there are fairly easy ways to go back and forth between Task and IAsyncOperation).  But then again, the BackgroundWorker doesn't even exist in the WinRT world.

Wrap Up
I have a bit of a soft spot for the BackgroundWorker component.  I have found it incredibly useful in many projects that I've done.  And if you are dealing with a situation where the BackgroundWorker fits in, I would still encourage its use.  (If you want to review those uses, check here: BackgroundWorkerComponent: I'm Not Dead Yet.)

But, if you're dealing with a situation where the BackgroundWorker does not fit, then don't try to force it.  Instead, look at how Task can be used to make things work.  And as we use async and await more frequently, understanding Task becomes a critical part to writing understandable and reliable code.

Happy Coding!

Monday, January 21, 2013

Extension Methods - The Movie

So, I've created my first technical screencast: an overview of extension methods.  Now available on YouTube: http://www.youtube.com/watch?v=fKxy8Hl7Ht0.

If you'd like to see more videos, let me know the topics you're interested in (just leave a comment on this post).  If you don't want to see more, let me know that as well.  The goal is to make my blog, website, and other resources as useful as possible.

Happy Coding!

Saturday, January 12, 2013

Speaking in 2013

I've been busy setting up speaking engagements for 2013.  So far, I have 7 events booked (I'll post more details as the events approach).  If you'd like me to come speak at your event, user group, or corporate meeting, either drop me an email or send a request through INETA.

I specialize in intermediate .NET topics -- the topics that developers need to move up to the next level, and I've received good responses from new developers and seasoned developers alike (you can view feedback on SpeakerRate and my website).  Popular sessions include Design Patterns, Lambda Expressions, Delegates, Interfaces, Generics, and Dependency Injection.  For more details, check out the Demos section of JeremyBytes.com: http://www.jeremybytes.com/Demos.aspx.

Some new topics planned for this year include a practical introduction to the Model-View-ViewModel (MVVM) Design Pattern, how to perform common actions with MVVM, an overview of Unit Testing, as well as Mocking Strategies for Unit Tests.

I hope to see you at an event this year.

Happy Coding!

Monday, December 31, 2012

2012: A Look Back

The end of the year is always a good time to take a look back and evaluate progress.  It seems like 2012 has been a busy year for me, so let's take a look back at Things I've Done, Things I've Learned, Cool Stuff that Happened, and some Thing I Didn't Get To.

Things I've Done
Speaking
It seems like I did a lot of speaking this year.  Anyone who's heard me speak has probably picked up on how much I love it, so I try to get out to as many events as I can.  This year I presented 33 sessions at 19 events.  The events included 5 Code Camps: the 3 So Cal Code Camps, Desert Code Camp in Arizona, and the Silicon Valley Code Camp (my first time there -- wow, it's big).

The rest of the presentations were at various User Groups in So Cal as well as Arizona and Nevada.  A big thank you to all of the user groups who hosted me; I always have a great time.  (And not that I'm hinting or anything, but I'm available again this year -- just use the INETA request link on the right.)

Blogging
I wrote 54 blog articles this year (55 if you count this one).  That's the most so far.  The articles are a mixture of technical articles, book reviews, upcoming events, and answers to questions from session attendees.  I even had a couple of 5 part series articles.  It was nice to have some free time earlier in the year.  I need to make sure that I set time aside specifically for technical articles.

New Sessions
I came up with 2 new sessions this year complete with code samples and walkthroughs: T, Earl Grey, Hot: Generics in .NET and Dependency Injection: A Practical Introduction.  My goal was to come up with two sessions, and I'm glad that I had a chance to present the new topics.  Dependency Injection has been a very popular topic, and I'm sure that I'll be speaking on that throughout the coming year.

Things I've Learned
It's been a big year for learning new things.  As usual, most of my learning is just-in-time learning for whatever projects that I'm working on.  I had a chance to work on a great WPF project (I really love XAML) that uses Prism (XAML application guidance from the Microsoft Patterns & Practices team).  If you've been following my blog, you've seen my thoughts on the framework.  And if you haven't been following my blog, you can catch up here and here (short version: Prism has worked very well for this particular project).

I've also learned quite a bit about Dependency Injection both through Mark Seemann's excellent book and from experience using it myself.  I also had to do a bit of learning outside of my project requirements so that I could write the new session mentioned above.

And one of the big reasons I'm a fan of Dependency Injection is Unit Testing.  I really dug in to Unit Testing this year, and I'm surprised at how quickly I took to it.  I've used mocking and dependency injection to isolate units of code for testing.  The one thing I like most about unit testing is that I can refactor with confidence.  If there's a bit of clumsy code that needs to be reworked, I first make sure that I have good tests of the functionality.  Then when I extract methods or update algorithms, I can be sure that the code is still working as intended.  As I mentioned in an article earlier this year, I'm still not at TDD yet, but I find myself doing small bits of TDD during my coding process.

Honorable mention goes to MVVM and Tasks.  I've been buried in MVVM and doing a bit of fine-tuning to make sure that I have good separation of concerns in the presentation of my applications.  I've also dug into Tasks a bit deeper and have been learning about asynchronous calls, UI interaction, exception handling, and unit testing.  Lots of good stuff.

And 2 of the most impactful books that I read this year are Clean Code and The Clean Coder.  Clean Code has made me rethink some of the ways that I've been writing methods.  I'm starting to think smaller with more layers -- something I was reluctant to do before.  The Clean Coder has made me think more about myself as a professional -- making sure that my conduct is appropriate, that I'm clear with my communication, and that I live up to my commitments.  This is definitely a process (both the code and me), so I'll keep moving forward in both areas in the coming year.

Cool Stuff that Happened
Probably the coolest thing that happened this year was being presented with a Microsoft MVP Award.  It was a great honor to be recognized for my development community contributions, and I'm looking forward to attending the MVP summit with the goal of making lots of new MVP friends (in addition to the MVP friends that I already have).

I've been getting a bit of recognition at Code Camps as well.  At the So Cal Code Camp in Los Angeles, I had someone ask if I was giving the Design Patterns talk again.  And at the Desert Code Camp in Arizona, I had someone ask if I was talking about Lambda Expressions.  These people attended my sessions the year before and still remembered not just me, but the topics as well.  That makes me feel like I'm really making an impact with the topics that I present.

Another cool thing is that my blog is getting over 1,000 hits per month (I even had close to 2,000 in September).  That might not sound like much (and it really isn't), but it's a big increase over the 250 to 350 hits per month that I used to get.

One thing that has directed some traffic to my blog is a mention on StackOverflow (thanks for the referral, Peter Ritchie).  For some reason my articles on the BackgroundWorker component get a lot of hits.  I guess it's because I have a soft spot for that component.  I know that it will probably go away soon (it didn't get included in WinRT), but I'll hang onto it as long as I can.  It's great at what it does.

Also for some strange reason, if you Google "MVVM Design Pattern", one of my articles comes up on the first page.  That's driven a lot of traffic to my blog (which is really cool), but I'm not quite sure how I got ranked so high.  I guess I shouldn't complain because it probably won't last too much longer.

Things I Didn't Get To
There were a couple of things that I didn't get to this year, but there's always next year.  First, I was planning on getting my CTT+ certification (Certified Technical Trainer).  I'm still interesting in pursuing it, but I didn't get to it this year.

I also didn't produce any technical videos this year.  I was planning on putting together a handful of quick video tutorials on various topics (like lambda expressions and delegates) but never got around to it.  A friend recently asked me for some feedback on a video that he's producing, and I think that might have given me the kick in the butt that I need to start making my own.

A Great Year Gone -- Another One Coming
Overall, it's been a great year.  I'm learning and growing as a developer -- that lets me know that I'm still interested and haven't stagnated.  I'm still having a great time speaking and mentoring, and I love to help other people.  And it's been really great to get some recognition from the developer community.

There's a great year ahead.  I've got some exciting things lined up.  And I also have no idea what's going to happen with a lot of other things.

Take a few minutes to reflect on what you've learned this year and how you've grown as a developer.  If you're not constantly learning, then you're probably falling behind.  If you don't already attend a local User Group, find one.  It's a great way to keep in contact with other developers, to find out what's going on outside of your company, and to learn about lots of great technologies.

Looking forward to another great year!

Happy Coding!

Monday, December 17, 2012

Update on Windows 8 Guidance

Last week (Five Months In: Working with Prism in WPF), I mentioned that application guidance for Windows 8 is still pending.  As an update, Blaine Wastell published an article a few days ago with the roadmap for Windows 8 guidance: Prism on .NET 4.5 and the road to Windows 8 apps.  So, it looks like we have something to look forward to from the Patterns & Practices team in the next few months.

Happy Coding!

Sunday, December 9, 2012

Five Months In: Working with Prism in WPF

Several months ago, I put down some initial thoughts regarding Prism: First Impressions: Working with Prism in WPF.  Now that I've been working with Prism for five months, I thought it was time for a follow-up.

It turns out that my opinions haven't changed much from those first impressions.  Prism is working out very well for the project I'm working on.  Taking advantage of the modularity (and the independence of each module) has allowed us to quickly modify and add to our task workflows.  We've managed to keep good separation and isolation which has made unit testing much easier.  The navigation objects are working as expected.  And the helper objects make the code much more compact, readable, and maintainable.

Prerequisites
I have confirmed my opinion that Prism is not for beginning programmers; there are a number of intermediate topics that are necessary to understand.  What is interesting is that I have articles or presentations that are centered around these prerequisites.  I didn't plan for this, it just turns out that the topics I've written about happen to revolve around the foundational knowledge required for Prism.

Here's the list from the previous article along with links to my materials:
These articles are a good place to get started.  By understanding these topics, you will be better prepared to work with Prism in your applications.

Useful Features
In the previous article, I mentioned a number of features that I liked.  That list is still accurate.  I'll go into a little more detail on 2 of these features.

DelegateCommand
The DelegateCommand allows you to create an ICommand object with much less code.  Commanding is used to data bind to buttons in the UI.  Let's compare some code.

To implement ICommand yourself is not very complicated.  But there is a lot of boiler-plate code in a custom object.  Here's a sample command implementation (this is taken from the Dependency Injection session samples):


As we can see, there is quite a bit of code here, but we really only care about the last line (that assigns to the People property of the ViewModel).  The rest is plumbing.

Compare this to using a DelegateCommand from the Prism framework:


This allows us to do the same thing (assign a value to the People property), but we can do this with just one line of code (the DelegateCommand constructor) instead of needing to create a custom class.  The parameter of the DelegateCommand constructor is the "Execute" we want to perform ("Execute" is part of the ICommand interface).

ICommand has another method: "CanExecute".  This returns true or false depending on whether the command can be executed.  In our example, this always returns "true".  But sometimes this is more complicated -- such as if we need to check a property or run some code.  The DelegateCommand constructor takes a second parameter which is a delegate for "CanExecute".  If you do not provide one, then "CanExecute" is always true.

As you can see, DelegateCommand makes our code much more compact.  And if we don't want to use a lambda expression (or if our Execute is several lines of code), then we can use a standard delegate method instead.  The result is that it is easier to see the intent of our code.  Instead of looking through a custom command object for the Execute method, we have the code right here in the constructor (or a pointer to it in the case of a named delegate).

When you have a number of commands in the application, this makes a huge difference in the amount of code that needs to be written as well as the readability of that code.

NotificationObject
NotificationObject is another class that is provided by the Prism framework.  This class implements the INotifyPropertyChanged interface.  This interface needs to be implemented in order for data binding to work as expected in XAML.  The interface itself is not hard to implement (just a few lines of boiler-plate code).  The difference between NotificationObject and manual implementation has to do with the RaisePropertyChanged methods that are available.

When implementing INotifyPropertyChanged, you generally make a call to RaisePropertyChanged in the setter for a Property, such as this:


The RaisePropertyChanged method will alert the UI that the underlying property has been updated and that the UI should refresh the binding.  Notice that this version of RaisePropertyChanged takes a string parameter.

In contrast, NotificationObject provides a RaisePropertyChanged method that takes an Expression.  This lets us write code like this:

Your first thought might be, "I don't see much of a difference."  But there is.  Instead of using a string, we use an expression with the actual Property.  This means that we get IntelliSense when we are creating this method.  It also means we will get a compiler error if we type the property name incorrectly.  And most importantly, if we rename our property, our refactoring tools will automatically update the RaisePropertyChanged method as well.  Using properties over strings is definitely the way to go.

Nothing You Can't Do Yourself
I had an interesting conversation with someone about Prism.  He asked me what I liked about it, and I told him that I really liked the DelegateCommand.  His response was that you could create a DelegateCommand object yourself -- it's only about 15 lines of code.  And he is absolutely correct.

Prism doesn't perform any magic.  It consists of a set of helper classes and methods that you could implement yourself.  But we don't have to.  The Patterns & Practices team has implemented these for us and put them together in a package that is easy to use.

If you don't like any of the implementations, you are free to change them.  Prism comes with all of the source code (including unit tests).  So you can enhance or re-implement any of the features.  My experience is that the features are well-implemented and have met my needs.

What About Windows 8?
My one disappointment around Prism is that it looks like there won't be an implementation for Windows Store Applications.  Prism covers a lot of platforms: WPF, Silverlight 5, and Windows Phone 7.5.  The latest rumors are that there will be a different guidance package from the Patterns & Practices team for Windows Store Applications, and I have not been able to hunt down a beta or a release date at this point.

If you are developing Windows 8 desktop application with WPF, then Prism will work just fine.  But for Windows Store Applications, we will need to wait for another solution.

[UPDATE: There has been announcement regarding guidance for Windows Store Apps.  More info: Update on Windows 8 Guidance]

Wrap Up
As I mentioned, my opinion of Prism has not changed much from my initial impressions of working with it.  It has been a very good framework for my current project, and I will keep it in mind for future projects.  If you are working on fairly straight-forward applications or applications with just a few screens, then Prism may be more than you need.  But if you are working on modular or enterprise-level applications, it may be just what the doctor ordered.

Happy Coding!