Sunday, October 26, 2014

Rewriting a Legacy App - Part 3: Accepting Commands

So, I'm continuing to work on my house automation software to replace my legacy system. In Part 1, we looked at existing functionality and figured out our minimum viable product (MVP). In Part 2, we got the basics of the hardware interaction working. Now we'll expand things to work with various devices and commands.

But before we move on, let's review the requirements:

Needed for MVP:
  1. Send commands through the serial dongle
    This is the purpose of the system.
  2. Send commands for 8 devices on House Code "A"
    These are the only devices that are actively used.
  3. Fire on/off/dim events on a schedule
    To maintain the air conditioner functionality (and current lighting schedule).
We've already got #1 in place, so let's expand things to #2 -- being able to work with all 8 devices on the system.

[Update: Code download and links to the entire series of articles: Rewriting a Legacy App]

Separation of Concerns
Now, I realize that the typical way of implementing a minimum viable product is to not really worry about the code organization (just get it working). I have trouble working that way. I like to clean code up as I go along.

When moving on to the next step of accepting commands for various devices, I really wanted to separate the concerns. One thing I didn't like in the test code was the mixing of building the message (specific to the X10 system) with sending the message (interacting with the serial port). So I created a new library and a couple of classes to handle this:


The first file is "DeviceCommands.cs". This simply has an enumeration to hold the "On" and "Off" values (and in the future, it will handle other commands as well).

The MessageGenerator is responsible for building the message that we'll send through the serial port, and the SerialCommander is responsible for sending those commands. Let's look at the SerialCommander first.

No Sleeping Allowed
When we were going through the test code in the previous article, it was littered with Thread.Sleep commands. These are generally not good because they block the current thread. But there's some good news for our code.

I did some additional tests and found that the Thread.Sleep commands were not necessary. When I removed them, the hardware interaction continued to work just fine. As mentioned, I brought these over because they were part of the legacy implementation. But they may have been needed on earlier systems just for timing issues. Perhaps (just a guess) modern computers run fast enough that they no longer run into issues here.

Creating and initializing the serial port is very similar to what we had in our test code:


The only difference here is that I added a configuration setting for the COM port. This is the one part of configuration that may need to be changed depending on the physical computer. The code also defaults to "COM3" (in case there is no configuration setting). This probably isn't a good way of handling a default, but we can loop back around to this later.

The method to send the command has a new parameter, but the bulk of the code is unchanged (except for the removal of the Sleep commands):


Just like before, it opens the serial port and initializes the DTR/RTS control signals. Then it loops through the message and sends the individual bits. And finally, it closes the serial port.

The biggest difference is that we're sending the message in as a parameter. We have to build this message somewhere. And that's the responsibility of the MessageGenerator.

Generating the Message
In order to fulfill requirement #2 for our MVP, we need to be able to interact with devices 1 through 8 on the "A" house code. To facilitate this, I created some static variables that we can work with.


I decided to go ahead and stick with strings for these values. I could have made them byte arrays and done shift left/shift right to process them, but the strings aren't causing any problems at this point, so we'll stick with them for now.

This code has the "header" and "footer" values that we saw earlier. In addition, I noticed that the first byte of the message (the middle 2 bytes) was the same for all of house code "A". So, I created a variable just for that. This means that our changing command portion is only 1 byte long.

To make things a bit easier, I created 2 lists: one for the "on" commands, and one for the "off" commands (I don't show the entire entry for the "offCommands" list, but you get the idea). This will give us a list that we can index into in order to find the value that we want. For example, if we want the "on" command for device #2, we can look at "onCommands[2]". I added the "dummy" values at the top of the lists since the indexers are 0-based. That way, we don't need to subtract 1 to get the right value.

With these static variables in place, we can now create a method that builds our message:


Notice that the "GetMessage" method takes 2 parameters: an integer for the device number and a DeviceCommands for the command. I spent a bit of time working on the parameters and the layout of the static variables so that this method would be fairly easy. Some of my other ideas included nested switch statements -- that seemed overly complex.

I start by validating that the device number is in a valid range. Since we're only supporting devices 1 though 8, this is important to validate.

Next, we start creating the message with the "header" and "codeA" parts.

Then we switch based on the command. If the command is "on", we look in the "onCommands" list from above; otherwise, we look in the "offCommands". As mentioned earlier, we can index into these lists based on the device number, and we'll get the right command string.

Finally, we add the "footer" to the message and return it.

Running the New Methods
Now that we have these classes in place, we can use them to send commands to any of our connected devices. Here's our updated console application (from Program.cs):


This uses our new classes to turn on device #5 and then turn off device #5. I was using this device since it was a lamp in the room that I was working in. This let me verify visually that the commands were working -- although I think my cats were getting kind of annoyed that the light kept going on and off.

And, of course, we can change the parameters of the "GetMessage" method to interact with any of the devices on the system.

Closer to MVP
Let's review our requirements again:

Needed for MVP:
  1. Send commands through the serial dongle
    This is the purpose of the system.
  2. Send commands for 8 devices on House Code "A"
    These are the only devices that are actively used.
  3. Fire on/off/dim events on a schedule
    To maintain the air conditioner functionality (and current lighting schedule).
By creating a parameterized method (along with the static variables for the various commands), we've fulfilled requirement #2. We can now interact with the 8 devices that are on house code "A".

I'm not completely happy with this implementation. In the console application, we need to create both the SerialCommander and the MessageGenerator objects. I don't want my calling application to have to know so much about the details. So at some point, I'll wrap these up into a class that is easier to work with.

What's left is to be able to process a schedule (requirement #3). This will be a little more involved. We'll need some sort of class that wakes up at particular times to fire events, and we'll need some way to persist the schedule to disk. We'll be looking at these in future articles.

So we can see that we've made quite a bit of progress toward our minimum viable product. And I like the direction this is going in so far. By eliminating the features that we don't really need, we've managed to come up with a system that is pretty quick to implement.

Stay tuned for more articles on this. The scheduling portion should be interesting (but I may swing off into some other articles in the meantime).

Happy Coding!

Saturday, October 25, 2014

Rewriting a Legacy App - Part 2: Working with the Hardware

The first step to rewriting an application is to figure out what we need (this is true when we're working on new applications, too). Last time, we looked at existing features and figured out the bare minimum that we would need to implement to replace existing use.

Note that I said existing *use* and not existing *functionality*. These are two different things. Here are the features that are currently used:

Needed for MVP:
  1. Send commands through the serial dongle
    This is the purpose of the system.
  2. Send commands for 8 devices on House Code "A"
    These are the only devices that are actively used.
  3. Fire on/off/dim events on a schedule
    To maintain the air conditioner functionality (and current lighting schedule).
Step one is to interact with the hardware by sending messages through the serial port. I wrote a test application to make sure that this would work. The code isn't very good, but it gets the job done. We'll clean up the code as we go.

[Update: Code download and links to the entire series of articles: Rewriting a Legacy App]

Communicating with a Serial Port
The first piece of the puzzle is to communicate with a serial port. As a reminder, we have a 9-pin dongle that we hook up to a USB port with an adapter:


Us old-timers (well it wasn't really that long ago) used serial modems to connect to other computers (whether to Wildcat BBSs or other systems). So, we're used to the things that need to be set up for serial port communication -- things like baud rate, parity, number of stop bits, and so forth. If you had the wrong settings for the system you were trying to connect to, then it didn't connect.

When setting up a serial port in .NET, we need the same information. Fortunately, I can bring these settings over from the legacy system -- with one exception. The COM port will vary depending on the hardware.

To figure out the COM port, I just plug in the USB adapter and take a look at the device manager:


This shows that we're using COM3. With this information, we can initialize a serial port.

A Test Library
For the initial test, I created a class library that we can use to send commands to the serial port. I'm expecting that we'll do a lot of refactoring of this code along the way. I called the class "X10Utils", and it has the following initialization code:


I won't go into the details. The only thing that has changed over the years is the baud rate. This started out as a slower value when I first put the legacy project into production. But now, we basically max out what is available with the serial port.

Sending a Message
This is where things get fun. In order to send a message to the system, we enable and disable DTR and RTS. DTR stands for "Data Terminal Ready", and RTS stands for "Request to Send". These are serial port control signals, and they (and others) would determine if a system was listening, sending, waiting, etc.

But these meanings have nothing to do with how they are used here. The use here was decided by whatever engineer designed this interface to the dongle.

So, we enable/disable DTR and RTS in a particular order to send a message. Here's an example of two messages:


The first turns on device A01 (that is device #1 on house code "A"). The second message turns off that same device. I represented the messages as "1"s and "0"s because that's how they were represented in the documentation that I originally used.

For each "1" in the message, DTR needs to be disabled and re-enabled. For each "0" in the message, RTS needs to be disabled and re-enabled. These sequences get translated into an RF signal that makes it's way to the transceiver module (don't ask me how that happens -- I'm not an electrical engineer).

Each message is broken up into 3 parts. The first line (2 bytes) is the header. This is the same for every message. The last line (1 byte) is the footer. This is also the same for every message. The middle line (2 bytes) is the actual message that is being sent.

Strings?
You've probably noticed that the message bits are represented as strings. I don't think that this is the best way to represent this data, but this is how it was represented in the legacy application. I left it for now since it's easy to copy over the data from the legacy application. Here's a small sample of the data:


You'll notice that the "xA1on" and "xA1off" values correspond to the middle lines of the code sample above. As you might imagine, there's quite a bit of this (16 devices and 16 house codes). This is one reason why I'm limiting things to just the devices being used (#2 from our MVP requirements).

Preparing the Message
There's really 3 parts to sending a message: (1) Prepare for the message, (2) Send the message, (3) Reset when done.

Here's the code to prepare to send the message:


This method takes a parameter to decide whether we're sending an "On" message or an "Off" message. The "message" variable is set to the correct value based on the parameter. (Again, not great code at this point.)

Next, we open the serial port and enable both DTR and RTS. The initializes the hardware device.

Then we have a "Thread.Sleep(10)". Now, Thread.Sleep is usually a bad idea. And one of the first things I want to do is to change this. But to get started, I'm moving the working code over from the legacy system. When I first wrote this code, I found that I needed "Sleep(100)"s in place between processing each bit. And I found that this value would vary depending on the computer. On previous systems, this value has been "100" and "50". I found that on my current computers (which are extremely fast compared to the hardware this was originally running on), I have the value down to "10". We'll work on getting rid of the Sleep a bit later.

Sending the Message
Now that things are prepared, we need to send the actual message. Here's how I process our "message" variable:


I simply "foreach" over each bit of the message. Since these are strings, this comes out as the character "1" or the character "0". Based on that, I click off RTS or DTR.

Again, the "Sleep" values are in there to give things a chance to register.

Resetting Things
After sending the message itself, we reset the serial port:


This closes the serial port once we are done sending the message.

So, there's not all that much code here. Let's see if it works.

Testing the Code
The best way to test this method is to plug things in and run the method. I created a console application to do just that.


This is pretty straightforward. I create an instance of our library class and call the test method twice -- once with "true" to turn the device on and once with "false" to turn the device off.

The main reason I'm doing both commands is because I'm lazy. The Transceiver Module (which is the one we talk to when we talk to the "A01" device), makes a satisfying clicking noise when it changes state -- either clicking on or clicking off. Since I run it through both states, I know that I should expect to hear 1 click (if it's already "on") or 2 clicks (if it's "off"). By sending both commands, I know I'll hear at least 1 click each time.

And when running the application, I do hear the module turning on and off: SUCCESS!

Where Are We?
So this is a really good start. We know that we can interact with the hardware. And this really is a big success. When I was first programming against this hardware, trying to figure out the timings and settings through trial and error, I went through about 2 weeks of frustration. Eventually I found out that I had my "1"s and "0"s inverted. Hearing that first click and seeing a light go on was a huge step forward.

Let's review what we need for our minimum viable product.

Needed for MVP:
  1. Send commands through the serial dongle
    This is the purpose of the system.
  2. Send commands for 8 devices on House Code "A"
    These are the only devices that are actively used.
  3. Fire on/off/dim events on a schedule
    To maintain the air conditioner functionality (and current lighting schedule).
We've accomplished #1: interacting with the hardware. As we move on to #2, we need to do some thinking and refactoring. We'll need to figure out if storing the commands as strings is practical (maybe it is). There may be a better way, but we also may not care about that when we're coming up with a working product. It may be better to spend our time on #3, which is a bit more complicated.

I haven't posted the source code because there really isn't much that you can do with it without the hardware. But if you'd like to see a copy, let me know, and I'll be glad to make it available.

We're well on our way to creating a replacement for an existing application. And it doesn't look like it will take much more work to get the minimum viable product.

Happy Coding!

Friday, October 24, 2014

Rewriting a Legacy App - Part 1: Looking for the MVP

Okay, so I've been meaning to re-write an application that has been running in my house for 10 years. The original was written in Delphi (which I haven't used for new projects since 2005, so it's been a while), and it's been serving it's purpose. But there are some features that I'd like to add, and some that I don't really need. So, it's time to analyze the existing application, come up with a minimum viable product (MVP), and move forward with a re-write.

[Update: Code download and links to the entire series of articles: Rewriting a Legacy App]

Home Automation Hardware
The application is to control home automation hardware that uses X10 technology. This is based on a starter kit that my brother gave me for Christmas one year. It came with a serial dongle, and he thought I would have fun programming for it.

The technology uses power line communication. Here's the basic hardware:


This shows the Transceiver Module (the one on the left with the antenna). This receives RF transmission from a physical remote (not pictured) or from a serial dongle (lower center). When it receives the command, it transmits to the other modules through the power lines in the house. On the right is a Lamp Module -- this has a built-in dimmer. There are also Appliance Modules that have on/off (but no dimming), and I have a special module for my wall-unit air conditioner.

The last piece in the picture is the serial adapter cable (from DB-9 to USB). This is so that we can hook up the dongle to a modern computer -- when was the last time you saw a serial port on a computer?

And if you're curious about how you program against the dongle, you enable/disable RTS and DTR in a particular order. I'll go into the details of this in a future article.

Original Intent
The primary reason I was interested in this technology is because I live in an apartment with a wall-unit air conditioner, and I wanted to be able to schedule the air conditioner to go on and off during hot days (when I wasn't home) to keep the place a reasonable temperature.

Here's the main screen of the current application:


This shows the various modules in my apartment (yeah, it's not a huge apartment, but it's the right size for me and the cats). This has buttons to manually turn things on and off. And the sliders are there for the dimmable items.

But the important part is the schedule:


This lets me set up a schedule to turn items on and off throughout the day. I can set the time, the function (on/off), the level (which is the dimming level), and the days of the week that this applies. On top of that, I have labeled Schedule Sets that let me enable/disable groups of commands.

For example, there is a schedule set called "Summer" that I can enable when it's hot. This turns the air conditioner on an off throughout the day -- currently set to alternating between 30 minutes on and 60 minutes off throughout the afternoon. I've found that this is enough to keep things a reasonable temperature. (And I'm sure the cats appreciate it.)

The user interface for the application isn't great, but this was created during the "battleship gray" era, so it's actually pretty impressive taken in that context.

Stuff That I Don't Need
The X10 system has the concept of a "House Code". This is the letter setting that you see on the modules. Each letter can accommodate up to 16 devices (the number on the Lamp Module). This lets you either segment devices if you have a lot of devices, or use a different setting if there is power line interference.

When I coded up the application, I coded for all of the House Codes. I made this configurable in the settings screen:


In reality, I've only ever needed House Code "A". So, I can eliminate the other settings (at least for now -- I can always add them in if I find that I need them in the future).

The other thing is that I coded for 16 devices. I have a total of 8 modules, and since X10 technology has gone out of style, I probably won't be acquiring any more (plus, I don't even use all the ones I have most of the year -- Christmas lights get put onto the system in December).

In addition, I don't really use the manual buttons in the UI. This application runs on the entertainment center computer. This computer is on all the time and plays music through the stereo (in addition to controlling the lights). The monitor for this computer is the television, and the only time I really use the application is to enable/disable the schedule sets. The rest of the time, I use the physical remote for manual operations.

Features I'd Like
There are a couple of features that I'd like to add. The first is being able to interact with the system over a network. The current application has a little bit of this -- it opens up and listens on a TCP port, and an application on the same network can communicate with it using a proprietary message format (nothing makes it outside of the local network).

Something else I'd like to add is temperature-aware operation. So, I'd like to be able to have the air conditioner cycle based on temperature rather than simply based on a schedule. For real-time operation, I would need some additional hardware (a temperature sensor), but I've also thought about hooking it up to a weather service. This way I would not have to manually enable/disable the schedule; I could have it automatically enable if the temperature is forecasted to be over 90F.

Finding the MVP
In order to replace the current system, I need to figure out the minimum set of features that I actually need.

Needed:
  1. Send commands through the serial dongle
    This is the purpose of the system.
  2. Send commands for 8 devices on House Code "A"
    These are the only devices that are actively used.
  3. Fire on/off/dim events on a schedule
    To maintain the air conditioner functionality (and current lighting schedule).
Not Needed:
  1. Manual control buttons/sliders
  2. Map of the apartment
  3. Scheduling UI
  4. Configuration UI
  5. TCP listener
So, what I'm saying is that in order to produce a minimum viable product that I can put into production, I don't need any of the current UI or networking elements. Now I'm sure that I'll want to add these later, but they aren't required to get started.

Not Much Needed
What we find is that when we analyze the current application and look at how it is *actually* being used, we really don't have very many features that we need to code up. As I've mentioned, I do have other features in mind, so I want to make sure that I don't code myself into a corner along the way. But let's start simply and work our way up from there.

I've already done some tests to confirm that I can communicate with the serial dongle through .NET (that's the environment we'll use for this application). So, it shouldn't take very long to implement these initial features.

The main reason that I'm writing about this is to motivate myself to actually do this project that I've been thinking about for a long time. I don't expect that the specific technologies will be of much interest, but the process of building the application will be interesting.

Next time, we'll take a look at the basic operation of sending codes through the serial dongle. Then we'll look at how we can use this to move toward the minimum viable product.

Happy Coding!

Wednesday, October 15, 2014

Developer Community Events & the Learning Mindset

This past weekend at Silicon Valley Code Camp, I was invited to be part of a panel discussion: Community, Career, and You: a Microsoft MVP Panel (big thanks to Esther Lee for inviting me to participate). This made me start to think a bit more about what I like about developer community events: the people.

I've often said that if you attend user groups, that puts you in the top 10% of people that I want to work with. This is because you are putting in your own time (time you aren't getting paid for) to try to better your skills. And this tells me 2 important things:
  1. You care about continuous learning.
  2. You care enough to put your own time into it.
Lots of Events
I have lots of experience with this. Just this year, I've been to 20 events as a speaker and attended about half a dozen more. I get the chance to speak a lot in Southern California because there are lots of .NET user groups in the area. Since traffic is usually horrible, no one wants to drive 30 miles to get to a user group after work, so there are lots of little groups scattered around the area.

I've been involved with the developer community for close to 5 years, and my experience with the people who attend these types of events has been fairly consistent: men and women who are interested is learning something new, talking to other developers about their experiences, and investing their own time in the process.

And this is what I like about community events like user groups and code camps.
Every single person is there to learn or share or both (most often both).
I try to talk to as many people as I can when I'm at these events. This past weekend, I was able to catch up with people I hadn't seen for a while, shoot the breeze with some people that I know well, and also meet a whole bunch of new people.

At code camp, I try to have lunch with someone I don't know. I'm not afraid to start a conversation or join a conversation (which is way different from how I was 5 years ago).

The Difference of the Developer Community
The thing that I like about the developer community is the consistency of this learning mindset. At professional events, I've seen a different mix. There definitely are people who are there to learn, but there are also people who see it as a paid week away from the office.

I still remember meeting someone from my company at a professional conference. I asked him, "So what cool stuff have you learned so far?" (usually a good conversation starter). And his reply was, "I already know all of this stuff." I was a bit shocked by the reaction (but not really surprised by it). This particular developer was not interested in learning. He was there for other reasons.

Get Involved
If you're not already involved in the developer community, it's time to change that. Cruise over to Meetup.com and see what's going on in your area. I really regret that I discovered the developer community so late in my career. Yes, I've been involved for close to 5 years, but I think about what my career and experiences would be like if I had gotten involved 10 years earlier.

I've met a lot of really great people (I'm amazed at how many people I know these days (and I'm not a social person by nature)). I've learned about a lot of really interesting technologies. I don't often use these technologies, but it's good to know what's available -- I'm really big on using the right tool for the job, and we have to learn about those tools somehow. When a particular project comes up, I can think back to a demo I saw and say, "Hey, I think that Technology X would be really good for this. Let's look into it some more."

And I have had several times where that has helped me find a good solution for an application.

Encourage Other Developers to Get Involved
I also lament for the people who aren't involved in the developer community. There are a lot of user groups in my area, but there is a much, much larger number of developers in my area. A very small percentage take the time to get involved. And many developers are not interested. One time I was working in an office of about 40 developers, and there was a user group that met less than 1 mile from the office. At that group, I met a total of 2 developers from the office (and one of them was a contractor).

If you've had a good experience attending community events, share them with your co-workers. If you've managed to improve your career from your continuous learning, share that as well. I would love to see our entire industry as a group of constant learners who become an unstoppable force in improving the lives of our users, companies, and the world at large.

Happy Coding!

Tuesday, October 14, 2014

"dynamic" Type Inference with Lambda Expressions

I had a great time at the Silicon Valley Code Camp this weekend (more on that to come). I get a lot of good questions when I give presentations, and I don't always have the answers up front. This is because I have a bit of a slow thinking process. If the question is about something I've done before, then I've got a good answer for it. But if it's something I've never encountered, then I'm reluctant to give an answer. Just such a situation came up this weekend.

Lambda Expressions and Parameter Type Inference
In my presentation Learn to Love Lambdas, I talk about parameter type inference (and also in video: Anatomy of a Lambda Expression). If the compiler can figure out what the parameter types for the lambda expression are, then we don't have to put them in.

Here's an example where we hook up a lambda expression to an event handler:


When we hook up an event handler, the method *must* match the method signature, otherwise, we have invalid code. Since the compiler knows that there is only one valid method signature to hook up to this event handler, it knows the two parameter types are "object" and "GetPeopleCompletedEventArgs". And we can see that "repoArgs" is, in fact, of that particular type even though we don't specify it in our code.

This also happens quite a bit in LINQ. Here's an example of using the "Where" method to filter a collection of "Person" objects:


Again, we see that the parameter is a "Person" since that's the only method signature that we are allowed to use here.

What About "dynamic" Types?
So as I was showing how awesome parameter type inference is, I got a question:
Q: Does parameter type inference work with "dynamic" types?
And I'll admit that I froze up for a bit. It's something that I never thought about. So, I was honest and said that I'm not sure how it would work since I'd never tried it before. And I said that it would be a blog article some time this week (hey, here it is!).

And with a little more thought, the answer was really obvious:
A: Of course parameter type inference will work with "dynamic".
"dynamic" is a type; it just happens to be a type with some special compile-time and run-time behavior. But it is a type nonetheless. So it will work with parameter type inference just like other types. We're still matching method signatures; the only difference is that we use "dynamic" for a parameter type instead of "string" or something else.

Some Experimenting
So, I did some experimenting to see how the IDE behaves. I started with the code from the Learn to Love Lambdas session (which you can download) -- specifically, the button click event handler in the code-behind for MainWindow.xaml:


I started out a bit verbose (so that we could follow this through). The first line of the method is existing code that grabs the selected item out of a list box in the UI. This is a "Person" that has 4 properties: FirstName, LastName, StartDate, and Rating.

Next, I created a delegate of type "Action<dynamic>". Action is just a built in delegate type that takes zero or more parameters and returns void. So our "dynamicAction" delegate needs to be hooked up to a method that takes a "dynamic" as a parameter and returns "void".

And that's what we do with the lambda expression. I start out being explicit about the parameter type, using "dynamic d". And in the body of the method, we just say hello in a message box.

Finally, we check to make sure that there was a "selectedPerson", and if so, we execute the "dynamicAction" delegate with that person as the parameter.

Parameter Type Inference
But we're still being explicit with the parameter type. Let's strip out the type and rely on parameter type inference (we'll also remove the parentheses since we only have 1 parameter and remove the curly braces since we only have 1 statement):


This is equivalent to the code that we have above, and it runs exactly the same. If we hover the mouse over the parameter, we can see the type:


It is "dynamic" just like we expect. And if we use the parameter in the body of the method, the IDE treats it like a dynamic:


So, if we type "d." code completion doesn't give us any hints. That's because we can type in whatever we want when we use a "dynamic" type, and the method or property call will be resolved at run-time.

An Anonymous Type
To show that we can take advantage of the dynamic nature of this parameter, let's create an anonymous type and try to use it with this delegate:


This code creates an anonymous type that has 2 properties: FirstName and Age. When we call our "dynamicAction" delegate with this parameter, it works just fine. That's because our anonymous type does have a "FirstName" property (which is the only property that is being used in the body of the method).

Wrap Up
Since "dynamic" is just another type, parameter type inference in lambda expressions works just fine. It seems very obvious to me now. But it wasn't obvious when I was "on the spot". When I get questions, I never just make up an answer. Sometimes I will give an educated guess, but I will always qualify it as such. I'm much more comfortable taking a little extra time to get things right.

Happy Coding!

Monday, October 6, 2014

New Pluralsight Course: Abstract Art: Getting Things "Just Right"

I'm happy to announce that my latest Pluralsight course has just been published: Abstract Art: Getting Things "Just Right" (Pluralsight link).

I've been talking and writing about this topic for quite a while, so I was glad for the chance to put everything down in one place. I'm a big fan of the proper use of abstraction. When we use it correctly, it can make our applications easier to extend, maintain, and test.

And many of the techniques of abstraction took me a long time to grab on to when I was a young programmer. To save other developers from having to go through that struggle, I often talk about Interfaces, Design Patterns, and Dependency Injection.

And used properly, these things are really awesome. But we can also take things too far. If we have too much abstraction in our code, then things get pretty awful. Our code can become overly complex, confusing to navigate, and difficult to debug.

Our goal is to find the balance. Part of this is to look at ourselves and see what our natural tendencies are. Does your nature lean toward over-abstraction? Does your nature lean toward under-abstraction? Once we recognize this, we can use it to our advantage to avoid the danger areas.

And the course is full of practical advice. There is no one right answer -- no particular abstraction technique that applies to every situation. So, we'll look at several principles that we can apply to our code. If we keep these in mind, then we'll be headed in the right direction.

So, let's build on the experience of this girl:


And get things "Just Right".

Happy Coding!

Using the CallerMemberName Attribute for Better XAML Data Binding

I really like XAML (in case you haven't figured it out yet). The data binding mechanism is pretty awesome -- you can data bind to properties of other controls, data bind to properties of data objects in code, and even data bind to incompatible datatypes using a value converter. I often show this last feature by data binding a background color to a DateTime property -- this let's me have different colored backgrounds for records based on a decade.

But it's not magic. In order to for the data binding to work well with our C# objects, we need to implement the INotifyPropertyChanged interface. It's not a show-stopper, but it is a bit of a hassle. It turns out that we can use the CallerMemberName attribute (which we got in .NET 4.5) to make things a bit better.

Let's look at an example.

Standard INotifyPropertyChanged Implementation
For our example, we'll use a prior example that uses the BackgroundWorkerComponent with the MVVM design pattern. You can get the code sample here: CallerMemberName Attribute Sample.

This is a WPF application where the UI elements are data bound to properties in a view model. Here's what the application looks like when it's running:


The part that we'll be looking at is the progress bar that's right in the middle. The value of the progress bar is data bound to a property called "ProgressPercentage". But in order for the UI to get notified when we change the value in the code, we need to raise a property changed event. This is normally done by implementing the INotifyPropertyChanged interface on the view model.

Here's a typical implementation of INotifyPropertyChanged (this is in the "MainViewModel.cs" file):


Notice that we have a "PropertyChanged" event. This is an event that is specified by the interface. And generally, we also include a method that makes it really easy to raise this event. In this example, this is the "RaisePropertyChanged" method.

And we call this method in the setter of our properties. Here's the "ProgressPercentage" property:


So, if we follow the logic, when we set our property, it calls the "RaisePropertyChanged" method and passes in the name of the property as a string.

Then the "RaisePropertyChanged" method uses that parameter to pass the name of the property in the event args, and it raises the "PropertyChanged" event.

This alerts the UI that the "ProgressPercentage" property has been modified and that any UI elements that are data bound to this property should be updated.

Default Parameter
There's one other thing to notice about our "RaisePropertyChanged" method: it has a default value for the parameter:


This means that if do not pass in any value, the "propertyName" parameter will be null. If we pass "null" on to the PropertyChanged event, then it alerts to UI to update *all* data bound elements.

This is a great way to refresh an entire screen. But it is also very inefficient. If we send update alerts for values that haven't changed, then we're just wasting computation cycles. So we generally want to target our updates as much as possible.

The Problem of String Parameters
There is a bit of a problem with having a string parameter in this case. What happens if we type the name of the property wrong when we call "RaisePropertyChanged"? Nothing happens. Our UI doesn't update as we expect. And we don't get any compile-time checking on this because it's just a string.

We need to think about refactoring as well. What happens if we rename the property? Refactoring tools are good about renaming any references to the property we renamed, but they aren't always good about updating strings that might match the value. (And when the refactoring tools do offer this option, they don't often have it selected by default.)

It's easy enough to create a helper method that allows us to pass in something other than a string. The Prism framework includes an implementation that let's you pass in a lambda expression. This has the advantage of being compiled (so no worries about typos), and it also will get updated automatically by refactoring tools if we rename it.

So that introduces us to the situation. What can we do to improve it?

Using the CallerMemberName Attribute
In .NET 4.5, we got a new attribute: "CallerMemberName". When we use this attribute with a parameter, it will automatically fill in the name of whoever made the method call. The best way to understand this is to add it to our example.

In order to use this attribute, we first need to add a using statement to System.Runtime.CompilerServices:

Here's our updated "RaisePropertyChanged" method:


The only difference is that we added "[CallerMemberName]" before our parameter. Now, if we do not include an explicit parameter, the name of the caller will be used as the default value.

Let's update our "ProgressPercentage" property to remove the string parameter:


Now we no longer have to worry about the "ProgressPercentage" string in our code. If we run our application, we will see that it behaves exactly the same way that it did before.

And to show that we are getting the value that we want, we can set a breakpoint an look at the value that is coming in to the "RaisePropertyChanged" method:


This shows that even though we don't have any parameter in our source code, a value still gets inserted for us.

Updating All Properties
As mentioned above, we can pass in a "null" to notify the UI that all of the properties have been updated. But we can't just rely on the default parameter value anymore. If we leave out the parameter, it will default to the CallerMemberName.

But we can still explicitly pass in a null:


This gives us the results we expect:


So we can still update all of the properties if we need to.

Are There Performance Concerns?
When looking at this code, it looks like it's using reflection in order to figure out the value for the parameter. Reflection is slooooow, so this should be a concern. But we don't need to be concerned about this. One hint is that the namespace is "System.Runtime.CompilerServices".

The magic of "CallerMemberName" happens at compile-time. So, the resulting code is no different than if we had included the string explicitly in our code.

Don't believe me? Let's look at the IL that is generated:


This shows that the "RaisePropertyChanged" method is still being called with a static string parameter ("ProgressPercentage"). This means that our compiled code is just as efficient as if we had included the string in our source code.

One Requirement
There is one requirement when we use the "CallerMemberName" attribute with a method parameter: the parameter must have a default value. In our case, we have a default of "null" specified, but the default can be any valid value. The reason for this requirement is that the compiler sticks in the parameter value from the attribute in a similar way to how default parameter values are handled. So this will only work if there is a default for the parameter.

Wrap Up
We can use the "CallerMemberName" attribute to make our implementation of INotifyPropertyChanged much better. Instead of passing in hard-coded strings, we let the compiler fill in the value for us.

This eliminates the problem of having typos in the parameter or having incorrect values after renaming a property. This is especially frustrating with XAML data binding because we would not get any errors telling us what is wrong -- the binding simply would not work the way that we expect it to.

I like to eliminate these types of problems wherever possible. It turns out that the "CallerMemberName" attribute can help us with this.

Happy Coding!