Ayende @ Rahien

It's a girl

Castle Igloo

Castle Igloo (ppt) is a very interesting experiment in bringing more MVC goodness into the WebForms. I have to say that when I dove into the code, the ideas that Gilles Bayon (no blog :-( ) had there blew my mind away. I always believed that trying to do MVC in ASP.Net was possible, but fairly awkward.

My main issue with this was always that I always had to do extra work in both the view and the controller in order to make this work, and I never felt that I really got the flexibility that I can get in MonoRail. Here is an implementation of MVP from Phil Haack, as an example. The problem here is that I still have the following problems:

  • I need to define an interface for the view, which will likely contains a lot of data passing parameters.
  • My controller is dependant of that interface, if I want to test that, I need to mock/fake the interface before I can use it, not a big deal, but not as trivial as just dowing new MyController() in the test.
  • My view implementation is dependant on the controller, and is actually responsible for creating it.

I may be spoiled by the pure MVC that I can get in MonoRail, but I really want that back. As I said, I didn't believe that I could get nearly the same experiance, but Gilles has proven me wrong. [Forehead still hurting from that smack]. You can get the code here, I suggest taking a look and seeing what is in there.

Here is a small part of the controller:

public class PatientController : BaseController

{

 

    [Inject(Name = "doctor")]

    public Doctor Doctor

    {

        set { _doctor = value; }

    }

 

    [Inject]

    public IList<Patient> Patients

    {

        set { _patients = value; }

    }

}

And another small part of the view the view:

public partial class Index : Page

{

    [Inject]

    public IList<Patient> Patients

    {

        set { _patients = value; }

    }

}

Notice that the controller doesn't care about the view at all. How does it works? Well, there is some magic behind the scenes, but basically, the controller can register an object in a registry, and when it is done, that object is populated to the view transperantly. Here is the method on the controller that gets the list of patients.

public virtual IList<Patient> RetrievePatients()

{

    IList<Patient> patients = _patientService.RetrievePatients(Doctor);

 

    Scope["Patients"] = patients;

 

    return patients;

}

The view can either call this directly, or rely on getting the value from the scope:

protected void Page_Load(object sender, EventArgs e)

{

     if (!IsPostBack)

     {

            GridViewBlog.DataSource = PatientController.RetrievePatients();

            GridViewBlog.DataBind();

     }

     else

     {

            GridViewBlog.DataSource = Patients;

            GridViewBlog.DataBind();

     }

}

In the second case, we got the value from the scope automatically.

What we gained:

  • No need to define an interface for the view.
  • Controller completely seperated from the view, easier testability.
  • The view is still tied to the controller (since it needs to let it know about things such as button clicks, etc), but trying to avoid that is something that isn't really possible with WebForms (but you are welcome to prove me wrong).
  • Strongly typed support for passing items from controller to view :-)

I fear that I am not really doing much justice to Igloo, mainly because I am still in the process of grokking it. There are still several things there that I need to figure out. There is an automatic navigation part that I am doubtful about (I don't see the usecase, actually). I think that I will try and get a small sample with just the bijection support (the automatic injection and outjection of properties from both controller and view), just to see how I can make this work.

Comments

Ayende Rahien
02/03/2007 08:00 PM by
Ayende Rahien

My response:

http://www.ayende.com/Blog/archive/2007/02/03/Why-seperating-the-View--Controller-is-important.aspx

S
02/08/2007 05:59 AM by
S

I could not get the code to build

Ayende Rahien
02/08/2007 06:01 AM by
Ayende Rahien

Please post a question on the caslte-dev group, about it.

sternr
03/01/2007 11:48 AM by
sternr

I don't like the Igloo's injection approach,

I think object injection should not be implemented as properties but as method parameters.

Every controller is a set of services (methods), and by their nature some method require different properties, but each has the ones he must accept in order to operate.

What I'm trying to say is, that you cant know on each call which properties are assigned and which aren't - the assignment is not explicit enough...

Just my 2 lira's...

--sternr

Jeff Brown
03/17/2007 08:47 PM by
Jeff Brown

How about code generation?

There's still too much boilerplate in here that could be omitted without any confusion. If you can hook ASP.Net so that code-behind can be written in Iron Python then it should be possible to make it use other dynamic classes. Basically make the Page be abstract and then dynamically derive and fill in the blanks.

I like Stuart's event publisher/subscriber suggestion too. It keeps the controller in the loop. The forwarding hooks to the controller could probably be implemented generatively.

Comments have been closed on this topic.