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

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

July 2007 - Posts

  • Is there a future for Fit testing?

    I use Fit testing and I'm even building a tool for easier test creation and management of Fit tests.  I've used it to drive web UI's, WinForms UI's, logic in domain model classes, web services, and even a polling windows service.  Some things have gone well and others haven't.  My dilemma today is this.  I have some logic that needs some automated acceptance tests.  It's a little doubtful to me that anybody but me will ever look at these tests.  I'm strongly considering just writing integration tests in NUnit instead of Fit. 

    Long term, all the testing gurus I know of seem to be driving towards scripting tests in Ruby and I'm thinking of moving in that direction in the future.  I'll still use Fit tests for set-based logic where it excels, but otherwise it just seems, I don't know, clunky.

    What do you guys think?  Does Fit have a future, or is it just a little blip that's never really going to take off?

     

    I'm not ready to throw in the towel on executable requirements by any means, just considering a change in mechanism for expressing the tests.

  • My Menu State Management Article from Build a CAB is now online

    The entire content is now online as a page on my site at:

    Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface

     

    Community Server really, really didn't like this post and just wouldn't let me post the content as a normal blog post.  I hope that isn't indicative of the quality of the content, but you never know.  And yes, with all the trouble we're having since the upgrade, I think CodeBetter is at least flirting with the idea of a different blog engine... 

    .

     

     

  • The Build Your Own CAB Series Table of Contents

    Yes, this is overdue.  Here is an introduction and table of contents to my "Build Your Own CAB" series of blog posts on designing WinForms applications.  You'll see nothing here about user experience and not much WinForms technology.  That stuff is covered quite well in a hundred different places.  This series is about code.  How to write it, how to write less, how to test it, and how to structure it.  And there is code in user interfaces, no doubt about that.  Code that's complex.  Code that changes every time you're foolish enough to ask an end user how they like it.  Code that's hard to test if you're not careful.

    I'm still working on the series, so check back here occasionally for updates and new downloads.  After I finish posting the menu state series I'm going to take a break for a while, but it's for a good cause.  The most persistent complaint throughout the series is that it's not clear how all the pieces fit together.  Understandable.  At the same time that I'm writing this series I'm also working on my OSS StoryTeller tool that includes a sizable WinForms client.  Last week I scrapped about half of the StoryTeller UI code so I could go back and incorporate the ideas that I've explored through "Build a CAB."  I can say without a doubt that I'm the one person who's learned the most from "Build a CAB."  What I'm hoping to do is use the StoryTeller UI code to demonstrate fully working screens from end to end.  The beauty of using OSS code for examples is that the code is automatically available for download.

    I'll finish before the end of the summer, I promise.  Just set a bookmark to this page and I'll keep updating it as the series expands.  At the end I've committed to gathering all this stuff up into a single, printable PDF for download.
     

     

    Downloads

    Soon...

     

    Table of Contents

    There's an extended introduction below.

    1. How I got into this mess - Look for the section "Microsoft, OSS, and the Patterns and Practices Team"
    2. Preamble
    3. The Humble Dialog Box
    4. Supervising Controller
    5. Passive View
    6. Presentation Model
    7. View to Presenter Communication
    8. Answering some questions
    9. What's the Model?
    10. Assigning Responsibilities in a Model View Presenter Architecture
    11. Domain Centric Validation with the Notification Pattern
    12. Unit Testing the UI with NUnitForms
    13. Event Aggregator
      1. Event Aggregator with Generics
    14. Rein in runaway events with the "Latch"
    15. Embedded Controllers with a Dash of DSL
    16. Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface
      1. MicroControllers
      2. Boil down the "wiring" to a Registry
      3. The Command Executor
      4. The Main Players
      5. Testing through the UI - Forthcoming
      6. Subcutaneous Testing - Forthcoming
      7. Creating the Application Shell - probably a couple posts
      8. Wiring the Components with an IoC tool - Forthcoming, but I may push this off into late summer
      9. A Day in the Life of a Screen - by popular demand (gripe), let's look at a couple of complete screens through their entire lifecycle

       

      Introduction

      In building enterprise software systems I've often observed a feeling that building the actual User Interface is less demanding or important in terms of design compared to the backend.  We worry quite a bit about the appearance and the usability of the User Interface, but how about the code structure of the UI itself?  In my experience, UI behavior changes more often than anything else and generates a much higher defect rate.  Several years ago I briefly used Use Case Points as an estimation technique.  One of the features of this technique that caught my eye at the time was how it treated user interface features.  Any feature that included an interactive user interface was automatically given a higher modifier of effort than the same size feature that only dealt with other computers.  In that technique it was a given that interfacing with a human was more complex than interfacing with other code.  My point being here that user interface development is complex and we need to take it seriously.

      A couple years ago heavy clients were out of style due to well-founded concerns over deployment and support issues.  Lately, or at least for me anyway, heavy clients seem to have made a comeback as the newer .Net technologies have alleviated the deployment concerns somewhat.  Instead of dying away, we're building more complex WinForms user interfaces than ever before.  There's a lot of talk about building "composite" applications that can quickly host multiple, logical applications or applets in the same application shell.  We're trying to build applications that can be easily extended without ripping up the existing code.  We're sold on Test Driven Development, but the user interface has remained one of the last uncharted territories for automated testing.  The traditional approach towards building user interfaces in the Microsoft is to fire up the designer and pump energy and effort into it until it works.  That has to change.

      At DevTeach 2007 I gave a talk called "Put Down that Wizard!" with a subtitle "Design Patterns for Maintainable WinForms."  By and large, the talk was about how to code and design a WinForms application.  I discussed design patterns for assigning screen responsibilities, screen synchronization, and issues that effect testability of user interface code.  I was fairly happy with the way the talk went and the feedback overall, but a particular comment from an attendee caught my eye:  "the content was obscure."  The criticism itself wasn't bothersome in and of itself, but the fact that these patterns were considered "obscure" definitely bothered me.  Designing software is largely an exercise in determining the responsibilities of the code and assigning these same responsibilities to different modules of the code.  How you assign, or fail to assign, responsibilities has a great impact on the maintainability of a codebase.  Patterns like Model View Presenter are a reoccurring recipe for assigning responsibilities in a user interface.  These patterns weren't created or invented, they were discovered by practitioners who began to describe the structures that worked (or didn't work).  If we're going to build and evolve more complex user interfaces, we can't blow off the internal structure of the user interface code.

       

       

      What's this series about anyway?

      At DevTeach 2007 I was part of a panel on the tenuous relationship between Microsoft and the Open Source community.  At some point in the panel discussion and the resulting blog discussions afterward, we set off an argument about whether or not the Composite Application Block (CAB) framework was necessary or even valuable for building larger, maintainable WinForms applications.  My point of view then, and now, is that understanding the core concepts and patterns is the first step.  I don't think you can use the CAB effectively unless you understand the underlying patterns.  On the other hand, if you understand the underlying patterns and design forces, you can quite efficiently and effectively do your own thing.  Either way, you want a strong core of design principles. 

      User interface technologies change.  I'm sure it'll take a while, but WPF screens will eventually eclipse WinForms and who knows what's over the horizon.  The specific knowledge that you carry around about WinForms widgets will be obsolete soon.  I think the Microsoft community stresses API knowledge too much and core design principles too little.  When I switched jobs last fall I knew I was going to need a better foundation on WinForms, so I bought and read one of the more popular books on WinForms by a Microsoft luminary (and I say this without any irony).  I read the book and it presented the technology behind WinForms very effectively.  The wizards and designer support was well covered, but the book didn't address the issues of maintainability and testability in WinForms development.  There wasn't a single mention of any kind of View/Controller separation in the entire book.  That's a huge gap in knowledge, and one I hoped to help fill by writing this series. 

      The way it's unfolded, this series isn't really about replacing the CAB with your own Model View Presenter pattern.  It's just the things you can do to make a maintainable WinForms architecture -- with or without the CAB.  A large chunk of maintainability for me is creating code that's easy to test with granular unit tests, and you'll see this desire for testability permeating the entire series.  Despite rumors to the contrary, it is possible to Test Drive WinForms development, but you testability has to be a first class design goal.

      One of the other points I wanted to get across in my DevTeach talk was that oftentimes a code-centric approach can accomplish user interface tasks faster and with less duplication than using the designer.  I'm just now starting to explore some of these code-centric solutions through the later posts involving Fluent Interfaces.  The designer is great for laying out the look and feel, but we can't allow the designer to be our architect.  I don't think WinForms is a bad technology at all, but it's deeply flawed in the sense that it does not lead you into a maintainable structure.  The designer makes it relatively easy to crank out user interface code, and that's what it's doing behind the scenes, but some judicious code-centric design can eliminate duplication and reduce the overall effort.  Maintainability is your job, not the designer's.

       

      So hotshot, you think you can build a better CAB?

      No, I don't, that's not my point.  My point was just that if you were well armed with an understanding of the underlying design patterns and motivation that you could happily evolve your own application specific framework that would better fit your application.  Part of that belief is that building a framework is much simpler in this day and age of Dependency Injection tools.  Today, you can pull one of a couple different Inversion of Control / Dependency Injection tools off of the shelf that are all more powerful than the limited ObjectBuilder inside the CAB.  Then again, I'm the progenitor of one of those tools, so my opinion might be somewhat suspect.

      And yes, to be honest, like many developers there's an inner demon inside of me that arrogantly believes he can build a better [insert name of framework] and is just dying to prove it. Begone inner demon, begone!

    17. Announcing the ALT.NET Open Spaces Event

      I've been excited for this for quite awhile, and now we can finally talk about it.  Scott Bellware made the first official announcement last night.  In early October, there is going to be a three day event hosted in Austin, Texas.  The theme of the conference is the ALT.NET idea and theme identified by David Laribee this spring.  As Scott mentioned in his post, I'm one of the members of the organizing committee, so feel free to send any questions or suggestions to me via the contact page.

      Every so often in blogging discussions I read a line of BS that goes something like "I just use what's best for my project."  Ah, that's nice.  Cheap, useless advice, but nice. So back to where we started, what is best for your project?  Is it the standard MSDN proscribed solution, or is it something else?  What are the "something else" possibilities?  What's coming over the horizon in terms of techniques or technologies that could make development more successful?  What are other development communities doing?  Where can I find out more about these "something else" approaches and tools?  Finding answers to those questions, and the very rare opportunity to interact with fellow developers interested in these very same questions, is exactly the purpose of this conference.

      You don't like the ALT.NET moniker?  Think we're arrogant?  Bunch of twaddle?  Fine, show up and add your voice too.

      The best part of a conference for me is usually the people you meet and the discussions you have in the hallway between talks.  On the other hand, I'd say that one of the best ways to learn something is to be tagged to present on that topic.  So wouldn't it be nice to have a conference that gives you more chances to interact with other developers and the speakers, and while we're at it, give you the chance to give a talk as well?  If that sounds good to you, you're in luck, because the event is going to follow the Open Spaces format.  If you're going to come, start thinking now about what you want to talk about, and come prepared.  It's an awesome chance to do it in a collegial environment.

      I'm pretty excited for the chance to get back to Austin.  I'm threatening some of the New York attendees with a heartburn-inducing tour of my favorite Tex-Mex places.  I'm already scanning the calendars for the Saxon Pub and the Continental Club.

       

    18. Build your own CAB #14: Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface

      THIS ARTICLE IN ITS ENTIRETY IS HERE.

      The title is a mouthful and accurately implies an alarmingly high jargon to code ration, but I just didn't see anyway to write this post without straying into all of these different subjects.  When you try to write an explanatory article you have to walk a tightrope between a sample problem that's simple enough to work through in no more than a handful of pages and a sample problem that's just too simplistic to be valuable.  I'll leave it up to you to decide which end of the spectrum this one falls on.  I also had a rough time trying to decide on the best way to order the topics in the narrative.  All I can do is ask you to scan the following headers if something seems to be missing or I'm lurching ahead.

      Last week I had a flood of people follow Martin Fowler's link into this series.  I thought it was pretty cool because most of my UI patterns material and terminology is transparently based on Fowler's work.  I'm especially glad that Martin didn't mention the fact that I volunteered to help with the UI patterns writing three years ago then disappeared...

      If you missed something, here's the Build your own CAB series in its entirety. 

      1. Preamble
      2. The Humble Dialog Box
      3. Supervising Controller
      4. Passive View
      5. Presentation Model
      6. View to Presenter Communication
      7. Answering some questions
      8. What's the Model?
      9. Assigning Responsibilities in a Model View Presenter Architecture
      10. Domain Centric Validation with the Notification Pattern
      11. Unit Testing the UI with NUnitForms
      12. Event Aggregator
      13. Rein in runaway events with the "Latch"
      14. Embedded Controllers with a Dash of DSL
      15. Managing Menu State with MicroController's, Command's, a Layer SuperType, some StructureMap Pixie Dust, and a Dollop of Fluent Interface (This Post)
      16. Replacing Data Binding with MicroControllers and the Window Driver Pattern - Forthcoming
      17. Subcutaneous Testing - Forthcoming
      18. Creating the Application Shell - probably a couple posts
      19. Wiring the Components with an IoC tool - Forthcoming, but I may push this off into late summer
      20. A Day in the Life of a Screen

      The end is in sight.  In traditional developer style I blew the estimate for how long "Build your own CAB" would take.  I thought all I needed to do was copy n'paste a bunch of verbiage and code from my DevTeach talks into Live Writer and that would be that - but my usual wordiness kicked in and I ended up submitting a completely new talk to DevTeach Vancouver on this subject. 

      A couple years ago I remember reading Stephen King say that he always found the Dark Tower books difficult to write as a way of explaining why there was so much lag between new books, much to my exasperation at the time.  I'm obviously not Stephen King, and there's no line of folks wrapped around the corner of CodeBetter waiting for the next installment, but I know how Stephen King felt now.  I do promise that the end of this series won't be as shocking/disappointing/brilliant(?) as the end of the Dark Tower.*

       

      Problem Statement

      Again, I am not a licensed namer of patterns, and some of the people I've shown this code to have commented that it's reminiscent of Smalltalk UI's, so it's a good bet that some of you have already seen or used similar approaches.  That said, I use the term "MicroController" to refer to a controller class that directs the behavior of a single UI widget.  By itself, a MicroController isn't really that powerful, but like an army of ants, a group of MicroController's working cooperatively (with some external direction) can accomplish powerful feats. 

      Here's a common scenario: 

      1. You have a menu bar of some sort or another in the top strip of your composite WinForms application
      2. Each individual menu item needs to fire off a command of some sort (duh)
      3. The availability of some, but not all, menu items is dependent on user roles.  In other words, some menu items will be disabled or hidden if a user does not have a necessary role.
      4. The availability of some menu items is dependent upon the screen that is currently active in an application with some sort of MDI or tabbed interface
      5. The menu bar frequently collects new additions as the application grows

      There's nothing in that list that's particularly hard or even unusual, but I want to explore an alternative approach.  Off the top of my head, I've got four goals in mind for the design of my menu state management:

      1. Quickly attach the proper commands and actions to each MenuItem.  This can get tricky because each MenuItem potentially touches and interacts with very different pieces of the application. 
      2. Eliminate duplicate grunge coding.  I say you pursue any chance to eliminate the mechanical cost, and there's quite a bit of repetitive functionality here.
      3. Make the code that specifies the menu behavior as expressive and readable as possible.  This code is going to frequently change, so it's worth our while to make this code readable. 
      4. I want an easy way for each screen to configure the menu state, and I want this menu state calculation and manipulation to be as easy to understand, write, and test as possible.   

      Much like the screen state machine sample from my last post, I'm going to try to use a Domain Specific Language (DSL) / Fluent Interface to express and define the menu behavior.  By hiding the mechanics of menu management behind an abstracted Fluent Interface I'm hoping to compress the code that governs the menu state to a smaller area of the code.  I want to be able to understand the menu behavior by scanning a cohesive area of the code.  It's my firm contention that this type of readability simply cannot be accomplished by using the designer to attach bits and pieces of behavior.  Leaning on the designer will scatter the behavior of the screen all over the place.  One of the main reasons I don't like to use the designer or wizards is because you often can't "see" the code and the way it works.

      Start with the End in Mind

      Before zooming in one the individual components of the solution, let's keep the man firmly behind the curtain and look at my intended end state.  Inside some screen (probably the main Form) is a piece of code that expresses the behavior of the menu items like this fragment below:

      
      
              private void configureMenus()
              {
                  _menuController.MenuItem(openItem).Executes(CommandNames.Open).IsAlwaysEnabled();
       
                  _menuController.MenuItem(saveItem).Executes(CommandNames.Save)
                      .IsAvailableToRoles("BigBoss", "WorkerBee");
       
                  _menuController.MenuItem(executeItem).Executes(CommandNames.Execute)
                      .IsAvailableToRoles("BigBoss");
       
                  _menuController.MenuItem(exportItem).Executes(CommandNames.Export);
              }

      And in each individual screen presenter you might see some additional code to set screen-specific menu settings like this that would be called upon activating a different screen:

       

          public class SomeScreenPresenter : IPresenter
          {
              public void ConfigureMenu(MenuState state)
              {
                  state.Enable(CommandNames.Save, CommandNames.Export);
                  state.Enable(CommandNames.Execute).ForRoles("SpecialWorkerBee", "BigBoss");
              }
          }

      So what's going on here?  There isn't a single call in this code to MenuItem.Enabled or any definition of MenuItem.Click, so it's safe to assume that there's somebody behind the curtain.  So, what is the man behind the curtain?  Before I talk about each piece in detail, here's a rundown of the various moving parts:

      1. A small MicroController object for each MenuItem that "knows" when to enable or disable its MenuItem and set up the MenuItem's Click event.
      2. A controller class for the menu that aggregates all of the MenuItem controllers.  Part of the responsibility of the Fluent Interface configuration code above is to associate a MenuItem with a CommandNames key so we can quickly reference the correct MenuItem's when a different screen is activated.
      3. A series of Command pattern classes that all implement a common interface. 
      4. StructureMap is lurking in the background as my IoC tool of choice to wire the various parts together.
      5. The Fluent Interface configuration API.  For the most part, it's job is to look pretty.  All it's doing is gathering in input values to set on the individual MenuItem controller classes that do the real work.  What I've found so far is that Fluent Interface strategies seem to lend themselves best to situations like this where you're really just configuring an object graph to do the real work.
      6. A MenuState object that is used to transmit the desired state of the menu from the individual screens to the main menu controller
      7. Each Presenter in the application implements a common interface that includes some sort of hook to configure the items on the main Menu.
      8. The whole application is stitched together with the combination of an ApplicationController and ApplicationShell.  I'm going to be very brief on these two because I'm going to devote a couple posts later down the line to these classes.

       

      NEXT, LET'S LOOK AT THE PRESENTER PIECE...           ...it's all written, but Community Server wouldn't let me post it all at one time for some reason.

       

       

       

      * Come on, I'm not the only person that screamed and threw the book across the room when Roland ends up back at the very beginning.  I'm going to swear off fantasy books permanently if Rand doesn't win a clear cut victory in book 12 whenever that comes out.  Almost 20 years worth of waiting better come with a really solid ending.

    19. You're a TDD newbie on a project team with Jeremy, what do you do?

      I was cranky the day I wrote this, can you tell?

      • DO take TDD seriously or Jeremy will ride you mercilessly persistently remind you to do so. 
      • If you think writing unit tests is hard with the project's current approach, DO talk with Jeremy about changing the approach, or just DO IT and show Jeremy the better way later.  If it's hard to test, it's probably bad.
      • DO make suggestions.
      • DO write unit tests first for everything reasonable -- and it's reasonable almost everywhere.
      • PLEASE DO make a good faith effort to learn how to write testable code.  It's a significant adjustment.  TDD is all that and the proverbial bag of chips, but it does come for free on day 1.
      • If you don't know how to write a unit test for a task, DO ask Jeremy for help!  It's Jeremy's job to help you.  You're not gonna look bad for asking for help, you're simply making Jeremy earn his salary.
      • If nothing else DO write unit tests after you make the code work, just don't whine to Jeremy when you find out that it's harder to retrofit tests than it is to go test first because he will just act smug and say "I told you so."
      • DO NOT commit code without any tests.  DO NOT get caught dead with multiple defects in code with no unit tests.  Something always leaks through no matter how good your unit tests are, but let's at least make the testing net pretty fine. 
      • If nothing else, DO NOT say you're done with a coding task until you've verified that the code does what it's supposed to do.  I'd rather you did TDD effortlessly, but manual testing after coding beats nothing.
      • If you break the build, just FIX IT.  Jeremy doesn't do the Shame Card or Smelly Shirt crap, but likes that soothing, little green ball in the system tray for a clean build.
      • DO learn how RhinoMocks works or DO NOT use it.  Seriously.  It's a very powerful tool when used correctly, but it punishes folks with a shallow understanding of the tool.  Understand what it does, don't memorize, and don't try to copy/paste RhinoMocks code you don't understand
      • If you don't grok mock objects, DO ask Jeremy for alternatives.  There are other ways to do TDD.  A lot of people seem to be allergic to dynamic mock objects, so don't ever think you're the only person in the world who struggles with it.
      • If writing Assert.AssertSomething seems really repetitive, think or talk about a way to make the tests more declarative.

      And please, please, please don't just stare at the screen if you don't know what to do next.  It's okay to spike something, just come back and do it TDD as soon as you know what to do.
    20. Answering Questions

      I'm awful at returning emails.  It was even one of my new year's resolutions to reply to emails faster.  The last couple weeks I've had a very hard time answering correspondence and I need to catch up.  I'm publishing my answers here because some of them are common questions, and others are things that I just flat out don't have a good answer for.  Feel free to chime in below with better answers than mine.

       

      Won't Constructor Injection cause a ripple effect? 

      I had a question on whether or not using Constructor Injection would create an undesirable ripple effect, and whether or not that problem could be solved or alleviated by using a Dependency Injection tool.  I'm very much biased towards Constructor Injection over using setters for reasons I'll detail a bit later in the post.  However, using Constructor Injection can easily lead to cases like the class structure below:

      class A {
      public A(B b) {}
      }

      class B {
      public B(C c, D d) {}
      }

      public C {
      public C(E e) {}
      }

      public D {
      public D() {}
      }

      Class A needs class B, which needs C & D, which in turn also brings in E.  That's a lot of stuff to bring in and set up.  You can go three ways:

      1. Do all of the constructor argument setup manually (bad idea)
      2. Use default constructors with no arguments that set themselves up and then open up alternative "greedy" constructors for use in testing (not a bad compromise and a common technique)
      3. Use a Dependency Injection tool like StructureMap to "auto wire" the dependencies together.  Assuming that you've specified the default concrete type (and constructor args) for each IService/Service pair, StructureMap can quite happily set up all of the constructor arguments and dependencies to an n-deep level.  In other words, If you ask for an "A" above, StructureMap will work recursively to create an E to inject into C which gets injected into a B which gets injected into the A that you wanted in the first place.  StructureMap (and other tools) look for the "greediest" constructor function to automatically determine what dependencies a concrete class needs.

      Part of the reason to use a Dependency Injection tool like StructureMap is to reduce the mechanical cost of composition and loose coupling.

       

      What if I don't need it right away?

      Part of the question was about the efficiency of this approach, especially if a dependency deep inside the hierarchy isn't needed right away, or possible never.  In that case I might opt for using Service Location instead.  That's what Bellware was calling a "[EDIT]transitive dependency" a little while back.  In my code that would manifest itself as a call to StructureMap like this:  D d = ObjectFactory.GetInstance<D>(); somewhere inside a method in class B above.  Inside of unit tests I can still mock D by using: 

      [Test]
      public void SomeTest(){
      MockRepository mocks = new MockRepository();
      D mockedD = mocks.CreateMock();
      ObjectFactory.InjectStub(mockedD); // InjectStub isn't the best name. In 2.1 it's gonna be renamed "Inject"
      }

      Any class that asks for an instance of D is going to get the "mockedD" instance.

       

      What about dependencies on File, Path, and Directory?

      Another question is how to deal with static classes like File or Path in unit tests?  Is it okay to wrap my own interface around these classes for testing because this feels strange.  I know exactly where this question is coming from.  Like Jeffrey, I happily wrap some sort of IFileSystem interface around these classes and test against mocks of these interfaces.  Does it feel weird?  I suppose, but being able to write unit tests is a good feeling.  Other points:

      • You could use TypeMock I suppose, but that also goes against the advice (that I would second) to only mock interfaces that you control.  IFileSystem up there isn't a one for one copy of the Path class.  It's specific to the application's needs.
      • This is exactly the kind of thing that turns some people off on TDD, or at least integration testing approaches.
      • To make TDD work, and I obviously believe that it does work, you've got to be thinking about testability as a matter of course.  Bolting on unit tests after the fact usually doesn't work all that well.

       

      Can StructureMap help with Pluggable Views in ASP.Net?

      Absolutely.  Check out Jeffrey's post on this very subject.  But, before you run off and do that, you might go check out some other solutions like Igloo or MonoRail and see if they've already addressed this issue.  To be honest, I've never done all that much ASP.Net coding, so I'm not a very good resource for ASP.Net questions.  However, that won't keep me from saying things like "the WebForms event lifecycle is the most gawdawful, overcomplicated piece of crap MS has ever rammed down our throats."

       

      Where does threading code go in a WinForms app?

      Threading code is some of the trickiest code to unit test.  Not impossible, just tricky.  Following Jeremy's First Law of TDD, threading gets it's very own set of classes and layer.  I would try to treat threading, even if it's just a wrapper around the BackgroundWorker, as a separate service in your application in its own right.  Just a rule of thumb, any code that touches into the System.Threading namespace should do nothing but threading manipulation.  I'd probably pass some sort of ICommand interface objects (1 for the real thing and a second for the callback) into the threading service.  All communication with the rest of the system should be through abstracted interfaces. 

      The Presenter's would be responsible for making the correct set of instructions to the threading code service then get out of the way.

    21. C# -- I don't care if it's Rubenesque as long as it's Rubyesque

      A week or so back David Ing raised a concern that the new language features in C# 3.0 are bloating the language.  Jim Downing adds to the conversation by asking if C# if Fit or Fat.  I certainly understand their concerns, but for me, waiting for the new C# 3.0 features is like being a 5-year old on Christmas Eve knowing that the package in the corner is a Milleneum Falcon toy.  I think Linq is overhyped, but the stuff they supposedly did just to support Linq is going to rock.  The movement in regards to programming languages that I'm seeing is to pack more punch with less code weight, and I think the C# 3.0 stuff is going to help the mainstream move in that direction.

      1. Filter/Map/Reduce type functional programming constructs.  I've never even gotten to use a language in anger that has these features (except JavaScript with Prototype), but I find myself wishing for them quite frequently.
      2. Lambda expressions.  I'm using anonymous delegates quite frequently now, but the syntax is fugly.  I've spoken with developers who won't use them because they feel, with some justification, that the resulting code is just too unreadable.  Lambda expressions are going to make the code noise go down.
      3. Type inference.  Again, this is going to reduce code noise - and without sacrificing static typed checks from the compiler.  I love what Generics do, but the resulting code is also fugly.  One of the advantages of a Ruby or Python over C# is the extra "noise" code in C# compared to duck typed languages.  Type inference helps alleviate that issue in C#, especially with Generic type declarations.
      4. Extension methods.  Bring it on!  I've been wanting them badly on my current project.  I think the Fluent Language stuff we've been talking about the last couple weeks will be much easier to extend with extension methods.  I thought of an extension method I want to add to RhinoMocks today for StructureMap integration in testing.

      Yeah, it's more things to know, and somebody is going to write truly atrocious code with the new features, but I'd rather have the sharpest tools possible and I'll be responsible for not cutting my fingers off. 

       

      What do you think?  Exciting new stuff or unnecessary cruft.

    22. Where do Presenter's come from, and upcoming stuff

      I had a good question on my Build a CAB series today.  "Where does the Presenter get instantiated?" 

      1. It depends. 
      2. For me, it's always StructureMap instantiating a Presenter instance and filling it with its dependencies including the View.  Occasionally I'll pass the View in via some sort of Start(IView) method.  Now, who calls StructureMap?  That's a longer question that I'm going to try to address in the last couple chapters of Build a CAB.   

      I don't actually have true end-to-end code samples for Build a CAB unfortunately.  I'll try to address that in the ApplicationShell topic.

      I've been slow on posting the last week or so mostly out of writer's block.  I've got a bunch of drafts but nothing remotely finished.  In no particular order, I'm working on:

      • A Gentle Introduction to StructureMap and Dependency Injection (request from Chad Myers.  I didn't forget, I'm just slow)
      • 2 posts on MicroController for "Build a CAB", including one on my crackpot data binding replacement scheme
      • Lessons Learned for Building a Fluent Interface in C# (another request)
      • An essay on the importance of feedback
      • Fit testing tips and tricks
      • I've been wanting to do a post on the Visitor and Composite patterns forever

       

    23. A Train of Thought - July 10th 2007 Edition

      Just for fun, I'm going to try to keep each section under 3-4 sentences, and finish in under an hour.

       

      That's bookkeeping, not project management

      JIRA, Microsoft Project, VSTS, whatever.  Fiddling with a project management tool is not project management.  Project management is communication, analysis, risk management, and getting me the stuff I need to keep coding!  Don't tell me project milestones or tasks in a tool.  Let's determine milestones and iteration plans collaboratively in an iteration kickoff.  More interaction and communication and less bookkeeping.

       

      How do you not know?

      I listened to the DotNetRocks episode featuring the VSTS panel at TechEd the other day.  Part of that conversation bothered me a little bit.  The panel addressed a question about using the metrics generated by VSTS on developer checkin's to make quantitative judgements about the relative productivity of the developers on a team.  I thought the panelists were fairly good about saying that the metrics should merely inform the judgement of productivity and named a couple reasons why the metrics (code checkin's, code churn, whatever else) could be skewed to give you a false impression (and I can think of a couple dozen more, not the least of which would be pair programming).  That's fine, but my immediate response was how the *&^%%$ do you not know exactly who your most and least productive developers are?  Even without statistics and software engineering, how the heck are you not intimately aware of your team and each of your teammates?  I don't buy the big team/big project argument because those projects are just divided into a team of teams.  What gives?

       

      Stay on Target!

      My colleague got a little object lesson today in priorities.  At almost all times, you need to stay focused on the highest priority feature.  Any effort you spend on unnecessary frills or low priority features is time and energy that isn't spent on higher priority tasks.  It sucks some of the fun out of development, but the guy paying the bill needs to be kept happy.  You've only got so many units of developer time to play on the project.  Use them wisely.

       

      The Last Responsible Moment

      In a related topic, last week I did a review of our system to the developer who'll likely be in charge of the system after I bow out.  I showed him our scheme for plugging in new types of trades into our WinForms app.  Right now it uses a C# fluent interface that's nothing but a thin layer over the StructureMap configuration API.  He challenged me on why there wasn't an option to plug in new features by simply deploying an extra assembly and making an Xml configuration change.  My response was that there wasn't a requirement for that.  It does sound like something that might be useful in the future, but any time spent on that feature today takes time away from the things that are necessary now.  In terms of the Last Responsible Moment, however, we've left the door wide open for making that feature possible in the future.  By no means have we eliminated the possibility of pure xml extension.  Things just don't have to be perfectly future proof when you've got reversibility.  Code and design in a way that leaves the door open for extension and modification later and you won't have to kill yourself getting it perfect upfront.

       

      YAGNI for Enterprise Architects

      I came to a realization today on one of those strategic versus tactical decision points.  We decided early on to persist data in the industry and client standard Xml format.  The horrendously convoluted not meant for human consumption Xml format.  Why did we do this?  Well, because in the future it should make it easier to communicate with external systems and it's the standard by golly!  I thought it sounded like a good idea, with a minor caveat.  In the end though, that decision has caused us a significant amount of extra work with zero payoff.  With an Xml format that complex you can't say that you're ready to integrate with another system until you've tested the Xml payloads anyway.  If we'd gone with the alternative of just serializing the Trade objects to a simple Xml format, we would have save a lot of time while still delivering the immediate business functionality.  I think we should have YAGNI'd that decision.  The Xml will almost certainly need to be tweaked later for the downstream systems anyway, so all we bought ourselves was an extra headache.  And compliance with corporate guidelines.

       

      Dogfood It

      Process, design, or framework.  It just shouldn't be trusted at all unless the creators dogfood it.  You need to feel the pain of your decisions.

       

      If/Then Klooge is my Coding Horror

      Jeff "Coding Horror" Atwood recently wrote a post criticizing the usage of design patterns as unnecessary complexity.  While patterns can definitely add unnecessary complexity when used inappropriately (just about any use of the Singleton anybody?), I'm going to disagree with Jeff.  If you take a close look at most of the original "Gang of Four" Design Patterns, you'll see that many of the patterns are aimed squarely at:

      • Reducing the amount of branching constructs in the code.  Switch statements and deeply nested if/then statements are to logic bugs as stagnant water is to the mosquito population
      • Eliminating duplication 
      • Decreased coupling
      • Separate concerns

      All of those bullet points seem like good things to me.  Maybe you just simply ask yourself if a pattern helps you before you use it.  I know many people have a near knee-jerk reaction to design patterns, but if you ever work for me I'll verbally abuse you for deeply nested code and repetitive branching logic.  I've started to walk up and down the row of cubes just muttering "Control-Alt-M."

      There's a strain of Extreme Programming practitioners that seems to believe that "simple" means using nothing more sophisticated than throwing if/then statements against the wall until unit tests pass.  Then, once it's so obvious that a casual observer is appalled by the state of the code do they start some refactoring work.  Don't be like that.

      My latest hypothesis for the development skills shortage

      I think most of you will agree with me that there just isn't enough developer talent out there right now, and I've got a little theory about why this is.  I just interviewed a trio of candidates with about 10 years of experience on average.  A couple of them might be okay with some coaching, but on the whole all three seemed rather weak

       

      Fast way to blow an interview with me

      I knew within 5 minutes that I was rejecting a candidate, but I try to give everybody a chance.  This particular candidate had bombed some basic .Net trivia before proceeding to crash and burn on my design related questions.  I'm always worried that the questions I ask might not bring out the particular strengths of a candidate, so I try to give people an opened ended chance to tell me what they bring to the table.  This clown gave me a spiel about how he did poorly on the interview questions because they were skewed towards a developer perspective and he was an architect.  All rightie then.

       

      2nd Fastest way to blow an interview with me

      I'm too lazy to change it, so I'm more or less stuck with an attacking Tie Fighter as my cellphone ring.  Last year I was interviewing with a little consulting firm in Austin when my phone rang.  One of the interviewer (about my age) had no idea what the sound was.  I just couldn't imaging working in a development shop with people that can't quote Star Wars.  It's just plain wrong.  Like using an interface without prefacing the name with "I" wrong.

       

      3rd Fastest way to blow an interview with me

      The same interview from above included a pop quiz that included a question on basic CSS mechanics.  Um, google?  If you're actually asking me that, what the heck does this position actually pay?

       

      4th Fastest way to blow an interview with me

      So, Jeremy, our architect is concerned that you won't be happy just writing code and not doing any design.  How do you feel about that?  Um, bye?

       

      5th Fastest way to blow an interview with me

      From a single shop, in rapid order:

      1. Our architect builds the framework, we just use it
      2. Them:  We want to be database neutral, so we're using the ODBC provider.  Me:  That's a terrible idea!  You're not using stored procedures then are you?  Them (looking annoyed):  Of course we're using stored procedures for all data access.
      3. We're asking all employees to work 48 hours a week until we ship next spring -- and everybody in the room had the bleary-eyed look that coders get from too many hours and too much caffeine

       

      6th Fastest way to blow an interview with me

      Steve & I:  So, we'd really like to have a tester with strong test automation skills.  What is your experience in this area?

      Him:  I don't think test automation is very important

       

      7th Fastest way to blow an interview with me

      We have our own proprietary Agile process (why the hell do companies insist on trying this line of mularkey) that's based on RUP.  We have our Inception phase, then our Elaboration phase, then...

    24. Anders Norås on C# DSL's

      More C# DSL goodness from Anders:

      Behind the scenes of the planning DSL

    25. What I've already done to be a better developer

      After the last post, I thought it might be worth talking about the things that have already led to me becoming a better developer.

      1. Converse - That's it.  As often as possible, talk about developing software development with other developers.  Cultivate personal relationships.  Talk to people that disagree with you.  Talk to the more experienced guys.  Talk to folks with different experiences.  Go to user groups, especially the kind of user groups where the conversations are free flowing.  I've never been that big of a fan of the "Presentation o' the Month" meetings, but I've gotten a lot out of lunchtime and happy hour type groups with no set agenda.
      2. Environment - I've met several developers that I thought had all of the makings of greatness, but just hadn't had the opportunity to work in a good environment.  By a good environment I mean a place where you're surrounded by good developers who are willing and able to share their knowledge.  If you're a junior developer your career path can be greatly shortened by solid mentoring relationships.  If you're a solid developer you can only get better by being intellectually challenged and stimulated by your peers.  My first real development job was in a truly awful shop.  I had a few relationships that I treasured (the brotherhood of the smoked chicken enchiladas), but it was obviously a place with limited possibilities.  I made the personally risky move to an elite consultancy where I interacted every single day with great developers.  It wasn't a great move on the personal and family front, but it supercharged my career growth.
      3. Do an OSS Project - Your job is probably boring, and quite possibly not that interesting.  You're never on a project that gives you every possible kind of experience.  That's where participating in an OSS project becomes so beneficial.  I've used StructureMap for years as a personal laboratory, and looking through the code I can trace my personal development from VB guy to what I am now.  Preferably, pick something interesting that you'll enjoy.  Something that forces you to expand your skills or let's you try out new design ideas -- where they won't damage a real project.
      4. Write a blog - I've told my wife several times that writing The Shade Tree Developer is the single smartest thing I've ever done for my career.  A lot of the posts I've written have turned into book reports or research projects.  Writing blog posts, especially argumentative blog posts, is a fantastic way to organize the thoughts in your mind.  Nothing makes you think more than the simple act of expressing yourself - especially when there's a couple thousand people reading what you write.  Oh yeah, you might get some attention and name recognition out of it too.
      5. Read a lot - There's a tremendous amount of stuff out there in the blogosphere.  Take advantage of it. 
      6. Expand your reading - Your OPML file is one of your best intellectual tools, but make sure there's some balance in your RSS feed diet.  My OPML file still leans too heavily to Agile-flavored writers, but I've expanded my reading intake quite a bit to include developers, testers, and project managers from outside of the .Net community to see how the rest of the world is doing things.  Just to get you started, and feel free to write in suggestions, break out of the .Net mold with:
        1. programming.reddit.com & joel.reddit.com
        2. Raganwald
        3. Giles Bowkett
        4. Jay Fields
        5. Neal Ford
    26. How I'm, sigh, going to become a better developer

      I was perfectly content to sit out this meme started by a bunch of wacky Canuck's, but Bil Simser tagged me

      It's not really this bad, but it always feels like you're never quite as good as you wish you were.  Every time I think I've arrived at my career destination, I just learn something new that teaches me just how much I don't know.  Software development is a young discipline on a rollercoaster ride, where ideas quickly gain traction and fall away almost as fast.  In the field of software development, you're either learning or regressing.  There just isn't any way to tread water.

      Here's my distressingly long list of the things I want to do over the next 6-12 months to become a better developer:

      Things I Should Do

      • Since the world is conspiring to force me into an occasional Project Manager role, I'm going to improve my planning and estimation skills by reading Mike Cohn's Agile Estimating and Planning book.
      • Get StoryTeller released.  The engine is fine, but I'm going to rewrite some of the UI.  I'm not really passionate about the project so much as I simply wanted a tool like StoryTeller.
      • Learn more about the financial industry
      • Add some better low level knowledge and heavy duty concurrency programming techniques to my belt

       

      Things I Want to Do

      • I'm finally going to take StructureMap into the Aspect Oriented Programming arena.  Most likely it'll just be integrated support for an existing AOP technology.  I put it off for a long, long time because I just didn't think AOP was very valuable.  I'm starting to see some real examples that are making me change my mind.  I fully realize that StructureMap is probably last in terms of adoption, I'm going to keep it going regardless to be my software design laboratory
      • I'm going to learn at least a working knowledge of Functional Programming.  I just barely started to learn Haskell, but I've decided to switch to F# instead.  It looks like the F# team has some real momentum and energy and it just might be something you could actually use on a project in the near term.  I'm thinking about trying to create some sort of test refactoring support into StoryTeller and use F# to build that functionality.  I really don't want to be that guy who just can't grok OOP because all they learned was COBOL -- except move OOP to the right and backfill the beginning with Functional Programming.  Learning Functional Programming is also a way to get ready for the massively multi-threaded application development that's heading our way in a couple years.
      • I've got two related ideas for new IronRuby OSS projects, both related to DSL's applied to WinForms or WPF.  One to finally master Ruby instead of just playing around, and two to deeply explore the mechanics of writing internal Domain Specific Language's.
      • I'd like to do more speaking engagements and become a better speaker.  I did several talks when I lived in Austin, but not anything lately.  I enjoyed DevTeach in Montreal and I'm hoping to speak again in Vancouver.  I want to be a No Fluff, Just Stuff speaker when I grow up.

       

      Things I Won't Do

      • I have no interest in becoming a Certified ScrumMaster.  If you've read this blog before you know I'm a huge proponent of Extreme Programming techniques and Agile development in general, but even so, I think Certified ScrumMaster sounds eerily like certified Snake Oil Salesman.  Besides, my passion is for the software construction side of things.
      • Dive deeply into WPF, WCF, and WF.  I'll learn them in detail, and with enthusiasm, when I need them, but not a moment before then.  There are nuggets of knowledge that serve you well on every project, and there is API memorization that's only useful on specific projects.  I'd rather focus on the general knowledge first.  I will say that WCF would have been a beautiful thing for the types of projects I was doing 5 years ago.
      • Write a book.  I've flirted with it.  I chickened out once.  I was excited about a possible book proposal in May, but it just sounds like too much work right now for not enough gain.  Besides, I think I actually get as much "reach" from the blog than I would by publishing a book.

       

       

      Tag, You're It!  (no tag backs!)

      I want to know what these guys are up to:

    27. Build your own CAB #13 - Embedded Controllers with a Dash of DSL

      Start with http://andersnoras.com/blogs/anoras/archive/2007/07/04/i-m-coming-down-with-a-serious-case-of-the-dsls.aspx and come back.

      Just to continue the world's longest run on sentence.  Before I start, here's the table of contents for the "Build your own CAB" series:

      1. Preamble
      2. The Humble Dialog Box
      3. Supervising Controller
      4. Passive View
      5. Presentation Model
      6. View to Presenter Communication
      7. Answering some questions
      8. What's the Model?
      9. Assigning Responsibilities in a Model View Presenter Architecture
      10. Domain Centric Validation with the Notification Pattern
      11. Unit Testing the UI with NUnitForms
      12. Event Aggregator
      13. Rein in runaway events with the "Latch"
      14. Embedded Controllers with a Dash of DSL (This Post)
      15. MicroControllers - Forthcoming
      16. Subcutaneous Testing - Forthcoming
      17. Creating the Application Shell - probably a couple posts
      18. Wiring the Components with an IoC tool - Forthcoming

      Why is this post necessary?

      Why, you might ask, are you writing a post on what amounts to a "ViewHelper?"  One simple reason - View's can easily become absolutely massive blobs of code.  Any chance to move a cohesive set of screen responsibilities into another class should serve to make the View itself simpler, and that's all this post is about.  Plus, breaking a View's behavior into multiple, cohesive classes can potentially lead to reuse opportunities for the little Embedded Controller classes.

      For much of the last three years I've worked with a lot of legacy code over a half-dozen different codebase's.  All of them, to be charitable, were less than ideal in quality and structure.  If you ask me what the single biggest flaw or problem across all of these codebase's my answer would be near automatic -- long classes and long methods.  What I continuously see is code stuffed into modules until the modules are coming apart at the seams. 

      Come to think of it, my current project is about 95% greenfield code so far.  Come Thanksgiving time when it's my turn to say what I'm thankful for my answer might just be "I'm thankful for getting six months of working on a greenfield project."

      Embedded Controller

      Again, I'm not a sanctioned patterns naming body, but the term "Embedded Controller" is my name for nonvisual classes that help a View control some distinct part of it's behavior.  The first example that comes to my mind is from a WinForms project that used a 3rd party grid (not a vendor on the CodeBetter friends list by the way).  The grid control needed a lot of consistent help and infrastructure code around it to implement the behavior we needed (little things like sorting and paging).  We quickly discovered that additional screens needed the exact same bootstrapping code, so the obvious answer was to extract that "grid helper" into it's own reusable class.  We were using a pretty strict Passive View approach, but even so, we didn't want the Presenter's tied that tightly to the screen mechanics.  Instead, the new GridHelper class was just something that the View controls used internally.  After the third screen with the grid control, development suddenly went faster. 

      To differentiate Embedded Controller classes somewhat from the Presenter, here's the attributes of an Embedded Controller:

      • Nonvisual class used by a View to implement some of the View behavior.  I guess in
      • Completely encapsulated within a View.  There is no sign of the Embedded Controller in a View's publicly facing interface.
      • Embedded Controller's are happily aware of the actual, concrete UI widgets.  The Embedded Controller class "knows" about buttons and checkbox's and the nasty 3rd party grid that you're being forced to use.
      • Very limited in scope.  An Embedded Controller provides classical controller functionality for a very specific part of the screen

       

      My advice for taking advantage of Embedded Controller's is threefold:

      1. Look for common UI coding tasks within a system and look for opportunities to encapsulate some screen mechanics in reusable pieces.  This is just another exercise in eliminating duplication.
      2. Split up any View class that gets too big.  I might have left the impression in earlier posts that the View code is somehow exempt from the normal coding standards because we've made it "simpler" now.  Code quality matters everywhere, and especially in areas of the code that are likely to change over time -- like View's.  Even with a Passive View architecture a complex screen will almost inevitably lead to complex code in the View.
      3. Pulling out an Embedded Controller might be an easy way to extend unit testing deeper into the View.  This won't always be true, but a "POCO" embedded controller class can often be quite easy to unit test inside vanilla xUnit tests without resorting to anything exotic like NUnitForms.  There is some widget behavior that only functions when a Form is visibly displayed, but a lot of behavior can be tested just by instantiating UI widgets directly within a unit test.  One way or another the UI widget stuff is nothing but CLR classes.

       

      Sample:  The Control State Machine

      Here's a scenario from my current project that I bet all of us have dealt with a few times over.  We have a Trade screen that has seven different states depending upon whether you're creating or reviewing a Trade.  The various user actions available on the screen differ from state to state.  As the screen changes state either upon opening the screen or a result of user actions while it's open we need to enable/disable and show/hide different screen elements.  The screen started simple, so I just coded specific methods at first to enable or disable bits of the screen.  Fast forward a couple of weeks and the behavioral logic had exploded (funny how that happens when you actually get to talk to the end users).  Unsurprisingly, the code in the Presenter and View had become hairy, plus the screen had way too much flicker for that matter. 

      Before I show any code, let's be pretty clear that this code is not very optimized or even very powerful.  All I want to talk about is the concepts and structure of the design irrespective of performance.

      At least in concept, the solution was pretty simple.  Move that logic into a state machine construct.  Since we already had a full set of regression tests against the UI screen itself, I felt pretty safe making the changes.  All I did was create a class called "ControlState" that's nothing but a collection of Control's to display and enable for a particular screen state.  ControlState has a method called Activate() which simply loops through its internal collection to enable and show the configured controls (it's not shown but the call to Activate() is wrapped in SuspendLayout() and ResumeLayout()). 

       

              public class ControlState
              {
                  private List<Control> _displayedItems = new List<Control>();
                  private List<Control> _enabledItems = new List<Control>();
       
                  public void ShowControls(params Control[] controls)
                  {
                      _displayedItems.AddRange(controls);
                  }
       
                  public void EnableControls(params Control[] controls)
                  {
                      _enabledItems.AddRange(controls);
                  }
       
                  public void Activate(ControlStateMachine<T> machine)
                  {
                      machine.LevelSet();
       
                      foreach (Control item in _enabledItems)
                      {
                          item.Enabled = true;
                      }
       
                      foreach (Control item in _displayedItems)
                      {
                          item.Visible = true;
                      }
                  }
              }

      As you can probably guess, there's a second class that aggregates all of the configured ControlState's and Control's called ControlStateMachine<T>, where T is an enumeration of the possible states.  Here's a little bit of its implementation. 

       

              private readonly Control _parent;
              private readonly IScreenBinder _binder;
              private List<Control> _displayedItems = new List<Control>();
              private List<Control> _enabledItems = new List<Control>();
              private Dictionary<T, ControlState> _states = new Dictionary<T, ControlState>();
              private T _currentState;
       
              public ControlStateMachine(Control parent, IScreenBinder binder)
              {
                  _parent = parent;
                  _binder = binder;
              }
       
              public void SetState(T stateKey)
              {
                  _parent.SuspendLayout();
       
                  _states[stateKey].Activate(_binder, this);
                  _currentState = stateKey;
       
                  _parent.ResumeLayout();
              }

      The View itself just calls ControlStateMachine.SetState() to configure itself.

      Now, for the cool part.  Here's a somewhat obfuscated version of our code that defines the state machine inside the View.* 

              private void configureStateMachine()
              {
                  _stateMachine = new ControlStateMachine<TradeDetailState>(this, _binder);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.Creation)
                      .Show(createTradeButtonsPanel)
                      .Enable(status1CheckBox, status2CheckBox, status3CheckBox, externalTradeIdTextbox);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.Review)
                      .Show(updateTradeButtonsPanel)
                      .IsReadOnly()
                      .Enable(
                          editTradeButton, 
                          status1CheckBox, 
                          status2CheckBox, 
                          status3CheckBox, 
                          externalTradeIdTextbox, 
                          cancelTradeButton);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.ReviewDirty)
                      .Show(updateTradeButtonsPanel)
                      .IsReadOnly()
                      .Enable(
                          undoButton, 
                          status1CheckBox, 
                          status2CheckBox, 
                          status3CheckBox, 
                          submitTradeChangesButton, 
                          externalTradeIdTextbox, 
                          cancelTradeButton);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.Edit)
                      .Show(updateTradeButtonsPanel)
                      .Enable(externalTradeIdTextbox, cancelTradeButton);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.EditDirty)
                      .Show(updateTradeButtonsPanel)
                      .Enable(undoButton, submitTradeChangesButton, externalTradeIdTextbox, cancelTradeButton);
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.Cancelled)
                      .Show(updateTradeButtonsPanel)
                      .DisableEverything()
                      .IsReadOnly();
       
                  _stateMachine.OnStateChangeTo(TradeDetailState.History)
                      .Show()
                      .DisableEverything()
                      .IsReadOnly();
              }

      If you haven't seen this kind of syntax before, it's what Martin Fowler (a real patterns naming authority) has christened Fluent Interface.  Why, oh why, did I go to the extra trouble of making a Fluent Interface instead of just defining the state machine by filling up the collection state (and let's be clear, it is a little more work)?  Because I thought it would make a good blog post wanted to create Domain Specific Language in the code to make the code easier to understand.

       

      That's Not Really a DSL!

      Unfortunately, in my opinion, the .Net community is fixated on graphical Domain Specific Language's (DSL) that revolve around yet more code generating visual tooling.  There's a complete other side to the DSL's however.  Another alternative is lexical languages which could be either internal/embedded or external to the language, with the pro-lexical argument being something like "people can read English you know."  I'm not particularly enamoured of creating my own programming language and interpreter, so my particular area of interest right now is in creating embedded DSL-like syntax's inside existing languages.  Granted, C# is very limited in th