• Adam Esterline
  • View Adam Esterline's profile on LinkedIn
  • Advertisements

Cost Effective C# IDE

What is the most cost effective way to develop C#?I use VS 2005 with R# when working with clients, but unfortunately that copy of VS 2005 is owned by my employer. The same setup at home would cost $1400+. I know there are free C# IDEs, but they all have flaws that are hard to overlook.What are you using to develop C# outside of your workplace?Looking for ideas.p.s.I wish the ALT.NET guys would start building the Ideal IDE 😉


RoR based MVC Web Frameworks – Friend or Foe?

Ruby on Rails has inspired a whole generation of MVC Web Frameworks. The RoR inspired frameworks follow the same basic design; Controllers whose public methods are web endpoints. So…Do RoR based MVC Web Frameworks encourage good design?

MonoRail and MS MVC are a part of the RoR generation.  

They must. Right? I show, in the code below, that RoR inspired frameworks can actually encourage bad design. I show, in the end, what I think is a better way.

The code presented here is written for MonoRail, but the same problems exist in MS MVC and RoR.  

Let’s start with a simple ProductsController. The index method of this controller is the implementation of http://whocares.com/products/<code&gt;. The code on the end of the URL is the code for a specific product (i.e. nj1287).

public class ProductsController : SmartDispatcherController{   public void Index(string code)   {      Product product = Product.FindByCode(code);      if(product == null)      {         PropertyBag["UnknownSearchTerm"] = code;         RenderView("common/unknown_quick_search");      }      PropertyBag["Product"] = product;      RenderView("display_product");   }}

CategoriesController is our next controller. The index method of this controller is the implementation of http://whocares.com/categories/<name&gt;. The name on the end of the URL is the name for a specific category (i.e. montiors).

public class CategoriesController : SmartDispatcherController{   public void Index(string name)   {      Category cat = Category.FindByName(name);      if(cat == null)      {         PropertyBag["UnknownSearchTerm"] = name;         RenderView("common/unknown_quick_search");      }      PropertyBag["Category"] = cat;      RenderView("display_category");   }}

The index method in both classes are basically the same. We can remove the duplication. Let’s extract an abstract class.

public abstract class SearchableController : SmartDispatcherController{   public void Index(string name)   {      ISearchable item = FindByName(name);      if(item == null)      {         PropertyBag["UnknownSearchTerm"] = name;         RenderView("common/unknown_quick_search");      }      PropertyBag["Item"] = item;      RenderView(IndexView);   }   protected abstract ISearchable FindByName(string name);   protected abstract string IndexView { get; }}public class ProductsController : SearchableController{   protected ISearchable FindByName(string name)   {      return Product.FindByCode(name);   }   protected string IndexView { get { return "display_product"; } }}public class CategoriesController : SearchableController{   protected ISearchable FindByName(string name)   {      return Category.FindByName(name);   }   protected string IndexView { get { return "display_category"; } }}

What do you think about our new DRY code?I don’t like it. Why?

  1. ProductsController and CategoriesController no longer “speak” to me.
  2. Inheritance. I really don’t like the template method pattern because of #1.

Can we fix this?We can use a DynamicAction in MonoRail. Let’s see that code.

Does RoR or MS MVC have a concept of a “DynamicAction”?  

public class IndexAction : IDynamicAction{   private ISearchableRepository repos;   private string indexView;   public IndexAction(      ISearchableRepository repos,      string indexView)   {      this.repos = repos;      this.indexView = indexView;   }   public void Execute(Controller controller)   {      string name = controller.Params["name"];      ISearchable item = repos.FindByName(name);      if(item == null)      {         controller.PropertyBag["UnknownSearchTerm"] = name;         controller.RenderView("common/unknown_quick_search");      }      controller.PropertyBag["Item"] = item;      controller.RenderView(indexView);   }}public class ProductsController : SmartDispatcherController{   public ProductsController()   {      DynamicActions["Index"] = new IndexAction(             new ProductsRepository(), "display_product");   }} public class CategoriesController : SmartDispatcherController{   public CategoriesController()   {      DynamicActions["Index"] = new IndexAction(             new CategoryRepository(), "display_category");   }}

I like this code better. We are no longer using inheritance to reuse code and the code “speaks” better to me. This code has two things that bug me.

  1. The controllers are really not doing much.
  2. DynamicActions are second class citizens in MonoRail.

How do we fix these issues? I don’t know how in the RoR inspired frameworks. I think we need another abstraction. Chris Ortman and I discussed the below code at HDC 07 (so he deserves at least part of the credit). I am not sure he agreed, but maybe this post will change his mind.

The code below is not apart of any framework. It is only an idea.  

public class IndexAction : SmartDispatcherAction{   private ISearchableRepository repos;   private string indexView;   public IndexAction(      ISearchableRepository repos,      string indexView)   {      this.repos = repos;      this.indexView = indexView;   }   public void Execute(string name)   {      ISearchable item = repos.FindByName(name);      if(item == null)      {         PropertyBag["UnknownSearchTerm"] = name;         RenderView("common/unknown_quick_search");      }      PropertyBag["Item"] = item;      RenderView(indexView);   }}

IndexAction is now a first class citizen of the framework. Actions have all the benefits that controllers have in MonoRail (parameter binding, …).How do we hook this action to a URL?

new Route("/products/<name>",    new IndexAction(new ProductRepository(), "display_product"));new Route("/categories/<name>",    new IndexAction(new CategoryRepository(), "display_category"));

Routing engines allow us to remove the “controller” completely. We don’t need a “controller” (at least not in the RoR framework form). What were our controllers doing? They were really just organizing our actions. Routing engines allow us to organize our actions without the “controller”.What do you think? I would really like some feedback on this topic. Does anyone else feel this pain with these frameworks?

MonoRail – Beginner FAQ

I am giving a MonoRail talk, at HDC 07, on Thursday morning.What questions do you think I should be prepared to answer?Here is a list of questions, and answers, that I typically get, and give, about MonoRail.Why would I use (care about) MonoRail?

  • Separation of concerns makes your application easier to test.
  • Microsoft will soon be releasing MS MVC. It is very similar to MonoRail.
  • It works well on teams where the designers and developers are not the same people.
  • Your team does not come from the MS world. MonoRail is closer to the framework designs from other languages (Java, Ruby).

Why would I not use MonoRail?

  • Your project depends too much on 3rd party controls.
  • Your teams skill set is totally centered around WebForms.
  • If your only experience with developing web sites is with WebForms, then you will have to learn HTTP.

What kinds of projects work best with MonoRail?

  • I would choose MonoRail for all projects, except for simple reporting web applications.

Do you have any other questions that you think I should be prepared to answer? Do you have anything to add to the current set of answers?

MS MVC – A MonoRail Perspective

Scott Guthrie gave us our first look at the the new Microsoft MVC framework at ALT.NET. I took special care, while watching the video, to answer one question.What, if anything, can MonoRail learn from MS MVC?

  1. Routing – RoR and MS MVC treat Routing as a first class citizen. Routing in MonoRail is an after thought and it shows.Why is first class Routing a big deal?
    • DRY – Tight integration between the routing engine and URL generation allows URLs to refactored easily and safely.
    • Testing – Testing routes, in MonoRail, requires an end-to-end test. If routes were first class objects, then routes could be tested in isolation.
  2. Typed PropertyBag – Typed PropertyBag is not the default behavior in MS MVC, but it is supported.Why is a Typed PropertyBag important?Contract – A Typed PropertyBag communicates the contract between the controller and view. Without this contract, refactoring anything in the view or the controller is difficult and error prone. We enforced a contract by implementing Advocates, but it would be nice if it were supported by MonoRail.

What are your thoughts?

C# Puzzlers: The Joy of Lists

My quest to take a “deep dive” into C# has led me to this variation on the ShortSet Java Puzzler. I translated the ShortSet class, described in Java Puzzlers, to C#. C# does not have a Set class, so I used List.

public class ShortList{    public static void Main(string[] args)    {        IList<short> l = new List<short>();        for(short i=0; i<100; i++)        {            l.Add(i);            l.Remove(i - 1);        }        Console.WriteLine(l.Count);        Console.Write("Press any key to continue . . . ");        Console.ReadKey(true);    }}

What gets printed to the console?Well… this code does not even compile. List defines the Remove method as Remove(T value). The compiler correctly tells us that i - 1 is an int. We cannot remove an int from a List<short>.The Java compiler correctly allows this to compile, because Set’s remove method is defined with Object as a parameter. Remove is defined this way for backward compatibility.Does C# always behave as expected?My second attempt at a “deep dive” results in another boring/pointless example. Does C# not have puzzler material? Is it really that well designed?Where are the C# edge cases?


I want to thank the person that added my blog as a reference for MonoRail on Wikipedia. I am flattered.Thanks.

C# Puzzlers: Elvis Lives

I was a Java instructor earlier in my career. The best thing about being a Java instructor is you really learn Java. I knew Java as well or better than anybody while I was teaching. I quickly learned that students ask the best questions and they forced me to truly understand Java.A group of developers, at work, started exploring Java Puzzlers. Java Puzzlers reminded me about how well I knew Java and how I don’t have the same depth of knowledge in C#. I want/need the same depth of knowledge in C# as I do in Java.I am currently working my way through the Java puzzlers in C#. This post is the result of the first puzzler. This puzzler was written by Jeff Grigg.Given the following: What will be printed to the console?

public class Elvis : King{    public bool IsAlive = true;    protected override void Kill()    {        IsAlive = false;        Console.WriteLine("The king is dead.");    }    public static void Main(String[] args)    {        Elvis elvis = new Elvis();        if (elvis.IsAlive)            Console.WriteLine("Long live the king!");        Console.WriteLine("Hit enter to continue....");        Console.ReadLine();    }}public abstract class King{    public King()    {        Kill();    }    protected abstract void Kill();}

It turns out it only prints

The king is dead.

This went against my instinct. Why? The same puzzler prints

The king is dead.Long live the king!

in Java. Java does not execute public bool IsAlive = true; until after the super constructor executes.This obviously does not happen in C#. C# must initialize all member variables before executing the constructor. This behavior seems to be more obvious than the Java behavior. I guess I should try not to think so hard when I am working through these puzzles ;)The code for the puzzlers can be found in my svn repository.https://esterline.devguard.com/svn/code/csharp_puzzlers