Redmine - Trac without the Suck

Posted by Andrew on July 17, 2008

Looking for a free-as-in-beer issue tracker, forum, and generally flexible project management web application? If so, you could do a lot worse than checking out Redmine. We’ve been using it for a few days at work and I have to say it might be the nicest issue tracking system I’ve ever used.

Here’s the high-level feature list:

  • Multiple projects support
  • Flexible role based access control
  • Flexible issue tracking system
  • Gantt chart and calendar
  • News, documents & files management
  • Feeds & email notifications
  • Per project wiki
  • Per project forums
  • Simple time tracking functionality
  • Custom fields for issues, projects and users
  • SCM integration (SVN, CVS, Git, Mercurial, Bazaar and Darcs)
  • Multiple LDAP authentication support
  • User self-registration support
  • Multilanguage support
  • Multiple databases support

Out of the box it works just great, but it’s also extensible and modular and thus easy to customize to your particular requirements. It’s Rails-based too, so diving into the source is pretty easy. We’ve customized how it receives emails and themed it up a little.

Kudos and thanks to the Redmine team for a great piece of software!

Inflector.NET

Posted by Andrew on July 05, 2007

If anyone is looking for it I’ve created a dedicated page for my port of Rails’ inflector.

ASP.NET Web Forms vs. MonoRail

Posted by Andrew on March 20, 2007

Castle MonoRail has been getting more press than usual lately due to a recent Scott Hanselman podcast and news coming out of the recent MVP conference about the possibility of Microsoft offering their own Model 2 implementation as part of ASP.NET. Here are links to just some of the interesting discussion so far:

JD asked me about my views on ASP.NET Web Forms vs. MonoRail so here goes:

ASP.NET

First of all, I have to say that I agree with the many others who point out that Web Forms is a bit of a “leaky abstraction”. Basically, the Web Forms programming model attempts to simulate stateful “Forms” in a stateless web environment. This approach can lead to several practical problems, most notably:

  • Unnecessary plumbing required to create the abstraction. Think View State, Control State, events, postbacks, strange ids etc.
  • Consequently, poor performance due to the extra baggage. BTW, if you are using an editable DataGrid and your application isn’t a spreadsheet - please stop :-)
  • Loss of control of HTML generated and page weight. Yes, I know about extenders but this is still extra work.
  • The model obfuscates the “real” nature of the web: GET, POST, parameters, query strings, Post-Redirect-Get pattern etc.
  • Consequently, the average developer finds it harder to debug when there’s a problem: The very complexity introduced to make Mort more productive actually kills him when things (inevitably) go bad.

That said, WebForms is a rich platform and like any technology has it’s own sweet spot. As an example, we recently developed BackgroundMotion, a WebForms application commissioned by Microsoft as an example of how to rapidly build a composite web application using the latest MS toolsets. Over the past few weeks it has served as the centerpiece of our presentations at the recent Microsoft NZ Tech Briefing events. The majority of the build was completed by three developers over a three week period. BackgroundMotion is by no means a “smoke and mirrors” job either. It is a proper layered ASP.NET web app incorporating:

  • ASP.NET AJAX
  • The Web CAB, ObjectBuilder, MVP and Application Controller
  • LINQ to SQL
  • A proper Domain Model
  • Declarative two-way object data binding
  • Validation Block
  • Unit tests including mock IContext and IRepository<T> with in-memory database
  • Standards compliant, cross-browser HTML

As someone who was an early adopter of RoR and is a contributor to MonoRail, I was reasonably happy with the BackgroundMotion turned out. Yes, it’s not perfect, but some of the newer tools like the Web CAB really promoted a solid architecture. Overall, the toolset we employed allowed us to move pretty fast whilst establishing and building on a maintainable (a.k.a testable) architecture.

MonoRail

MonoRail is RoR inspired web framework the runs on the ASP.NET infrastructure. It’s primary advantage over Web Forms is that it’s MVC implementation encourages a solid architecture by leveraging proven web architectural patterns - basically Front Controller, Application Controller, and Template View. A MonoRail application will have an inherently “good” architecture (which is not to say it can’t be corrupted, but out of the box it’s pretty solid.) An important thing to note is that MonoRail, like RoR, achieves this without shielding the developer from the underlying mechanics of the web. In order to understand the advantages of MonoRail, we need to understand the advantages of the aforementioned foundational patterns.

Front Controller

A controller that handles all requests for a Web site

MonoRail implements the Front Controller pattern using a custom HttpHandler. For a given request the handler determines which Application Controller and action to invoke. Some of the advantages of this approach are:

  • Separation of URI from actual handler. Spin-offs from this are things like friendly URLs, “routing” etc.
  • Ability to plug-in interceptors before/after/around the request. In MonoRail these are called “Filters” and can be used to implement things like authentication, logging and other such “aspects”.
  • Ability to do more advanced things like “Dynamic Actions

Application Controller

“A centralized point for handling screen navigation and the flow of an application”

The “C” part in MVC, controllers in MonoRail can be thought of as Application Controllers. A controller consists of a number of “actions” each of which is the handler for a particular request. An action method may interact with a model and render a view, or may choose to redirect to another action. Such flow decisions are made before any thought is given to rendering anything. This is a key point of difference with Web Forms: The view (page) is in no way concerned with anything apart from how to render itself. As I see it, the main spin-offs from this clean separation are:

  • Potential for easier testability of controller logic outside the web context
  • Consequently, improved maintainability
  • Ability to render different views for the same request (see below).
  • Better organization of code into logical groupings
  • Ability to do intuitive object data binding (parameters on action methods for example)
  • Isolation from HttpContext, and therefore ability to extend it. Think Flash in RoR, MonoRail

Template View

“Renders information into HTML by embedding markers in an HTML page”

MonoRail uses a Template View pattern with pluggable view engines. This pattern results in completely decoupled, “thin” views which is a really good thing. It guarantees almost complete control over the rendered output and means that a single controller can can handle requests based on content type by using different view engines. I think this is something that the RoR guys grokked first after they started noticing DRY violations with respect to rendering different output formats like RSS, JSON, XML etc. This is a lot of what’s behind their recent work around REST and Resources. For example, the request: GET “http://foo.com/member/get/1″ is really a request for a member resource with id=1. It is abstract and should not contain any details about the actual result format desired by the consumer. The consumer instead specifies this using some kind of agreed-upon content-type header or similar. Upon receiving a request, the controller can determine the requested output type and invoke the appropriate view engine to render the response. Separation of the view engine from the request handler is essential to achieve this flexibility.

So what do proponents of Web Forms have to say?

Well, some have commented that Web Form’s “eventing and management of control state” is a feature that counts against MonoRail’s Template View approach. I would disagree and simply point out that these are merely artifacts of Web Forms itself. They do not solve any inherent problem in web development. MonoRail doesn’t have the notion of controls or events, so how can not managing them be a problem? :-)

It must also be noted that MonoRail, in it’s current state, is far from perfect. For example, one of the commonly cited advantages of MonoRail over ASP.NET Web Forms is testability. However, Hammett, Castle’s main man recently had this to say about Controller testability:

“The TestSupport component offered by MonoRail is totally flawed. It is useful for us, as we can use it to test how MonoRail is correctly integrated with the ASP.Net API, but it useless for any enterprise project.”

Other problematic areas include:

  • Documentation needs work. It’s open source after all :-)
  • May be harder for Morts to grok. Like any sharp tool, it must be wielded carefully.
  • Not Microsoft. Therefore harder to sell into the enterprise and harder to support
  • Tool support not as strong, primarily with respect to working with views.

As usual, at the end of the day both ASP.NET Web Forms and MonoRail have there place as they are different tools suited to different problems, scales and skill-levels.

On JD on Rails

Posted by Andrew on June 08, 2006

JD has posted about five four problems he sees with RoR. In this post I'll try to address each of his concerns.

Issue 1 - Scaffolding

If you think scaffolding is a "compelling" RoR feature then you have really missed the boat. Scaffolding is a minor feature of RoR in comparison with ActiveRecord for example. Scaffolding is beneficial primarily as a teaching aid for people new to the framework. Rather than pick on scaffolding why don't you choose one of Rails really nice features (like ActiveRecord) and contrast it with the approach you would use in .NET? Or maybe explain why you think the Page Controller pattern in ASP.NET is better than RoR's Front Controller.

Issue 2 - Scalabililty

Come on dude. This argument is really pretty tired now and I'm surprised you would partake in such FUD mongering without actually doing some research. A simple Google yields numerous discussions - Of which New Take on Scalability is a decent one. To paraphrase:

Scale to what? You are asking a meaningless question. Be specific like: Will is scale to 2.5 million requests per day? Uh, yep.

Remember, developer time is now a much more precious resource than hardware and this is only likely to continue. The best frameworks and languages are the ones that realise and optimise for this.

You also need to ask yourself: Why are you so obsessed with scale? From the aforementioned post, Alex answers:

That’s an easy one: everyone wants to believe they are going to be “big.” They want to use tools that let them indulge in that belief, however statistically unlikely their eventual bigness may be. Alternatively, they believe they are in fact already “big,” not understanding how massively unbelievably big they would have to be for scalability to really matter."

Finally, I like this quote from Koz:

"… But asking whether something ’scales’? It reveals more about the questioner than any answer would about the framework."

Issue 3 - IDE Support.

Um, is this not a general Ruby issue and not a specificly RoR one? Once again, be specific. What features are you missing that are not available in say something like Komodo or ArachnoRuby? They both have debugging, projects, intellisense etc. and are faster and more lightweight than VS.NET. It's not really about this IDE or that editor, but more about "have you mastered it?" In other words, I suspect that someone proficient in TextMate would go faster than an average VS.NET user.

Issue 4 - Frequent Releases.

Not an issue. Agile developers favour frequent releases because they reduce the feedback cycle and incremental change is easier to manage. RoR provides the necessary versioning mechanism (freezing) to allow you to pin your app against a specific version. It is hardly the framework's fault if the developer chooses not to use it.

Issue 5 - Scalability - again.

See 2.