Tuesday, 29 April 2008

Using Rasta #2 - Rasta in it's simplest form

Lack of time and sleep pushes me to be very lazy and present only the most trivial example of what Rasta was built for. Hopefully the future editions will become more interesting.

Rasta does many things, but one of the things you can use it for is Url rewriting for webforms. Simply declare the following in your global.asax file:

using (RastaConfiguration.Manual)

{

    UriSpace.HasTheUri("/home").ForThePage("~/pages/default.aspx");

}

And if you want to provide a url that matches a specific language, just expand this a bit:

UriSpace.HasTheUri("/accueil").InLanguage("fr").ForThePage("~/pages/default.aspx");

This will automatically set the language for the current request in the correct language, while still going to the same aspx.

Another fancy thing in Rasta's manual declaration is the using block. All the configuration needs to happen within that block, and is only applied when you exit the block. The fluent api is built using a chain of language elements that form a sentence. Each element you add to a sentence either replace it's predecessor in the list of sentences, or initiate a new sentence, and each fully-formed sentence will get called whenever the Dispose method is called on the object returned by the call to RastaConfiguration.Manual.

How do sentences get added? When you enter the block, the new object returned by the Manual property sets a CallContext that stores that list. When it is disposed, it calls the chain of sentences to configure itself. And finally, it makes most of the routing structures read-only to optimise them (a typical example is building a read-only tree of the Urls you can use for a site in a structure that is more efficient than if it was write-only).

That also means that trying to apply a configuration at runtime to replace the existing configuration will only succeed when the whole of the operation succeeds. This happens by only writing to a new copy of the configuration data, and committing the write if no exception happened. If you got the configuration wrong, the previous configuration will happily stay on to continue serving request.

Saturday, 26 April 2008

Migrating to IIS7

Over the last couple of weeks I've been upgrading my Rasta framework to support IIS7. Here's the highlights:

  • I automatically detect the base Url address for a site based on the application path and the first requested Url, at which point I create all the routing tables. This used to be at the end of the configuration code that used to run in Application_Start.
    You cannot access HttpContext.Request from there anymore, so this has to change. Right now I delay the discovery at a later stage (on first request), but this solution only support a single domain per web app.
  • DefaultHttpHandler is not supported anymore, so I have to implement the equivalent functionality for when Rasta doesn't recognize a Url and try to delegate to a registered handler. This probably won't land for a couple of weeks.
  • More Url processing weirdness than IIS6, with no support for unencoded + in paths. This goes against the RFC for uris that specify quite clearly that segments in a path should be opaque until handled. IIS considers it has the right to handle them and crashes. This is seriously limiting our ability to provide a virtualized Url space on a web site (any character not supported by the file system will automatically crash the request before a handler is called, as asp.net tries and do a MapPath, even when you percent-encode the special chars. I consider this to be quite unacceptable and limits my choice of Uri.

I also ended up with some weird issues where upon building, the ccnet machine would see its access to web.config denied, and the only solution is to go and copy the files manually the first time around. I'm still trying to investigate what happened there.

Wednesday, 23 April 2008

Talking about Linq2Sql and Expression Trees tonight

If you're in London, why not join us tonight to celebrate Visual Studio 2008 and .net 3.5 releases at the London .net user group? We'll be discussing some of the new features in the bits, and I shall be presenting some useless code that shows integration testing and fluid database design using Linq2Sql, with some expression tree goodness.

Monday, 21 April 2008

Announcing the Alt.net London Beers event

[Update: The event has been moved. See the latest location and stuff here]

Many people are keen on continuing the discussion that was started by the alt.net conference. While the altdotnet-discuss yahoogroups mailing list has been very active, I feel that much more can be achieved when meeting and seeing people.

It's also nice to be surrounded by like-minded people that face the same challenges you do when you try to promote alt.net ideas around you, to your colleagues, your employer, your sister... And of course, being surrounded by very bright people that love what they do and spend their free time getting better at it is fantastic.

In the spirit of providing something less grandiose than a conference and more personal than a mailing list, I hereby declare created the Alt.net London Beers. It's an event, in a pub, with whoever wants to come, subject to be decided on the day. Bring your laptop if you want, but more than anything bring yourself, and let's get the conversation continuing.

This is an experimental regular meet-up, and who knows, if it's successful, we could do it a bit everywhere. Make this a success and come along!

Using Rasta #1 - An introduction

Rasta has many meanings, but for the purpose of this blog, it is the REST Architecture Solution Targeting Asp.net. I've written this framework for one of my clients, and I'm in the process of trying to get the rights to open-source it and deliver it to the world. But as many things, it takes a lot of time.

That said, I've been wanting to blog about it since I started working on it, so now is as good a time as ever to start showing some bits on how to use it. It will let my beloved readers criticize the way the API is built, which will let me involve it for the better, and will also serve as a reference point for my client's employees to have some sort of reference on how the framework works.

Rasta, in essence, is a framework that lets you think about your site in terms of resources, how they are accessed, and how representations of such resources get served to clients. Let's compare this approach with other approaches we've seen over the years.

WebFroms

In this model, your Url is bound to your page. Because of the post-back model, any interaction with the system is done as units within the webform. http://example.org/Customer.aspx provides a view of your customer, but is also where data gets posted back. The posting of the data itself can be either about a customer, or about a button, or about an event one of the webcontrols can trigger. It can be a bit of anything.

This has a couple of very bad consequences. Only the asp.net framework can post data to /customer.aspx, because it's the only one knowing the format. This makes testing webforms terribly difficult, and patterns like MVP only solve the problem at the unit-testing code level, leaving a lot of code non-testable. It also makes integrating with other systems more painful than it should be. And it doesn't leverage hypertext in any way, because state is transferred across postbacks through either the session or the viewstate.

In this model, the resource is the page, and does many things. It's completely unrestful.

The MVC model

A lot of noise is being made about the new asp.net MVC framework. MVC as a pattern solves some of the issues introduced by webforms. Your Url is bound to a controller that receives the request, act upon it and send you to a view based on the result of the operation. This solves the unit-testing issue. To a certain extent, it also solves partially the integration issue, as your controller can act upon the http operations (GET PUT POST DELETE etc...).

That said, your Url is bound to a controller's action, so you would end up most of the time with a url looking like http://example.org/Customer/GetCustomer. You're mapping one web action to an operation. While you can override that, it's not the default. Another issue that makes it unrestful is the lack of leverage of hypertext, as links are not used for anything meaningful unless you implement that yourself.

In this model, the resource is the controller, and does quite a few things. It's up to you to define the semantics. It's quite unrestful.

The WCF Rest model

WCF in 3.5 has some support for something quite similar to the model provided by MVC. Your WCF service can be mapped to a specific Url and encoding (xml and json), and it will support a Get and a notion that team came up, an invoke. The rationale being that there was not that much of a different meaning between POST/PUT to justify mapping them differently, and that they all end up invoking a service.

This is a service-centric view that maps very poorly with the web. You're tying your Url to a service operation, and limit your representations to the two kinds provided by WCF. Its great for unit testing, not so much for the web.

I'll also have to question any team having spent that many years providing an abstracted toolkit that lets you not think about the plumbing (although this is a very big white lie) trying to implement a REST architecture which is, by definition, about the plumbing, leveraging Http verbs and hypertext.

In this model, the resource is the service, and does something. It's quite unrestful as well.

The Ado.net Data Services model

Formerly called Astoria, ado.net data services is the most restful of the APIs Microsoft is working on.

With Astoria, you map a Url to an entity (ado.net entities), and you interact with those entities based on AtomPub, which is quite restful. That said, it is about exposing your existing entities model on the web, and support for POX / POJson has been dropped from what I understand.

It does leverage hypertext (because AtomPub does), and it does have some content type negotiation. The big issue here is that it doesn't integrate with any of the previous models we've seen, and is yet another API that wants to have the Urls in your web application to itself. It supports data, and data only, so you won't be able to leverage an asp.net MVC page to serve a resource as text/html, and still support application/json for clients that want this format.

In this model, the resource is the entity, and you can do restful things with it. But it only deals with one aspect of developing rest applications, and has poor integration with the other components Microsoft is developing.

The Rasta model

Rasta takes a radically different approach. Every Url is mapped to a resource. In other words, http://example.org/Customer is mapped to a resource of type CustomerEntity. Each resource type can have many resource handlers that are responsible for acting upon a resource in a certain way. This could mean retrieving a resource, updating it, etc.

When you access a Url to get to a resource (called dereferencing), the first step Rasta is going to take is to try and locate which handler can be used to access the resource, based on the request you made. For example, http://example.org/Customers/{name}  is a Url that would associate a meaning of name with a value to the handler. From that name, the handler would return an instance of the resource (an instance of CustomerEntity). In other words, a handler is responsible for dereferencing a Uri based on a request to get to a resource, and to act upon it if required.

And that's it. The handler is not involved at any point in how the request is processed or how the response is sent to the client. This is the responsibility of the codecs.

A codec is a component that, to simplify, convert a Content-Type sent on the wire to an object and back. In essence, if your handler returns an instance of CustomerEntity, the codec will be able to convert it into an xml stream representation, or whatever wire format the codec supports. Out of the box, the current Rasta svn repository has support for webforms (for html rendering), json and xml, and I have some working code supporting AtomPub, atom, rss and even support for some WebDav, although all this is mostly prototype quality.

In this model, the resource is the resource, and its representations are handled by codecs that are loosely coupled from the resource itself. You could see it as an application of the semantic web, but based on types and objects. In other words, it works and is good enough.

Conclusion

Rasta's architecture brings quite a few benefits:

  • Loose coupling between the representation of a resource and the code that does useful stuff with it.
  • Automatic support for content-type negotiation, letting the client decide what is the best format to receive a resource in.
  • Resources don't change, but implementation of the handlers can
  • Adding new content-types is independent from the rest of your code
  • Adding things like AtomPub becomes very easy
  • You have only one way to do both your html representation and the computer-friendly ones.
  • Oh, and it's still compatible with webforms so you can retrofit existing work in the same site
  • And as a nice to have, it runs on standard .net 2.0.

There are many other parts to Rasta, but those are the basis of what it is, why it was built, and why I'm so thrilled about it.

Sunday, 20 April 2008

An extension method, just because I can.

Going to the dentist is an awkward experience. You know you have to use their service or your teeth will rot, but the experience is just not enjoyable.

That's how I feel about string.Format. I use it all over the place, but find it incredibly out of place. Thanks to extension methods though, I can propose a nicer syntax. Here's a snippet from a site I'm building for one of my clients, using my rasta REST framework and linq2sql.

[HttpOperation(HttpMethod.GET, ContentType=new HttpContentType("image/*"))]

public ResourceOperationResult GetMovie(string filmName)

{

    var movie = _movies.FindOne(movie => movie.UrlTitle == filmName);

 

    if (movie == null)

        throw new ResourceNotFoundException

        {

            Message = "The movie {0} wasn't found in the database.".With(filmName)

        };

 

    return new ResourceMovedTemporarilyResult { NewResourceUrl="/library/tempfilm.jpg" };

}

Notice the extension method there? I just find it sweet. Here's the very simple extension method.

public static string With(this string text, params object[] values)

{

    return string.Format(text, values);

}

There you are, a shamefully simple extension method, just because I can!

Computer naming scheme

While looking around for nice visual studio color schemes, I stumbled upon Commonality's Naming your computers post. I'm happy to know I'm not the only one doing that.

All the computers in Caffeine IT are named on the theme of light. Here's a rundown.

  • Luciole, Lueur: decomissioned machines I had when in France
  • Aurore: A dell machine that I am now disposing off, mainly because I can't be bothered to rebuild it.
  • Tinkerbell: my main dev laptop, MacBook Pro running Vista Ultimate.
  • Photon: The MacBook Air running Vista Ultimate.
  • Lumiere: The Sony TP1E that is the test machine for my yet to be released Vista media integration software, and connected to the big LCD screen. Only way to test 3-feet user experience is to set-up a machine with no keyboard and no mouse, relying only on the remote. Running Vista Home Premium.
  • Blackhole: The custom-built Xeon machine that holds my dev environments and the multi-terabyte RAID5 array. Running Windows Server 2008 Core with Hyper-V
  • Glimmer: The build server, web uat environment, and other bits and bobs (server 2008 Standard)
  • Pulsar: The backup server (windows home server)
  • Hubble: A video streaming server on Windows Server 2003 R2.
  • RayOfLight: The iphone :)

And before you ask, of course I need that many. :)

Thursday, 10 April 2008

Changing my blog subtitle

You know you're starting to be read too much when people get passionate about name-calling you. I'm very proud it is now happening to me, as Anonymous has proved in the first aggressive comment I've had on this blog.

That said, Anonymous said the sub-title of this blog should be renamed to Ramblings of a self-congratulatory, self-proclaimed, egotistical doofus.

So this is now my new tag line. Whatever you think of me, you're reading, so that's a communication channel open. If you disagree with me I'll probably learn something from you. If you agree I'm pleased I am not on my own in my rambling.

We're all on a journey. I'm pleased mine involves anonymous and prominent people questioning my opinions. It makes me a better geek, and that is what this blog is all about.

Saturday, 5 April 2008

referrals from internal wikis

Just found some referrals from wikis used internally at a previous client, full with the reference of the page, project code-name, etc.

I wonder if anyone realizes how much information you're disclosing by just linking...

Friday, 4 April 2008

IoC - The container is not a carpet, it's the floor

[Update: Removed references to the company, because while I may rightfully be bitter, it is irrelevant to the content of this post, and I don't want the two issues to be mixed. Apologies to my readers.]

Jason Gorman, who I've had the pleasure of crossing the path of at one of my clients, is asking an interesting question about containers: are we hiding sweeping dependencies under the carpet?

Questioning the value of a container is a very recurring topic amongst developers that haven't been ripping their benefits, and I think it deserves a post in its own (that, and the fact that Jason's blog doesn't seem to let me post comments.)

First comes first, you have to think about what a container brings you, as it does bring you several things.

  1. Dependency injection
    This relieves you of having to chain objects that depend on each others, as the container is responsible to get a reference to each component your component needs.
    This has the added benefit of enforcing the declaration of your dependencies in the component's constructor, making tracing dependencies much easier in a code review. It's also a good thing for discoverability of the code during test, as knowing what is required for your component to be put under test is very much in your face, on the first line, when you create the object. And that is a good thing.

  2. Inversion of control
    Your code no longer has to create the object to use it. You just don't have to think about it when you write your code. Of course, that doesn't mean you can ignore how the object is built, but this enforces a separation of concern: the consumer of the object doesn't have to know a whole lot to consume, and the creator of the object doesn't have to know much about the use of the object.

  3. Lifetime management
    Because you no longer use new, you can rely on the container to decide which object it gives you and where it exists. That means that asking for an IMyAppContext will retrieve the object from the HttpContext for you when it's needed, with no HttpModule or painful initialisation code anywhere.
    And if you work on composite applications, you can create for the container a new way to store the objects, be it per component, per form, etc. You write that code once for the container, and never again will you have to care about the how.
    Code reuse is a good thing.

  4. Centralized component management
    This one is less obvious but makes a lot of sense. When you want to know how an object is initialised and where, it's centralized in one place. One file gives you all the dependencies that exist in the system.
    This also makes it possible to run code in your integration tests (or as a post deployment task) to ensure all dependencies are resolvable, and this, again, is a good thing.

  5. Lower the cost of change
    This one becomes obvious when you've been using containers for a few iterations. Taking on a new dependency is fantastically easy: add a parameter to the constructor and you are done. No consumer will ever have any code to change. Less code to change makes me happy.

There are many other things a container can do, but those points are shared across Unity, StructureMap and Windsor (I specifically ignore spring.net in my analysis, because I have next to none experience with it), and even by the COM+ catalog.

Jason probably knows each of those points very well. His doubts are about the centralized place in which those components are declared.

To a certain extent, I will agree on a small thing. Storing your dependencies in an xml document is not the most natural way to handle them, especially when you start playing with generics.

In the project I worked for in that unnamed media company, I built a small object builder as I was  asked not to take more dependencies on external frameworks, hence I couldn't rely on a container. The dependencies were stored in the config file, and object instantiation is manual (no DI there, just IoC). A super-factory was a good first step to start decoupling components and get more visibility on what was going on in the code. But it's not as nice as having DI, and certainly not nice having types written in xml.

But you don't have to keep these things in config files. If you want to keep your dependencies as part of your project's code, go for it. Windsor has AddComponent, SturctureMap a fabulous Fluent api.

And if you don't want writing all that code, you can use Binsor for some boo love.

What I will strongly disagree with is part of Jason's analysis. A container doesn't hide dependencies from the compiler, because it can't. Component A implements interface A in assembly A. Component B depends on interface A and lives in assembly B. As far as I understand it, they all get compiled by a compiler. They are linked so dependencies are resolved when compiling the construction. That's why you declare your dependencies in the constructor!

But where Jason is right is highlighting that the configuration file is a dependency, and should be tested as such. This is exactly why you should have a stage environment that reproduce your live environment, and run your integration tests there. If your test don't detect a missing dependency declared in your config file, your tests are badly written or not extensive enough. You're just blaming the tool, blame the developer.

One thing that seems to be a common misconception is that you should know about your physical dependencies, aka knowing that component A depends on component B. This is the wrong way to look at the problem. Component B should depend on a contract it has for a service it's being provided. The glue between components is the container, and the guarantee that this works fine is your test. As for understanding your dependency graph, that's what code coverage and NDepends are there for. Anything else is only relevant to graphs people want to put in visio, which I would argue is irrelevant.

That said, it wouldn't take much work to trace those dependencies by asking the container. Maybe a day of work if you're into graphs. But if your dependencies bite you, you have a much bigger problem than tracing graphs, and that's usually a collapse in applying what is required for containers to work well: contracts, single responsibility principle, high cyclomatic complexity, poor code coverage, no integration tests, and self-containment of components to reduce complex interactions...