Development Blog

 Sunday, February 11, 2007

It amazes me how often developers lack fundamental competencies. Things that every developer should at LEAST know about, somewhat understand and know the capabilities of (i.e. when they're presented with a problem that is easily solvable using something such as... oh, regular expressions, they can at least google the steps to a solution.) What I'm trying to say is:

Understand and make use of regular expressions whenever it is appropriate.

Unfortunately, if you're reading this blog, you probably read several other blogs, so you've already been exposed to regex's. If that's the case, the tip for you is:

Think of more ways you can use regular expressions, understand them even more, oh and tell a friend/coworker who doesn't subscribe to 30 dev blogs and doesn't understand/make use of regular expressions about them.

There are several resources for regular expressions.

Roy Osherove has come up with some pretty killer tools for regex:

What do you do with them? Well, there are tons of uses for them, but here's a quick list of some of the basic things they're used for:

  • Find things - Duh.
  • Replace things - tons of cool stuff you can do here with and without capture groups. Here's a naive example:
    Foo bar
    Blah yadda
    Etc etc
    // search: (\w*) (\w*) replace: \1 \2 = new \1();
    // becomes:
    Foo bar = new Foo();
    Blah yadda = new Blah();
    Etc etc = new Etc();
    
  • Parse things - obviously we love to parse things.
by Aaron on Sunday, February 11, 2007 10:33:10 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, February 09, 2007

I've seen several people say the following when talking about TestDriven.NET: "It's so easy, just right click, and click run tests!" Maybe I'm just too lazy, but what's easy about moving my hand to the mouse, right clicking, finding the appropriate menu item and clicking it?

Bind a key to Run Test(s) and Run Test(s) with Debugger (I use Ctrl+Shift+R and Ctrl+Shift+D)

Just look for TestDriven.NET.RunTests and TestDriven.NET.Debugger in your keyboard settings. I personally use Resharper's Unit Testing feature (except in our 32bit apps on our x64 machines... they're still fixing that bug), but it's all the same. Bind a key to it. Real easy to finish up a test, hit Ctrl+Shift+R, and away you go. No arm movement required!

by Aaron on Friday, February 09, 2007 4:46:23 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [2]  |  Trackback

I've mentioned several tools that we use here, many of which cost money.  We're very lucky here that we can have most of the tools that we want, I know it pains the check writers--"What? Another $300s per dev?!?!" but thankfully they understand that it helps us immensely. I can't help but notice that occasionally people will mention on their blogs that they really like a tool, but that their company won't buy it for them. I think that usually, that shows a bit of shortsightedness in their management.

Developers are expensive and impatient. Good developers are often even more expensive and even more impatient. Tools help developers write more code faster, better, and with less distraction. We'll use ReSharper as an example to try and calculate true cost of the tool.

Let's say a developer's salary is $60,000 per year, that's about $240/day, or $30/hr. Say you build 10 times in an hour, half those times, you accidently typo'd something so you have to rebuild. We'll say fixing/rebuilding costs you 2 minutes per hour. That's 16 minutes per day or $8/day, $40/week, or about $2000/year. All for losing 2 minutes per hour. It's worse than that too, because 2 minutes is a gross exaageration, and that 2 minutes is during a developer's most productive time... the time they actually spend producing.

Now what if, for $300 you could have something that would warn you of impending build errors, so that you could fix them before you actually built? What if it had keybindings (I use Ctrl+Shift+N and Ctrl+Shift+P) to skip to the next error so you can quickly correct it? What if it saved you not only those 2 minutes per hour, but also gave you several other nifty features that saved you time with navigating, formatting, and several other things. Would you spend $300 to save $2000 per year? I would hope the answer is yes. Many other tools share this same productivity boost to cost ratio.

Does this mean developers should have carte blanche for tools? I don't think so. There still needs to be some filter in place, some time for evaluation, and someone who is in tune with both a developer's need for a tool and the company's need not to spend money senselessly, but please, managers, seriously consider requests for tools.

by Aaron on Friday, February 09, 2007 4:33:41 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Tuesday, February 06, 2007

This goes hand in hand with the first tip, so I figured I should post it now.

Get Gaston Milano's Cool Commands 4.0 and bind a key to Collapse All Projects (I use Ctrl+Alt+C)

There are plenty of other useful gems in CoolCommands (e.g. copy/paste project reference is very useful), but the one I use several times a day is Collapse All Projects. If you've got 40 projects, collapsing them all makes selecting the 36 projects you want to unload much easier.

by Aaron on Tuesday, February 06, 2007 8:45:14 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [2]  |  Trackback

I don't like waiting for things. I don't like typing the same thing over and over again for days, weeks or even months on end. I do as much as I can to speed my production of code up. I want the bottleneck to be in my mind, not in my fingers or my cpu. I figured I'd share some of the things I've learned along the way. Hopefully, a few of the tips will grab your interest and make coding just a little bit less tedious for you. So without further blathering, onto the first tip.

Bind keys to Unload Project and Reload Project (I use Ctrl+Alt+U and Ctrl+Alt+R) and liberally unload projects you aren't mucking with.

This may not apply to you, but here at Eleutian we have about 40 projects to build. Client, server, tools, shared libraries, generators, preprocessors, etc and of course tests for all of them. If you have all 40 projects open, just the dirty check during a build can take up a good amount of time. Generally you're only working on a few projects at a time, so go ahead and unload the rest (you can shift and ctrl select multiple projects to unload or reload). Every build you do (if you're doing TDD, you're dong several) will take significantly less time. Less time between build/test runs is a huge win. Adding the keybinding just saves you from fishing through the 100 item project context menu.

by Aaron on Tuesday, February 06, 2007 8:36:42 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Friday, February 02, 2007

As promised, here's the plugin I was talking about and the Rhino Mocks templates.

Rhino Mocks Templates - Import these in your Template config.

Plugin - Drop this in your "%PROGRAMFILES%\Developer Express Inc\DXCore for Visual Studio .NET\2.0\Bin\Plugins" Oh, and yeah I know it's named after only one of the commands in there, but I was too lazy after I added the other commands to rename the project. You'll see the new commands in the Template configuration in the Command dropdown.

Plugin Source - I know, not the source you want from us right now and it's pretty ugly, but it's a start, right?

by Aaron on Friday, February 02, 2007 6:00:18 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback

I mentioned before that we love templates in CodeRush and that they're incredibly customizable. I wanted to give a few examples of that and share one of the plugins I wrote for it.

We use Ayende's Rhino Mocks quite a bit. We're also lazy, so I came up with a set of templates for it:

  • tfm - Expands to a TestFixture that includes a MockRepository already.
  • scm/sdm - Takes whatever is in your clipboard and expands to this:
    someClass = _mocks.CreateMock<SomeClass>();
  • =cm/=dm - Similar to scm/sdm, but for when you don't have anything in your clipboard
  • mu/mo - Creates a using(_mocks.[Un]ordered()) block
  • mra - ReplayAll
  • mv/mva - Verify or VerifyAll
  • ec - Expect.Call().Return();

One thing I noticed while I was using these is that sometimes I wanted to use them after I'd already written some code that would be in the expansion... for example, say I've already got a class called SomeClassTests but I want to add the TestFixture attribute, add the MockRepository instance variable, etc. Before I had to delete the class and do a tfm on a blank slate. Instead, I spent a few minutes writing a template command plugin that allows you to add an attribute to the class your cursor is in. That enabled me to do what you see in the video below.

Also, say I've already typed the method I was going to set a rhino expectation on. Normally, I'd just have to go to the beginning of the line, type Expect.Call(, go to the end of the line, type the rest. So to solve this, I wrote a few commands: DeleteSemicolon (this one seems a bit buggy w/ the latest CodeRush), GotoBeginningOfLine, and GotoEndOfLine. Now ec, ae, an, ann, etc can all be written to add code around code I've already written as you'll see in the video below.

Bear with me on this video, it's my first attempt at something like this. If anyone can suggest something better than YouTube and a screen recorder for stuff like this that's still free, I'd appreciate it. I don't like being limited to 320x240.

Also, the astute will notice that I'm not running Resharper on this machine. This is my home machine and once again I'm not quite sure about the stability of it (it likes to crash every time I close VS, it breaks some autocomplete scenarios, etc). There are some autocomplete issues in this video, but i think that's just because I had multiple classes named the same thing in this project.

I tried to go slowly so that you can see the templates before I expand them so that hopefully you can get a feel as to how easy it is to write code when you've got templates this powerful. I'm going to upload the source for the plugins as well as my Rhino Mocks templates a bit later today.

by Aaron on Friday, February 02, 2007 10:04:00 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Tuesday, January 30, 2007

I figured I might as well continue on the string literal kick I started with my last post and talk about another situation where we've eliminated string literals. Take the following code from inside a MonoRail action method:

PropertyBag["User"] = ourUser;
PropertyBag["TwoStates"] = new string[] { "WA", "CA" };
PropertyBag["IsAdmin"] = true;

String literals, used as keys into dictionaries carry a cetain degree of code smell (for us) and we try to avoid them. It reminds me too much code that does something similar, but in the opposite direction:

int id = Int32.Parse(this.Params["id"])

Thankfully, this kind of code is eliminated when using MonoRail and its SmartDispatchController. We found ourselves thinking of how the same code would look in a SWF application. We would be populating views, only those views would be interfaces that the various forms/controls implemented. Well, this is exactly what we wanted in MonoRail, to wrap the PropertyBag with an interface!

After a few hours playing with Reflection.Emit, I had a code generator that would take an interface:

public interface IEditMyProfileView
{
  string Name { get; set; }
  DateTime Birthday { get; set; }
  IList<TimeZone> TimeZones { get; set; }
}

And produce a class like the following:

public class EditMyProfileViewPropertyBagManipulator : IEditMyProfileView {
  private IDictionary _bag;

  public EditMyProfileViewPropertyBagManipulator(IDictionary bag) {
    _bag = bag;
  }

  public string Name {
    get { return (string)_bag["Name"]; }
    set { _bag["Name"] = value; }
  }
  public DateTime Birthday {
    get { return (DateTime)_bag["Birthday"]; }
    set { _bag["Birthday"] = value; }
  }
  public IList<TimeZone> TimeZones {
    get { return (IList<TimeZone>)_bag["TimeZones"]; }
    set { _bag["TimeZones"] = value; }
  }
}

This has the advantage of keeping our interactions with the PropertyBag as type safe as they can be. Changing the interface, breaks the build. Where as changing the type of a value inserted into the PropertyBag will (hopefully) only break tests if even that. This is another example of us trying to turn run-time failures into compile-time failures.

This kind of thing also makes tests more elegant. Instead of:

Assert.Equals("Jacob", PropertyBag["Name"]);

In our controller tests, we can continue to leverage the use of RhinoMocks to ensure the views are properly initialized:

using (_mocks.Unordered()) {
  _view.Name = "Jacob";
}
_mocks.ReplayAll();
_controller.Action();
_mocks.Verify(_view);

All we've done here is created a mock from the view interface, rather than emitting the wrapper class. Again, another added benefit is if the view changes, compiling the tests will also break. The sooner things break after a change the better, and the build is pretty soon. Although, with ReSharper, it's nice to see red squiggles appear as that's even sooner.

by Jacob on Tuesday, January 30, 2007 8:31:07 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Monday, January 29, 2007

I was trying to think of a way to introduce this post, and I realize that here at Eleutian, we hate strings. We don't hate all strings, it's mostly string literals that we hate. Not even all string literals. But most of them. A good portion of the work we do to make our code more solid involves removing string literals. Anybody familiar with MonoRail has seen lines similar to the following:

RenderView("Home", "Action");
<a href="${siteRoot}/Home/Action.rails">...</a>

${UrlHelper.LinkTo("Home", "Action")}

And so on, see all those string literals that refer to things that aren't really string literals? At first glance, we can get rid of the Controller string by doing something with typeof(HomeController).Name and chopping off the Controller suffix. That'd be an ugly static method call everywhere and still leaves "Action" to be dealt with. We want things to break if HomeController changes names and we want to know where HomeController is referenced.

One of our rules is to turn potential run-time errors into potential compile time errors if at all possible.

It's funny, but the compiler is our first test, and a good one at that. We found ourselves using those controller names, area names, and action names in a variety of situations - redirections, view rendering, generating url's in the views, etc... Anytime I see this I'm annoyed:

Redirect("AnotherAction.rails?parameter=34");

or even worse:

Dictionary query = new Dictionary();
query["parameter"] = 34;
Redirect("AnotherAction.rails", query);

You'll notice that our life would be much easier if methods were first-class objects. They aren't in C# 2.0... or even in 3.0 (without lambda functions) and so this is where we are.

Aaron and I talked things over, complaining on end about how frustrating things were. Our problem boiled down to turning the controller action's into something we could reference, so we decided to try a little code generation magic. We wanted to be able to write code like the following:

MyActions.Action().Render()

Site.AdministrativeArea.Home.Action(24, "Jacob").Redirect()

And so on. In order to do this we have a tool that runs as a pre-build step that does the following:

  • Walks the source tree, parsing *.cs files, looking for controllers. We have to parse source, we can't use reflection because the same source files we're parsing will be using this generated code.
  • Look for public methods (the actions) on the controller.
  • Generates a class (HomeControllerNode) that has a method, with the same prototype as the action, that returns a ControllerActionReference:
public partial class HomeControllerNode {        
  private IControllerServices _services;

  public HomeControllerNode(IControllerServices services) {
    this._services = services;
  }

  public virtual HomeControllerViewsNode Views {
    get {
      return new HomeControllerViewsNode(this._services);
    }
  }

  [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public virtual ControllerActionReference SomeAction() {
    return this._services.ControllerReferenceFactory.CreateActionReference(this._services.Controller, typeof(HomeController),
      "Home", "Administrative", "SomeAction", new ActionArgument[0]);
  }

  [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public virtual ControllerActionReference AnotherAction(string name) {
    return this._services.ControllerReferenceFactory.CreateActionReference(this._services.Controller, typeof(HomeController), 
      "Home", "Administrative", "AnotherAction", new ActionArgument[] {
        new ActionArgument("name", typeof(string), name)});    }
  }
}
  • Generates a stub class for area's with properties for each controller in that area (they return HomeControllerNode instances) We introduce a default root area that all top level controllers and other areas are children of:
public partial class AdministrativeAreaNode {        
  private IControllerServices _services;
        
  private HomeControllerNode _home;

  public AdministrativeAreaNode(IControllerServices services) {
    this._services = services;
    this._home = new HomeControllerNode(this._services);
  }
        
  public virtual HomeControllerNode Home {
    get {
      return this._home;
    }
  }
}
  • Walks the Views subdirectory looking for *.brail files mapping them onto their controllers.
  • Generates a class (HomeControllerViewsNode) with methods for each view that return a ControllerViewReference.
public partial class HomeControllerViewsNode {        
  private IControllerServices _services;

  public HomeControllerViewsNode(IControllerServices services) {
    this._services = services;
  }

  [System.Diagnostics.DebuggerNonUserCodeAttribute()]         
  public virtual ControllerViewReference SomeAction {
    get {
      return this._services.ControllerReferenceFactory.CreateViewReference(this._services.Controller, typeof(HomeController),
        "Home", "Administrative", "SomeAction");
    }
  }
}
  • Generates a partial class for the controller class itself with two properties - MyViews and MyActions that return the ControllerNode and ControllerViewsNode instances for that controller.
public partial class HomeController {
  public virtual HomeControllerNode MyActions {
    get {
      return new HomeControllerNode(this.ControllerServices);
    }
  }
        
  public virtual HomeControllerViewsNode MyViews {
    get {
      return new HomeControllerViewsNode(this.ControllerServices);
    }
  }
        
  protected override void PerformGeneratedInitialize() {
    base.PerformGeneratedInitialize();
    this.PropertyBag["MyViews"] = this.MyViews;
    this.PropertyBag["MyActions"] = this.MyActions;
  }
}

In the generated code, we pass a reference to an IControllerServices implementation down through the hierarchy, which provides the ControllerReferenceFactory that creates the ControllerActionReference and ControllerViewReference objects. Our EleutianController class has a property on it - Site, that returns the RootAreaNode so the top of the site can be reached from anywhere. This is also always placed into the controller's PropertyBag, along with MyActions and MyViews. The PerformGeneratedInitialize method, that's called in our base class so that each controller can add it's own MyViews and MyActions, which don't live in the base class.

Our ControllerActionReference class has Redirect and Transfer methods as well as a Url property. So now we can do the following:

<a href="${Site.HomeController.Action(200, true).Url}">...</a>

ControllerViewReference has a Render method that does the appropriate RenderView call on the controller. Now we've accomplished a lot of things:

  1. No more string literals. If we rename something, the build fails. Our views will fail when they're opened and not when links are followed, it is pretty easy to test that a view compiles.
  2. All URLs for redirections/transfers are always well formed and include necessary parameters with proper type checking.
  3. Provided ourselves with Intellisense when building URLs in tests and controllers. (Sexy? Yes.)

Speaking of testing, in our controller tests we have a custom IControllerReferenceFactory that returns mock ControllerActionReference instances (via RhinoMocks) So now redirections, transfers and view renderings are just mocked method calls:

using (_mocks.Unordered())
{
  _controller.MyViews.AnotherView.Render();
}

_mocks.ReplayAll();
_controller.SomeActionThatRendersAnotherView();
_mocks.VerifyAll();

Which is much cleaner than string comparisons on _controller.SelectedViewName, especially if a redirect with parameters is expected in an action. This has simplified our life and given us incredible peace of mind, well worth the time to implement - which was relatively simple. Whew.

by Jacob on Monday, January 29, 2007 6:45:08 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Sunday, January 28, 2007

My team and I are whores when it comes to productivity tools. At the moment I have and use so many in concer it's kind of amusing. I've actually spent a decent amount of time working with the various tool authors to get their tools to play more friendly so that I can use them together. Here's a rundown of some of the tools I use every day:

  • CodeRush with Refactor! Pro
    • I'm pretty sure I couldn't happily write code without this, and I even disable or neglect half the features.
    • I use and customize the templates heavily. They're so customizable its stupid. You can literrally do just about anything, and if you can't do it, you can write a plugin to help you do it and integrate it with any other template. I'll post the set of plugins I wrote for CodeRush later.
    • The refactorings are great and rank high on the visual appeal, discoverability and usability scales.
  • ViEmu (Visual Studio vi/vim emulation)
    • I almost took it upon myself to write this. When I worked at Microsoft, I submitted requests to the Visual Studio team to write this. Jon came to the rescue and implemented the now near-perfect ViEmu and he will forever be my hero.
    • Vim is really so much faster than regular text editing it makes transferring code from your mind to the screen much less of a barrier. If you haven't heard of it, used it, given it a good shot, or even if you haven't fallen in love with it, I'd strongly recommend doing all of those things. Here are some resources to get you started:
    • One quick tip: use Ctrl+[ instead of escape to get out of insert mode, it'll save you at least 15 seconds a day!
  • ReSharper
    • This one's new to me. I've tried it twice in the past and it's only done bad things--crashed, played badly with CodeRush or ViEmu, etc. The latest version however, seems to play fine with everything I have installed, so it's going to stay. Yes, I use CodeRush AND Resharper. I told you I was a productivity tool whore.
    • The biggest feature for me is the Error Highlighting and QuickFixes. Most of the refactorings CodeRush does (often better) but there are a few that are pretty slick.
    • The navigation features are great too. Real fast and real usable, much better than scrolling through our 40 project solution.
by Aaron on Sunday, January 28, 2007 10:54:23 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback