Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Christopher Bennage

Our WPF book is now available!
follow @bennage on Twitter!
 

November 2008 - Posts

  • Dubious Honors

    Update: With striking proof that I'm dense and a Developer of Little Brain, Andrew points out that the results are sorted by date added. :- P

    On at least one torrent search site, our book is the #2 item when you search for WPF. Not searching for "WPF book", just "WPF". Rock on.piratedbook

    I have an alert setup that notifies me every time the book title is indexed on Google. There's an new pirating (free books!) link about once a week.

    If only I had a positive review for each site! :-)

  • Talks in December

    12.06 @ Tampa Code Code

    Expect lots of good content at this code camp. My session description is...

    An Introduction to WPF - A session for those who would like to know what WPF is all about. We’ll cover the basic concepts of WPF, discuss where the technology is useful, and follow it up with a handful of code examples. If you are interested to know if WPF can benefit your team, this is a session for you.

    This a free event, but you should register.

    (This is the same presentation I gave at the Tallahassee Code Camp 2008.)

    12.11 @ MSDN Developer Conference (Orlando) 

    This event is for everyone who (like myself) wasn't able to make it out to PDC this year. Just in case you've watched all the sessions online and think that you will see nothing new, we are planning on mixing it up a little bit.

    The cost is $99. Check the out the site for registration and agenda.

    Cool Stuff in January

    I am also looking forward to a Game Development in Silverlight talk in Tallahassee, and a TDD Firestarter in Tampa (along with a couple of other guys you might know.)

  • Unit Testing Change Notification

    In WPF work, it is very common to work with implementations of INotifyPropertyChanged. We need support for change notification in order to bind to the UI, and this interface is frequently the best approach. This means I have lots of properties that look like this:

    public string FirstName
    {
        get { return _firstName;}
        set
        {
            _firstName = value;
            RaisePropertyChanged("FirstName");
        }
    }

    I've gone back and forth as to whether or not I should test these properties for change notification on properties.  My main argument for not doing it, is the ROI. The typical test pattern might look something like this:

    [Test]
    public void FirstName_raises_change_notification()
    {
        bool has_property_changed = false;
        _person.PropertyChanged += 
            (s, e) => { if (e.PropertyName == "FirstName") has_property_changed = true; };
        _person.FirstName = "new_name";
    
        Assert.That(has_property_changed);
    }

    Sure, this isn't a long test, but when you consider the number of properties I could be dealing with you'll see the potential for a lot of noise.

    I also don't like the fact that I have yet another string in my code; easy to miss when refactoring. Nevertheless, I feel like I ought to have test coverage for these change notifications.

    What's the solution? Make change notification easier to test.

    Step One

    I extracted out the test pattern into an extension method that applies to INotifyPropertyChanged. So my test now looks like this:

    [Test]
    public void FirstName_raises_change_notification()
    {
        _person.AssertThatPropertyRaisesChangeNotification(
            () => _person.FirstName);
    }

    By using an expression to identify the property, I removed the magic string. I also have an overload if I need to set the property to a specific value:

    [Test]
    public void FirstName_raises_change_notification()
    {
        _person.AssertThatPropertyRaisesChangeNotification(
            () => _person.FirstName, "new_name");
    }

    The code for the extension is this:

    public static class AssertExtensions
    {
        public static void AssertThatPropertyRaisesChangeNotification<T, K>(
            this T propertyOwner,
            Expression<Func<K>> property,
            K valueToSet) where T : INotifyPropertyChanged
        {
            var has_property_changed = false;
    
            var memberExpression = (MemberExpression) property.Body;
            var propertyInfo = (PropertyInfo) memberExpression.Member;
    
            propertyOwner.PropertyChanged +=
                (s, e) => { if (e.PropertyName == propertyInfo.Name) has_property_changed = true; };
    
            propertyInfo.SetValue(propertyOwner, valueToSet, null);
    
            if (has_property_changed) return;
    
            var msg =
                string.Format(
                    "The property, {0}, did not raise change notification.\n" +
                    "The property was set to '{1}'.\nThe property is owned by {2}",
                    propertyInfo.Name,
                    valueToSet,
                    typeof (T).Name);
    
            throw new AssertionException(msg);
        }
    
        public static void AssertThatPropertyRaisesChangeNotification<T, K>(
            this T propertyOwner,
            Expression<Func<K>> property) where T : INotifyPropertyChanged
        {
            propertyOwner.AssertThatPropertyRaisesChangeNotification(property, default(K));
        }
    }

    Step Two

    The next step (which I haven't done yet) would be to provide a fluent API for easily expressing which classes and properties I care about. With the extension above, I'm still just dealing with one property at a time.

    What I would like is a way to say "all public properties on class X, except Y & Z" or perhaps "only properties Y & Z on class X". Then I can have concise, descriptive, intent-revealing tests regarding change notification.

    Thoughts? Improvements?

  • Building a WPF Application: Part 5

    ChumChase Table of Contents

    About 5pm today I was burnt-out from some difficult work on a particular client's project. Our last four projects have all been WPF with an emphasis on UI and UX. Fortunately, most of these were green field project, but the one I was working on today was not.

    What made it so difficult is that the application is practically one big xaml file with all of the logic in the accompanying code behind. It's hard to modify the UI when it is so tangled up with the logic.  <sigh />

    So at 5pm, I decided to take a break and work on ChumChase a bit.

    Hope I'm not embarassing anyone...Here's a quick overview of what I did:

    • I began a basic 2D view that will be the actual default view for the application. The 3D view is cool, but it's a novelty and not much else. The 2D is really simple at the moment.
    • You can toggle between the 2D and 3D views. The underlying presentation model is the same. It doesn't change. The only code associate with the views is the trackball code for the 3D view.
    • I added profile pictures for the user associated with a feed entry.

    Chasing Simplicity

    Let's review my thinking process for adding the profile pictures.

    I assumed that I could get the url for a given user's profile picture from FriendFriend's API. In fact, it is quite simple.

    http://friendfeed.com/nickname/picture?size=medium

    where nickname is the user you are interested in. You can provide small or large for the size as well. FriendFeed uses the term nickname where everyone else would use username.

    The data template for a individual item on the feed looks like this (simplified for the post):

    <DataTemplate>
        <Border>
            <DockPanel>
                <Grid DockPanel.Dock="Left">
                    <!-- this image is where the profile pick will go -->
                    <Image Width="50"
                           Height="50"
                           Margin="2,2,8,8" />
                    <Image Width="16"
                           Height="16"
                           VerticalAlignment="Bottom"
                           Margin="2"
                           Source="{Binding Path=ServiceIcon}"
                           HorizontalAlignment="Right" />
                </Grid>
    
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Path=Title}"
                               TextWrapping="Wrap"
                               FontSize="16" />
                    <TextBlock Grid.Row="1"
                               Text="{Binding Path=User}" />
                </Grid>
            </DockPanel>
        </Border>
    </DataTemplate>

    The template is bound to an instance of FeedEntry which represents a single entry in the feed. Notice the binding to User in the bottom TextBlock. That's simply the nickname of the user associate with the entry.

    My first thought was to add a new property to FeedEntry called UserProfilePictureUrl and bind it to the Source property on the Image.  This new property would merely inject the value of User into a url and return it. Even though it was simple, something nagged me about this. I felt like it should not be a concern of FeedEntry to provide the url for the profile picture. In addition, I knew that I would need to get the url in other places where FeedEntry was not part of the picture.

    In some sense, the translation of a nickname into a profile pic url is standalone. I mean, the concept exists independent of any of the current entities in my model. Because of this, I decided to encapsulate the concept in a value converter.

    public class NicknameToProfilePicUrlConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string size = (parameter == null)
                              ? "medium"
                              : parameter.ToString();
    
            string url = string.Format("http://friendfeed.com/{0}/picture?size={1}",
                                       value,
                                       size);
            return url;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    Then in the xaml, I used the converter like this (after adding a reference in the resources):

    <Image Width="50"
           Height="50"
           Source="{Binding Path=User, Converter={StaticResource NicknameToProfilePicUrl}}"
           Margin="2,2,8,8" />

    Notice that I'm actually binding to the nickname (note to self: I should rename User to Nickname). The converter takes the nickname and returns the url. Converters like this are easy to test as well.

    This implementation isn't all that robust, but we'll handle that when the need arises.

    So how do you feel about having a value converter that is so specific? I find myself using them more and more. Does it bother you to take this approach?

    Off to bed...

  • Building a WPF Application: Part 4

    Table of Contents

    Since my last post on building ChumChase, I've had a couple of projects that have changed my thinking just a bit about how to architect a WPF application. When I reviewed the code for ChumChase (in order to continue this series) I found it needlessly complicated in more than a few places. So I decided to fix it.

    A good portion of what I wrote in the first three posts is still true, but I did make changes in two major areas.

    Too Much Focus on Presenters

    I have had a habit of naively creating presenter classes for every "screen" within an application. I think this is a consequence of my experiences as a Web developer using MVC. With MVC, you really need a controller to coordinate any action with the the view. Not so with a technology like WPF.

    What's sad, is that I've known this intellectually for some time. Posts by Dan Crevier and John Gossman explained patterns like DataModel-View-ViewModel a couple of years back.

    If that's the case, what did I change?

    First, I created a model that represented what is going to be visualized. This is the "ViewModel" mentioned above, although I tend to use the term "Presentation Model". This view or presentation model often mirrors the actual domain model (or data model) of the application, but it has an entirely different set of concerns.

    For example, my company worked on the recently released (to beta) MapDotNet Studio UX. It's an application for designing maps to be rendered with MapDotNet Server. There's a domain model for representing the maps and the various layers of data that might be represented on them (e.g., parks, property parcels, postal codes, etc). In this application, we display a list of maps that can be edited. Underlying the application is a domain model that represents the maps and business of rendering them on a server. However, in presenting this model in the UI we need to do things like: keep track of the currently selected map, know wether or not a map is open for editing, and so on. These are presentation concerns and have no business in the domain model. Thus, we create a presentation model.

    In many cases, this presentation model is a wrapper around the domain model and adds the presentation concerns. However, the presentation model might stand alone,similar to data transfer objects. In that case, there would need to be some sort of translation between the domain model and the presentation model. All that is to say that there is more than one way to do it.

    In some cases, presenters make a lot more sense that a presentation model. The scenario we frequently encounter is a form or wizard-based UI. Presenters are much better suited for these types of UI's.

    Of course, there is no reason why an application might not have presenters and presentation model.

    Where do you put stuff?

    Partial Screen Shot of ChumChaseI'll reference our work on Studio UX again; a user loads a map up from a server, styles the map, and then saves or publishes the map back to the server. A user might initiate publishing a map from any number of places in the UI: right-clicking on a map in the explorer pane, Ctrl+S when a map is open, and so on. So where should the code that actually publishing the map live? These different portions of the UI might be backed by different presenters, or by a class in the presentation model. How do we handle the save?

    The missing link is using the Command pattern.

    Of course, the Command pattern is built into WPF. It's all other place and part of the WPF Way. Take a look at ApplicationCommands.Save, it's practically a stub for what I just described.

    Even though I live and breathe WPF, I was not bringing these concepts into my solutions.

    The act of saving the map can be expressed as a command. It might be class named something like the PublishMapCommand. This hypothetical class PublishMapCommand is a first class member of my presentation model. (I'm simplifying the scenario from what the real app dealt with). It has some prerequisites of course, for example it needs a map to operate on, and it might need access to a repository, but it's not tied to a specific presenter or even to a specific instance of a map. The map is provide by the context (the node I'm clicking on the explorer, or the tab that has focus when I press Ctrl+S). My IoC container can handle injecting the repository. And now, I can bind disparate parts of the UI to the same command.

    The command is also highly testable because it so focused, it does just one thing. As a side note, thinking about your domain in terms of Verbs is really useful. I would argue much more useful that the traditional approach of thinking in Nouns. Verbs == Behavior, Nouns == Data.

    Summing It Up

    My basic approach for the UI is this: first, I am thinking in terms of a presentation model. An important part of this model is the verbs or commands. Secondly, where it makes since I use presenters. If necessary, I'll introduce an application controller (or master presenter) to help orchestrate the entire application. Again, if necessary.

    The lesson for myself was this: don't get so caught up in the design, that you lose sight of what works. Keep it clear, keep it simple.

    I've already committed the changes for ChumChase that reflect these ideas. There aren't any commands in the model yet, but I did away with the HomeFeedPresenter. Instead, I now have the beginning of a presentation model that models the data I want visualized in the application. Right now, that is merely the home feed.

    You can get the latest for ChumChase here. The application actually works now , well the minimum base feature works. You'll be prompted for your user name (or nickname) and your remote key. The remote key is different from your FriendFeed password, and you can find it here (assuming you are logged into FriendFeed.) If you are lazy, you can use the default credentials for the dummy account I set up.

    Oh, and I started playing with the new 2D on 3D stuff, that's what the screen shot is, but I'll blog about that later.

    Oh yeah, and there are some wicked cool new WPF binding tests via Caliburn in there as well.

    Update: Karl Shifflett posted recently on the M-V-VM pattern, and also directs some attention (rightly so) to Josh Smith's site.

    More to come...

  • Solving Problems with TDD

    I'm giving a talk on TDD at our local UG tonight, and under the influence of some recent posts here on devlicio.us, I just finished reworking my presentation. This post is an outline for the first half of my presentation.

    The Problems

    Code has entropy. That is over time it deteriorates. At least, that's the metaphor we developers like to use. What is really means is that the code becomes harder to maintain and extend as it is maintained and extended over time. Did you follow that? Our typical approach to maintaining and extending code causes the code to become fragile and rigid and thus harder to maintain and extend in the future.

    There are three common difficulties that arise, maybe more, but I'm focusing on three:

    • Unchangeable Code
    • Unintelligible Code
    • Unnecessary Code

    A portion of code becomes unchangeable when its deeply entwined and entangled with other portions of code that have different responsibilities. You can't change method X because we really don't know what that will do to Y and Z.

    Code can become unintelligible for lots of reasons: abbreviated names, circuitous logic, enormous methods, confusion of responsibilities, use of php☺, etc.

    Finally, unnecessary code is code that is not used by the system. It can be vestigial, or as often happens, it can be the result of feature anticipation. We thought this was going to be needed in the app, so...

    The Solutions

    There are some generally accepted solutions to these three problems.

    In the case of unchangeable code, we can apply such patterns as Separation of Concerns (SoC) and the Single Responsibility Principle (SRP). For addressing unintelligible code, we have a number of techniques such as thoughtful comments, explicit naming, SRP again, etc. Finally, for unnecessary code we have the old axiom of You Ain't Gonna Need It.

    Okay, so we know how to solve the problems. Or least, we know how to mediate them. So what? What does that have to do with TDD?

    My proposition is this: solutions are without value unless they are applied.

    Additionally, when a problem occurs over time, the solution must be applied over time.

    The Analogy

    I just started going to the gym. It's been about a decade since I did that, but I'm back. For the past several years however, I have been preaching to certain family members the value of exercise and healthy diet. I knew the benefits: stress reduction, longevity, improved sleeping, and just plain feeling better. However, I wasn't really doing either.

    I had the problem and I believed in the solution and, in fact, I made attempts to employ the solution. Ultimately, I was unsuccessful. That is, until I committed to go to the gym three days week at a set time and with a workout buddy.

    My point is this, we are human beings and despite being smart we frequently revert to doing "the easiest thing". Therefore, we ought to set up some sort of framework of methodology or discipline where the easiest thing is actually what we want to do.

    Additionally, I have to keep on going to gym. For as long as I want to be fit, I will need to exercise. In the same way, for as long as I want my code to fit I will need to apply good principles.

    TDD as a Discipline

    I will argue that TDD is a discipline that enables the application of the solutions outlined above. Perhaps you apply those solution naturally. Perhaps you can benchmark 200lbs because of your genetic disposition. Bully for you. Go ahead and skip the rest.

    Let's examine a few essentials of TDD and see if they really address the problems we outlined.

    Test First

    I'm an advocate of automated testing in general. However, I do think that writing your tests first yields additional value. Primarily, it helps you discover your ideal API. In other words, you can design your API up front such that it is more intuitive. More intuitive means easier to understand.

    Secondly, testing first helps you identify dependencies early. You quickly discover that class X will need a Y and so you are forced to create seams in the application at the onset. This encourages SoC and SRP.

    Testing Units

    It took me a long time to understand the "unit" part of unit testing. The idea is that you decompose your problem into units, and deal with the problem one unit at a time. You could call this "test just one thing". Okay, well what is "one thing"? That is hard to tell and comes with experience. Nevertheless, the practice of trying to decompose a problem and identifying units leads you back to SoC and SRP again.

    Just Enough Code

    Another tenet of TDD is to write only enough code to pass the test. Our natural instinct is to anticipate. It is part of what we are as developer, and it is not a bad thing. However, like many strengths, it can become a weakness. By constraining ourselves to a single problem at a time we will end up with less code. It also forces us to be conscious about our anticipation and to ask if a given scenario is really necessary.

    Conclusion

    I know that there is much contention over the actual value of TDD as a practice, and I am not going to force it on anyone (unless I hire you and now you are warned). However, I have found it to be a useful discipline for helping me to overcome common problems and because of that I encourage it's use.

  • The Upcoming NHibernate Profiler

    Rob and I have had the fantastic opportunity to contribute to Ayende's NHibernate Profiler. It's somewhat analogous to SQL Profiler, and yet—oh, so much more.

    I'm really excited about this tool, not just because it has afforded an opportunity for interesting WPF work, but because of what I am learning about using NHibernate.

    Ayende just posted a guided tour of the application, along with the anticipated cost (which I consider very reasonable). Go check it out!

More Posts

Our Sponsors

Proudly Partnered With