Saturday, 23 August 2008

Proposing a syntax to attach behaviors to html elements

ScriptSharp, like asp.net AJAX, has the notion of behaviors, javascript code that can attach itself to DOM elements and change their, well, behavior.

As part of my spike on ScriptSharp (and I’ll have to admit having spent way too much time on it to still be called a spike), I’ve built a simple container that automatically resolves and binds behaviors to DOM elements, to reduce to a maximum the amount of inline code required within my generated pages.

The one thing I went round and round about was how to declare in markup that binding. Here’s a few solutions I tried or seen proposed through various tools.

<div style="behavior: url('myBehavior.htc')" />

This is something introduced in ie4, but it breaks the CSS standard *and* htc are only recognized by Internet Explorer. No good to me.

The next contender is…

<input type="text" id="searchText" />
<input type="button" id="searchButton" />

<script type="text/xml-script">
  <page xmlns="http://schemas.microsoft.com/xml-script/2005">
    <references>
      <add src="ScriptLibrary/Atlas/AtlasUI.js" />
      <add src="ScriptLibrary/Atlas/AtlasControls.js" />
    </references>
    <components>
        <textbox id="searchText" /> […]

…xml-script, and was originally presented early in the life of asp.net AJAX (back when it was called ATLAS). This is awfully verbose, and worse than that it won’t ever validate in non-xml languages (aha HTML 4.01 or XHTML5). The same is true of the proposed changes in asp.net AJAX Futures, which uses namespaces everywhere even though they’re not allowed in non xml renderings.

[Update: As Simon Pieters correctly points out in the comments, this syntax would indeed be compatible with HTML5 (the non-xml serialization one), because the definition of CDATA sections has been modified to include anything not including the closing tag. Hence what is after <script> can be anything that is not </script>. This redefined definition of a CDATA element is not something the XML specification agrees with however, which means that in all languages, aka XHTML 5.0, XHTML 1.1, XHTML 1.0 and HTML 4.01, you need to enclose the content of the script tag in a CDATA section, aka <![CDATA[ … ]]>. This makes HTML5 the only rendering with which xml-script would work. I may have misread some of those specs however, so if I have please comment and I’ll update and buy you a beer.]

In choosing how to map behaviors, I had several goals:

  • declare the behaviors contextually within an element,
  • being able to use the exact same notation for both HTML 4.01 (the SGML language), XHtml 1.0 and 1.1 (the XML language) and Html 5 (both the whatever it is format that is not sgml anymore *and* the xml language, as both exist)
  • being able to pass additional customizations and parameters specific to an instance
  • Not look too out of place.

I initially settled on an extension to the way content type definitions are expressed:

<div class="behavior/graphicscroll;horizontal=true;vertical=true;">test</div>

This says, ask the behavior family to add a graphicscroll behavior and pass it values for horizontal and vertical. All was good and I was happy with myself. For a whole five minutes.

Then you realize that while that syntax works like a charm, it is invalid in Xhtml 1.1, because the class attribute was redefined to be of type NMTOKENS, where the previous version had a type of CDATA. This is a serious breakage for content out there, and I wonder what the reason for this is.

The other issue I had with this is the need to declare the full syntax for each element I wanted to use, and I really wanted to leverage CSS selectors. One solution I would have wanted to use was to simply extend the CSS stylesheets with custom css attributes. This would have then looked like the following.

    <style type="text/css">

        div {

          -rasta: "behavior/graphicscroll;horizontal=true;vertical=true";

        }

    </style>

The syntax just felt very unnatural. And worse than that, the CSS validator doesn’t validate CSS with vendor expansions, even though they are defined as such in the specification.

After twiddling around endlessly, I’ve settled on defining a css-like language, behavior stylesheets, without some of the restrictions of the existing CSS. I now have this code:

    <style type="text/vnd.rasta.bss">

        div

        {

          behavior: graphicscroll {

              horizontal: true;

              vertical: true;

            }

        }

    </style>

The  selector syntax is simply the CSS one, which means you can combine and match them in the same way you would define your stylesheets. The properties however are dynamic, with the first level name always matching a family of components (implemented as a loader) with a value matching the component, and a sub-group letting you define properties on that component.

You’ll notice I mentioned my first goal was for this to be contextual within the element. Because you’re still using selectors, nothing prevents you from declaring a value in your class attribute and do your selection on that. The same of course goes for ids.

Time will tell if this is as compatible with current UAs as it could be, and I have the feeling it will be ignored when necessary, but it’s extensible, simple enough, doesn’t require the script engine, leverages an existing html element and still passes in all versions of html that support the style element.

Wednesday, 20 August 2008

When a provider ditch its own product…

I’m currently researching Server 2008 VPS products available, and stumbled upon bytehouse’s offering:

Why use a Windows operating system?

Windows Hosting is only really needed if you require ASP (Active Server Pages), Access Databases or VBScript.

Why use a Linux operating system?

If you just need to host HTML (Hypertext Markup Language) or PHP Web Pages, then Linux Hosting would be the better and cheaper choice for you. Linux has a proven track record of performance, stability and security within the Web Hosting industry.

Oh, god, I have Linux envy now, thanks!

Tuesday, 19 August 2008

Come and listen (or talk) about asp.net MVC in Brighton!

VBug apparently didn’t learn their lessons from the last presentations and asked me to come back to deliver my Bingo asp.net MVC talk in Brighton, the day before ReMix! You can have a look at the event, and frighteningly it is already fully booked!

You can expect a run-down of the MVC pattern, plenty of code (but less than last time), and of course Bingo.net in its third version. I may have some surprises in stock so be prepared for anything.

For anyone down in Brighton on that day, I’ll be staying there so expect a full attendance at the pub. The only true way to start any conference is with a hangover.

Saturday, 16 August 2008

Using getElementsBySelector in ScriptSharp

I’m on my way to my second spike for one of my clients on playing with ScriptSharp to extend Rasta with Ajax functionality, and really wanted to be able to select elements as I would in CSS, using selectors (something I got quite used to with jQuery).

ScriptSharp comes with various assemblies you can link to. The one called sscorlib is a .net mapping over a javascript library that extends document to have a getElementsBySelector method. But for some reason, ScriptSharp doesn’t map that method.

So how do you call random code in ScriptSharp without resorting to evil eval code? You create a function of course! Here’s the snippet.

        public static DOMElement[] GetElementsBySelector(string selector, DOMElement root)

        {

            return new Function("return document.getElementsBySelector(selector, arg);", "selector", "arg")

                .Call(Document.DocumentElement, selector, root) as DOMElement[];

        }

We define a function that calls the correct javascript code, declare the argument names we will pass it, and finally call it by passing our selector and the root.

In one word, sweet.

Monday, 11 August 2008

Received this morning

Dear Sebastien

We are currently searching for a JOB TITLE to work in  CITY, COUNTRY  for DURATION plus extensions. This is a fantastic contract opportunity for a large multi-national client.

The ideal candidate must have the following skills: SHORT JOB DESCRIPTION.

A nice way to start the morning! Where do I sign?

Thursday, 7 August 2008

“It doesn’t work”

Something seriously cracks me up. I hear day after day people telling me one technology or another, one tool or another, fails in matching their expectation, and explain the situation by it doesn’t work.

As soon as those words are muttered by someone in a team with low knowledge of the toolkit they are dealing with, you see developers running around to work around the symptom, replace the technology, or completely screw up an architecture or a design just to make it work.

Just the same, while TDD and fast feedback cycles have brought to the development community an antidote to the press F5, it works, I’m l33t, you still find a large number of rogue developers that still manage to write no test, go head down in development, produce unmaintainable code and still manage to lift it off because the UI is shiny and the managers don’t have a clue about the importance of quality and maintainability, as they don’t have the responsibility of their v2 budget.

Whenever faced with an intellectual challenge, you have two categories of people: those who step up, learn and understand a problem before finding a solution, and the it doesn’t work and Oh I press F5 I’m good! developers. My word of advice to the latter, if you are given guidance and mentoring and refuse to step up, you will eventually be out of work. Embrace change, challenge yourself and don’t discard mentoring when it’s given to you.

Monday, 4 August 2008

Updating Hyper-V to RTM

As is usually the case when you’re under pressure to push a new release of an app for a client, something goes horribly wrong.

What went wrong tonight is simple: my Server Core install was never updated to hyper-v RTM, but windows update did its job fine on one of the client VMs that also runs Server 2008. Suddenly, the whole server is down.

Second install on the core install and still failing. I wonder how I’m going to apologize profusely to my client tomorrow. Oh the joy.

[Update 03:22: License wasnt activated properly, trying yet another install…]

[Update 04:05: Need my bed. Trying an uninstall of the role, followed by an update with the .msu. If that works I’ll reinstall the Hyper-V role tomorrow]

[Update 04:13: Apparently uninstalling the role rebooted the machine which then updated itself on its won with the RTM version. Don’t know if I should cry or laugh. Reinstalling the role now (seeing as there’s one less boot as previously expected, I have a boot to spare)]

[Update 04:27: All back in order, machines are up. Lost 6 hours of my life, less than impressed.]

Thursday, 17 July 2008

The testing anti-pattern

I've now finished my previous gig and the guys are busy chasing some recurring issues with the application. Because of its complex architecture, those issues are equally complex to understand and debug.

Most of the code in this application happens around things we cannot put under unit-tests, because they all rely on heavy integration: syncrhonization of data between tiers, integration with external RFID hardware and 3G modems, sqlce and its multiple connections issue, and other equally difficult things to debug without running the system with said external entities. As a result, our code coverage is very low, and while we do have fakes for most of those external entities, we have to think hard and strong about the value provided by tests relying on fakes, or we'd end up testing a fake implementation. Not very useful to say the least.

That made me think of some testing anti-patterns I see recurring a lot on various project, and I thought I'd highlight them. That will let me reevaluate my position in a year time, and I also know that some of the people still invovled in some of my projects are reading this blog, so it will serve as a constructive criticism for their next projects.

  1. I'll paraphrase Chad Myers, code coverage is the new LOC/day. Code coverage doesn't ensure quality, and the percentage is just that, a number. It needs to be put into context of the project: some areas do not need unit tests because they don't provide value. If you chase 100% code coverage, you're on a wild goat chase and you should reevaluate your understanding of the value of code-coverage (beyond the marketing bullsh*t).
  2. It is more important to have a code-base with low cyclomatic complexity and loose coupling than it is to have thousands of text. Evaluating code quality is not only about testing scenarios, it is also about maintainability, understandability, extensibility, etc. Use NDepend to understand where you need to refactor or rework part of the systems.
  3. Finally, and more importantly, I see no value in spending time after your code is released to write unit tests for the sake of it. Because the code has already shipped, you should not do any refactorings to it (or you'd end up with changes that you'd need to re-deploy and re-test, in which case you'll have to ship again, it all becomes a virtuous circle). So you end-up putting code under tests without bringing much value at all (again, except for increasing code coverage, see 1). Unit testing is a tool *during development* that helps you shape your objects and functionality and refactor your code until you get a satisfying result. Writing code aftewards doesn't serve much purpose.

There you are. With the advances like BDD, the focus on unit tests and code coverage by management should hopefully die a much to be celebrated death, as the focus shifts to the real issue: shared knowledge and process, arriving at a common definition of the what and why, and let developers handle the how.

Monday, 14 July 2008

asp.net MVC presentation - the results are in!

The nice people at VBUG just sent me the result of the evaluation forms, and I am very pleased with the result, as a vast majority seems to have enjoyed the talk.

A couple of points were raised by an apparently unimpressed attendee, and as those forms are anonymous I thought I would take the time to provide some feedback here.

The font size was too small to read from the back

The font had been set to quite a big font size, added with a very large DPI. I'm afraid the length of the room compared to the size of the projector made it very difficult to accommodate everyone. If anyone has suggestions to reach to more people while still managing to put 30 characters in the wideness of the screen, I'd be very interested. Any experience from using different fonts? Maybe high contrast with dark background? I'd be quite interested in learning a few new tricks to make it work better.

That said, there were spaces on the front row, and I did ask everyone to confirm my font size was alright with them. I should have indicated this was a strong hint for people to reshuffle based on their sight :)

Discover powerpoint, where are the diagrams?

This one is quite accurate, I do not have powerpoint slides as a rule: unless I have something very compelling to show in a diagram I don't see a point in showing one. I had a slide introduction for the previous version of the asp.net MVC talk I did at DNUG, but I find them distracting and get the audience passive. Especially as for MVC I would end up showing either a product roadmap (I don't think it's my job) or a diagram of MVC, which in itself seems of poor value.

While pictures do speak a thousand words, I think code does speak more efficiently to most developers. So I'd be interested in knowing what people think. Do you prefer a screencast approach of demoing step by step what is going on, or have an introduction to the concept of MVC with nice diagrams, arrows, blocks and what not? I tried both and felt the tutorial approach worked better, but from the presenter side of things it's always difficult to make those judgement calls.

Lots of mistakes in the demo

Yeap, some glitches here and there happened. Some, like the exception thrown when a view is not found, were on purpose to demo a feature, some others were due to my poor typing. On an interesting note, when presenting just like when working, apologizing for something no one has complained about usually seems to trigger complains that otherwise would have been silent. From now on I think I'll stop apologizing for my typing errors and rely on my audience to correct me (which I really like because it means they're reading and understanding the code as I type it. Spot on!)

The examples were poor

Oh, I did like my Bingo game. I'm just sick and tired of the same stuff everyone does with Northwind / NotNorthwind / Southwind. Storefront is there to provide you with an end-to-end real demo and does it so well. I'll stick to my guns on that one, boring things are one of the reasons I don't work in the city anymore :)

Conclusion

What worries me slightly more is the discrepancy between speaker rates and overall session rates, which leads me to think the presentation itself was less than excellent. I think it really comes down to two issues: expectations should be managed to reflect the code-intensive nature of the presentation, and the content is probably slightly too complex, with too many points being presented, including containers, dependency injection, inversion of control, testability, c#, javascript, html, etc.

On the bright side, only one of you has not been satisfied by the content or the presenter, with 67% rating the session as Very Good or Excellent, and 72% rating me as Very Good or Excellent (see my head growing out of proportion!), so a massive thanks to all of you for making this the presentation I've enjoyed the most so far.

P.S. I seem to remember two people chatting and laughing away during parts of the presentation at the back of the room. A good thing I had my back to the audience the whole time or I would have given the eye. Presenters do put a lot of effort in preparing those sessions, if the content or the presenter doesn't interest you, I apologize for failing to make the subject interesting to you, but I'd rather you stayed quiet or left. The law of two feet should apply, even during a presentation.

Sunday, 13 July 2008

asp.net MVC presentation

What an absolutely crazy week! I've been working flat-out all week and still have a mountain of TODO: all over my screen.

Thanks to everyone that came to the asp.net MVC presentation. It's a presentation I really enjoy and look forward to give it again to other user groups. I have the feeling that I'll finally be happy with the content the third time I deliver it. And suffice it to say that I'm working very hard to actually make the bingo.net game playable.

Apologies are in order as I'm late delivering the code (will get around to do it, probably around Tuesday) and the slides (slide.txt) and answering some of your emails. Please bare with me while I work through the backlog.

Friday, 11 July 2008

Alt.net UK Conference

Register now! http://altdotnet.org/events/5

Friday, 27 June 2008

Rewriting history?

I very often update and modify my posts until I feel they carry the meaning I intended. With English being a foreign language to me, there are many instances where my posts end-up being interpreted the wrong way or don't represent my message really well.

I'll be migrating this blog over to my own servers quite soon, and I've been wondering if all those edits should be done the way they are now, without history, or if I should adopt a more bliki approach and leave anyone to see the variations and edits I do on posts.

Does historic truth matters to you? Do you want to see my edits? Or do you only care about the end result?

Thursday, 26 June 2008

Linq-to-Entities and me: Does what it says on the tin

For those not reading on the web, the subtitle of my blog is the result of a lovely name-calling session by an anon on this site. Proof that it works, another person has now proclaimed that I am indeed what it says on the tin.

The same blog argues that alt.net has turned into the nHibernate mafia, and that we all have a vested interest in nHibernate and are trying to defend our territory. One of the tenets of alt.net is to be pragmatic about the tools we use, and I've delivered projects with nHibernate, activerecord and linq2sql, and will use whichever tool works for the job. I don't have dogma for one tool over the other when they deliver what I need.

And to be absolutely clear, some of my clients will eventually, for better or worse, use the Entity Framework, and I'll have to use that tooling, be it that it fits or not in my personal practices.

On a more positive note, there's been some very interesting comments to my entry. I thought I'd highlight my understanding of the discussion so far. If I've misunderstood those arguments, feel free to respond in the comments or insult me by messenger, I'm always available.

Proponents of L2E argue that this new framework has been developed to provide the same tooling for modelling your entities across your different needs: reporting, data access, etc. As such, it should be seen as a tool that lets you re-use knowledge across models. Furthermore, it should not be understood as a tool to create global entities shared across applications.

This could very well be the case, and indeed bring benefits for people using Reporting Services and other data-centric tools that are apparently a pain. But if we see L2E as a tool, then for reasons that have been highlighted previously, they won't fit my toolbox because they do not support the development model I have adopted.

That said, other people still look affectionately at the idea of a global model for your application / applications. My projects tell me those models fail and my experience shows me that a DTO approach to boundary crossing is more effective.

I have expressed concerns at the fact that L2E has been at the core of  other frameworks (like ado.net data services), because it brings the fundamental idea that the same model could be exposed as a REST service, sent over a WCF service to another windows client, and put in a can of Coke to the moon. Doing each of those things represents a completely different set of challenges, each with a different model. Maybe if LinqToEntities could fit in my toolbox, I could reuse it to model every single of those different entities I need to have for each boundary in my application. But I don't believe the power of the designer is going to solve any of my issues, and will probably introduce more.

I stay unconvinced but I'm overall happy to realize that many proponents of linq2entities have an understanding of the issues with a unique entity data model and with sharing of models.

The Entity Framework - don't get fooled in what is wrong about it

[edit: modified text slightly to more accurately reflect my point and remove references to Julia being fooled, which apparently has been interpreted as Julia being a fool. Apologies.]

I'm off to bed, but thought I'd end up the day on a note. There are many flaws in the programming model adopted by the Entity Framework and they've been documented enough. But this is not what makes me cringe the most.

The Entity Framework team responds to the vote of no confidence by proposing fixes to programming issues in v2, talks of openness in the design of the next version, and have got people thinking that we object with the programming model. They even suggest that it's alright for Microsoft to deliver a tool that violates best practices established by people that built real systems.

[edit: I don't believe this is done with malicious intent, but I do believe there is a fundamental misunderstanding of the arguments that have been put forward, both by the EF team and their supporters and by the signatories of the letter]

The idea that a conceptual model can represent everything for everyone through designer-generated angle-bracket files is the issue. The fundamental of selling your product as one model crossing tiers and being standardized to all is a sweet dream that will end up biting anyone getting in contact with such a system. When Microsoft says transparently, I hear painfully.

The EF team explain how to fix the syntactic sugar without addressing the elephant flaw in the model is equivalent to telling people disagreeing with the one conceptual model to rule them all that they're just nitpicking over syntax. It's quite amazing that the people voicing their anxiety at the ripple-effect of introducing EF are being discarded as a small minority of weirdos that shouldn't complain because their way is not being adopted until v2. The reality is that a majority of those people are leading the industry in interesting directions discovered through experience and reflection, and their ripple effect is wide. . There is no wonder why TDD and BDD (and DDD and DDDD and all those acronyms I hate so much because of their opacity) all started with a couple of people, not with a couple of tools and designers.

Microsoft has a responsibility, because of its size, to not screw the people that are trying to promote a better craft. When those people react to a technology like they have with the Entity Framework, they should be listened to, because by delivering yet another monster (sharepoint anyone?), Microsoft may generate business but in the process degrade the overall quality of their development ecosphere. In the long term that may just end-up killing them, as the market will decide on better, simpler and more efficient tools. It's the law of two feets. But this movement takes years and impacts everyone that has to maintain a system.

As for Entities, they exist as several transpositions adapted to not only the programming model but also the context in which you use them. My notion of a user and your notion of a user only share a couple of trivial rules. If you ever, ever try to come up with one model that covers everything, you'll be too flexible or not enough, and your project, and the projects depending on your project, will fail. Full stop. It's been tried and tested. It is wrong. Like putting mustard in your corn flakes.

[updated for clarity and minor adjustments]

Wednesday, 25 June 2008

Jesus is back and His name is... svn?!?

image

Picture worth a thousand bibles.

Tuesday, 24 June 2008

Linq2sql running on Sql Compact Edition - calling on VistaDb to clean-up their act

There is a lot of misunderstanding on this subject. Even competitors of Microsoft seem to not understand fully what Linq2sql is made of or what it actually covers. One of these competitors is Vistadb that says on their product comparison:

SQL CE users will have to wait until the Entity Framework release before they can use LINQ against a SQL CE database.

I sent them an email to warn them that their comparison was erroneous, and an exchange has started in which they've assured me I was in the wrong and have neither acknowledged the confusion nor updated their comparison. As such I feel inclined to bring the conversation to the community, to get knowledge out there. I have not received their authorization to reproduce the exchange, so I'll have to represent as accurately as I can, in my own word, the different points they made. And I hereby invite them, and you dear reader, to the conversation.

Before you begin reading this, please note I do like the work the vistadb guys have been doing, I think it's a great internal database, and I probably would use their product still. But with greatness comes responsibility yada yada.

There is no provider model in linq2sql

This is an easy mistake to make if you don't spend your time in reflector. Linq2sql *has* a provider model that has been marked as internal late in the process, as described on the Wayward Weblog. If I was to guess the reasoning, I'd guess that there would've been a conflict of interest for partners to support both the Titanic Entity Framework model that leverages updates to the core ado.net classes and a provider model where they would've had to rewrite the sql code generation from the ground-up in linq2sql.

But I would concede that, as it's not public, for all intent and purposes, there is no provider model *you can build against*.

Linq2Sql gives you a Visual Studio GUI and a mapping tool

This is accurate, and very relevant to our conversation. There is several aspects to linq2sql.

  • A provider model, with a provider implementing access to Sql Server 2000, 2005 and 2008, as well as Sql Compact Edition 3.5. This is the bit of code responsible for translating between the model and the sql code
  • An abstract mapping model defining types such as MetaTable, MetaType and MappingSource, that let you implement different mappings. Linq2sql ships with two of those, one for xml mapping files, one for attributes.
  • Visual studio ships with a designer that lets you generate an xml mapping file through a point-and-click UI. This only supports the full-fledge Sql Server, and this is where the confusion may be coming from.

So there is a bit more than a GUI and a mapping tool. It's a GUI, a mapping model and a provider model.

Sql Compact Edition queries don't support Linq, the compiler does

Well I've struggled quite a bit to understand that one. Linq queries are compiled by the compiler as extension methods or interfaces defined by the implementations of Linq (Xml, object, Sql, etc). However, I fail to see any connection with Sql Ce itself, as the one querying the database is the provider that, indeed, supports Linq2sql just fine. The provider is indeed distributed with Sql Ce 3.5.

Microsoft does not use Linq2sql as a term that covers Sql Compact Edition and it's unsupported

I don't see how it relates to the technical conversation. And the download page of Sql CE 3.5 specifies the following.

SQL Server Compact 3.5 introduces a host of new features including LINQ to SQL support

Again, it doesn't seem like unsupported to me.

Conclusion

Vistadb is a strong product in its own right. The product comparison however contains a mistake and the company hasn't responded to the two emails I've exchanged with a catchall email address.

All in all, this highlights two points. Microsoft has a communication problem around Linq2sql; Iif your competitors don't understand your product well, imagine your customers. Secondly, if you want to put product comparisons you should *really* double-check your facts. Responding in person to emails rather than through a customerservices@... address, and double-checking before responding the second time would probably have kept me a bit happier.

The Entity Framework paves the way to years of uneducating the masses

This is in substance the bitter taste that's left in my mouth as EF v1 gets ready to be released.. I've been debating on this topic in user groups, meetings and within my clients: adopting EF as it stands would be a mistake as it introduces fundamental issues in the way we write code and in the way we design our architectures. We will spend years undoing the massacre done by introducing that technology as it stands, just like we still have to suffer DataSets today.

That's why I signed the ADO .NET Entity Framework Vote of No Confidence.

And today, it was announced that the Entity Framework team would adopt a transparent process in the same way as the ado.net data services team has. In this respect I'll have to remark that the ado.net data services team took the decisions they wanted to take, even when the community advised against them.

Furthermore, the objections that were made against the Entity Framework have been around for a while and apparently didn't make it into the V1.

I'll try and have an open and positive attitude towards this opening-up, but I'll notice that already there's a push within MS to adopt the entity framework everywhere. If you push for adoption of your v1 in the company and respond to criticism by promising to fix  fundamental scenarios in v2, you're doing more damage than good, and this is why I have a trust problem vis-a-vis the Entity Framework and its design team.

Tuesday, 17 June 2008

A real 3d-enabled web browser for WPF?

I know, some of you think that the browser control in the latest WPF 3.5 SP1 is the dog's bollocks. Sadly, it suffers from its origin as a wrapper around good old GDI and the lack of GDI redirection imposed by supporting WPF in Windows XP environments.

One thing I keep track of very closely is what the mono guys do. This is a fantastic pool of resources, skills and code, and if I had time to hack I'd probably join one of their many projects. And on their feed I came across Alp's post describing a WebKit-based 3d web browser. I can't wait to have a play with the code.

Technorati Tags: ,,,

Thursday, 12 June 2008

Alt.net London Beers #2 - 17th of June 2008

It's this time of the month again, and we continue with the tradition of organizing alt.net beers events monthly.

As usual, it's casual, it's about chit chat on alt.net things and its about beer.

The venue has kindly reserved a couple of tables in their upstairs bar where we'll be having some food and of course beer.

Don't hesitate to mail the details around, the more the merrier!

The Blue Posts
18, Kingly Street
London W1B 5PX


View Larger Map

Wednesday, 11 June 2008

NxtGenUG PreFEST08 Dinner & Fest08

NxtGenUG is the most thriving user group community around. They're organizing a dinner tonight, so come and join if you're around Reading (only 29 minutes on the train from London)

And of course, tomorrow is a day of pure geekiness with the Fest08 event in Reading. Come say hi!

Hello twitter?

Craig has been selling me twitter over the last few months and I always kept it on the back of my mind. From this morning twitteroo is installed and I'll be able to start moaning on my twitter feed about the poor QoS as soon as I get it. Right now it just looks like a web-based IRC to me.

Side note, when is too much information too much? Mailing lists, messenger (and often during the day visitors of this blog chatting away, usually introducing themselves with asdf or the time-proven testing), maybe I'm overcommitting?

Tuesday, 3 June 2008

Agile smell

Anthony talks about a potential agile smell and the concept of self-organizing teams. As with his brother's blog, I still can't figure out how to post a comment so it ends up on my blog. If I was to bother with putting categories on my entries, I'd probably have one specifically for commenting on other posts when I've been too dumb to find the reply or the register button.

Let's first separate Agile (as an enforced, recognized and lucrative book publishing business, as well as quite a bit of ego and a general lack of understanding or intelligence in applying the ideas), agile (as a bunch of methodologies you pick and choose from to try and get as many benefits as you can out from what others have spent years experimenting with, and that we alt.netters would consider the pragmatic choice), post-agile as a poorly worded (imho) variation of pragmatism, and scrum (as one particular self-organizing methodology, one of the most popular but also one of the most badly applied). They each represent different things and different steps you can and should follow in becoming more agile, and everybody should try to get more agile even when not wanting, refusing or considering being past the stage of, Agile.

Back to Anthony's post. He talks about a "conflict" with someone telling him that he should have chosen a story to pick on his own because teams are self-organizing, and Anthony argued that without prioritizations he should ask before committing to the work.

I'm not entirely sure which variance of agile that company is using, but here's what we do here. Stories are written on the wall and are negotiated with the client, and doesn't involve the dev team much at the early stage outside of simple feasibility study (when we're lucky). They get used for us to produce both the scenarios for the tester's acceptance criterias and the product backlog.

The product backlog is the one being prioritised: high-level functionality cards of a couple of days, and the prioritization is done by us from the knowledge we extract painfully from the project managers. Sometimes they even come and do it themselves, but sadly that's as common as a solar eclipse.

From this, we commit at the beginning of the sprint to the amount of work we think we can deliver. After a couple of sprints we know roughly from our estimates how many virtual hours we deliver per sprint, aka how many of the hours we have estimated we manage to deliver. This is usually quite accurate even though the number itself doesn't mean much at all.

The team is self-organizing from that point because the *team* has committed to the *whole* of the sprint backlog. If we had over-committed we would've de-scoped. In that sense, at the stage of a daily stand-up, I'd agree that a team member asking what to do next is usually a practice smell:

  • Priorities of tasks mostly don't exist as we're committed to all of them
  • The ones that need to be worked on first are based on dependencies rather than priorities. If you ask you probably forgot what depended on what. With short sprints, that's the last thing you would forget when you've spent 3 or 4 hours deciding all of those on the Monday.

We use the wall for roughly clustering tasks that are inter-dependent, and the bottom of the wall for the nice-to-have. When you commit to a task, you commit to the team that you're wishing to do a task, so you probably don't have a reason to ask for permission.

The final thing that I've experimented on my latest project is to decouple the sprint backlog maintenance and the daily stand-up. It's now a real-time wall: you add, remove, complete and reshuffle tasks when you feel like it, the wall is visible and people will see the changes as they happen. The daily is a summary of all those movements: this relieves the pain of updating the wall, makes it more entertaining, and no one asks what to do next because they've either not finished their current task yet or they've already chosen their new one.

Being agile share many of the tenets of alt.net: flexibility, lookout for the best solution, pragmatism. In that respect I'll agree with Anthony that an Agile Anal can be annoying. But on the other hand (and I'll leave that to another post), only the teams that tried and mastered Agile can allow themselves to deviate to agile. If you've not tried hard enough a change in mentality in the way you work, you will fail, and what some would call "adapted agile" I call "bad habits are back".

[Updated: s/Jason/Anthony]

Wednesday, 28 May 2008

Pdc2008 here I come

One of the first thing I did this morning was to make sure I had registered for the 2008 edition of the Pdc.

Any brits travelling to LA or any alt.net guys want to organize an unconf, let me know.

Now they need to open the registration for TechEd Europe and I'll be booked for the year.

Technorati Tags:

Monday, 26 May 2008

Retrospective on my asp.net MVC talk

I'm publishing this a bit late, but I took a few days (a whole two of them) without working. How refreshing!

In an effort for a more transparent process, here are a few things I think went well and didn't go too well. If you've been at the talk I would absolutely love your criticism. Practice makes perfection, but before that it makes for nicer presentations and a less worried Sebastien!

Preparation god damn it!

The font-sizes were all wrong in everything but the code-editor, this is quite unacceptable and certainly not like me at all. So be prepared if you install vs 2008 SP1 beta, it will reset all your settings. That explains the lack of proper configuration in visual studio. And of course, a problem never comes alone, vs refuses to start under my Presentation account that is set with ridiculously large DPI setting. But it all comes down to me installing this stuff too late, which left me no time to make sure everything was configured properly. Apologies to the audience, I should have had a VM up-and-ready with all my content. And apologies to myself for installing a beta service pack on my main development machines.

Tools

All the usual presentation tools were not installed on that laptop either, so no ZoomIt and no Keyboard Jedi. Again, with a reinstall of vista a couple of days before, I just didn't have the time to get it right.

One thing I find difficult is choosing a screen mode. When showing code, I want to show you my Visual studio and whatever other programs get spawned by it (ie, firefox, the command prompt) while still seeing them on my screen. For powerpoint, I want to keep presenter-specific stuff from your eyes (a timer, some notes, and in general the whole content of the slide you'll see appearing as I talk).

I need a hybrid between Clone and Span modes. I may have something working, so my next talk will guinea-pig the idea. I'll blog about it after trying it out. :)

Not having slides...

Some people didn't completely see how the asp.net MVC and the REST part of the talk connected together, and maybe I should've introduced that at the beginning on the slides. But if you know me, I don't like slides and will avoid them at all costs.

This is the first talk I give where I put some content on slides, to refresh everyone on MVP and MVC and how the models differ. I like how visual it makes the explanation, but I'd rather manage to do it graphics only, with no text whatsoever. That requires more work, a tiny bit of animation and very good graphics. Nothing that can't be done with enough time for pimping it up.

Body language

I used the MacBook remote to change slides, and the freedom to move around to move slides is next to none. I also find that having the remote to hold from the tips of my fingers helps me avoid leaving my hands hanging. Hold something to keep your hands at chest level, it puts your body language into explanation mode. Relax and put one hand in your pocket and you switch to opinion mode.

Eye contact is the best tool to calm anxiety. You'll always find a couple of people in the audience being very expressive, that lets you judge the rhythm of the presentation. There's nothing worse than an expression-less audience.

Messy content

I'm a bit in-between two waters on this one. The whole point of the talk was to see what toolkits you can use today to do REST applications, but, for various reasons, I fit in there an introduction to asp.net MVC as a first part. That just doesn't flow well, and I think I'll split those two in two different presentations: asp.net MVC introduction (I have some AJAX stuff to make that presentation complete), and REST today, rest tomorrow. They can both stand on their own feet, and it would leave me more time for doing what I prefer doing: talking rather than coding and rushing.

I'm not funny

I tend to make jokes during the talk, they're usually completely spontaneous, but they fall flat every time, except for a few friendly grins from people I've met or talked to before. I shall prepare my jokes in advance and only use them after having tested them. But not on animals.

Speak more slowly

My voice level seems to be alright, but I speak too fast. And I have those pet words that creep in, amongst them "I think" (very annoying one I have a lot of problems getting rid of, even in day-to-day conversation), and Ok (very patronising, hate it, think I managed to mostly kick it off my presentations).

It's quite funny how the brain gives you those little fetish words. I think they creep-in because they trick your brain think there's a rhythm to what you're saying, when simple punctuation and sentences should be enough. It may also be the case that they give your brain enough time to reformulate when you're mid-sentence and unsure about what to say next. Again, preparation is the key.

Have different solutions, not different projects

This one bit me during the presentation. As I prepare the code for all the major steps, I end up with the same project at different stages, and I made the mistake of keeping all the projects in the same solution, often resulting in the wrong code being ran when pressing F5 and the wrong files being shown when I expected to show some code.

From now on, I'll keep all the projects in separate solutions.

Conclusion

I really like giving talks. It is a bit frustrating to come up with new material every time and only use it once, as you don't get the opportunity to retrofit what you learnt from presenting it once. Hopefully that will change as I get new speaking opportunities.

Wednesday, 21 May 2008

Presenting at the London .net User Group: Put your webforms to REST - how to build rest-y architectures with .net

What:
With the raise of the web 2.0 meme, more and more web applications claim to support REST architectures. We'll explore together what is REST and what is not, and how we can write a testable web application that supports the REST concepts on the asp.net platform, with a code-intensive overview of current toolkits (asp.net MVC and others).

Where:
MRM Worldwide London
76 - 80 Southwark Street , Bankside Studios, London SE1 0PN

When:
Tomorrow Wednesday the 21st of May, 18:30

Why:
This, I have no idea of :)

That is, if I get Visual Studio 2008 SP1 installing properly on my demo laptop, which is no small feat in itself, or face a frantic rewrite of some of the presentation tomorrow.

Wednesday, 14 May 2008

Reflecting on my last project

Today is a day off, as I've accumulated 36 hours of work between Monday and Tuesday and needed some rest. The last project I've been working on has been one of the most interesting I've had in a long time, not only because I took more responsibilities than usual, being both a lead dev and as a scrum master, but because of the amount of technology we've fetched in one app. To give a quick run-down:

  • Fluid database design with an object-based linq2sql database (no dbml file and no sql files in the whole project)
  • Sql Compact Edition
  • ado.net synchronization services to sync to a central database, and hopefully the sync framework for multi-party syncrhonization
  • WPF all the way, with a ViewModel way of developing
  • Castle stack, for Windsor and a bit of DynamicProxy2 love
  • 3G support for an always on experience

I've learnt quite a few things in the process, so here's a few reflections for my own benefits.

  • When you don't know what you're building, you're going to have a hard time knowing when it's done
  • Working under pressure can be fun, but it's exhausting and it does highlight a failure in the planning part. We're getting better but we're nowhere near there yet
  • It's fun to see people with a background go around in WPF. It always starts quite code-centric and evolves into more XAML as time goes by
  • I still don't see people using Blend for anything meaningful. There's a wide range of reasons why, from crashes to not liking esoteric Xaml to the recording model. It doesn't go down well with either populations right now, at least as far as WPF is concerned.
  • The only reasonable way to monitor the correct use of patterns and abstractions is to do it continuously. Not paying attention to the code base and coming back with changes weeks later is not a good idea, and a complete failure on my part. I need to get better at agreeing, explaining and enforcing design decisions.
  • No one can work on several projects within a company and stay focused. This doesn't work at all. From now on, I will flat out refuse to work on  something else in the same day. If you want my time for two projects, my minimum time unit will be a day. Interruption decreases my productivity so much it's unreasonable, and the project (and my nerves) suffer.
  • Frameworks that hide all of their internal implementation suck big time. Understanding object tracking in linq2sql is not easy or enjoyable, and bite you. Badly.
  • Frameworks that show all of their internal implementations suck big time. Castle Windsor (at least RC3) throws exceptions in all the wrong places, and make dealing with registration more painful than it needs to be (when it works at all).
  • Designers and UE people *need* to be involved throughout the process, and work on the same stuff as the rest of the team. The way people think they can go off and work on the UE or the design on their own schedule, with only validation from tech (when they don't send the work done the day before a release) is driving me absolutely insane. This doesn't work for them (we can tell them how much more flexibility they can have in their own design), it doesn't work for us (they provide diagrams of stuff we've already delivered, or stuff that is completely limiting the capacities of the platform). It's the typical waterfall model, and fall and fail it usually does.
  • Someone needs to wake up and realize that the technology is not there to support the design, and the design is not there to put a nice face on technology. They're two sides of the same silver coin, they need to work together to deliver. That's what Apple does and it works great.
  • I'm always amazed at how little is still invested in most of my clients companies around supporting other development teams. With a core team of a couple of peoples working to support other teams and evangelize the company's infrastructure, any company would save *so much time* on all other projects, from enforcing good standards, deployment procedures, automation etc. Think a few weeks per project.

Overall, a very good project, a great team and a freedom that I don't have very often with clients. I think it'll be difficult to move to my next project, the comparison will suffer!

alt.net drinks moved, only slightly

Got a message from Catriona, and the original location for our alt.net beers event was fully booked, so it's now around the corner from the previous location. See the original post for the details.

Wednesday, 7 May 2008

Implementing INotifyPropertyChanged with DynamicProxy2

22:30 and still working on various bits and bobs, so I thought I'd take a well deserved break to tell you about one nice way to implement INotifyPropertyChanged, the one and only interface any class that will be bound in WPF should be implemented.

I used to (circa .net 2) not see a bit issue in this kind of code.

public class MyClass : INotifyPropertyChanged

{

    private string _myValue;

    public event PropertyChangedEventHandler PropertyChanged;

    public string MyValue

    {

        get

        {

            return _myValue;

        }

        set

        {

            _myValue = value;

            RaisePropertyChanged("MyValue");

        }

    }

    protected void RaisePropertyChanged(string propertyName)

    {

        if (PropertyChanged != null)

            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

    }

}

But I've been badly spoiled by automatic properties in C# 3.0, and this all sounds like a lot of noise. How great would it be if we could instead simply have the following.

public class MyDreamClass : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;

    public string MyValue { get; set; }

}

Definitly much cleaner.  We're going to use DynamicProxy2, which is part of the Castle framework, and is used amongst other things in nhibernate.

The process is quite simple. You ask a ProxyGenerator to create a type for you, and pass it an interceptor object that will... Intercept any call!

First, let's clear up our class. Because the object generated by DP2 inherits from the original type, it needs to have a virtual modifier on the property. Furthermore, I wanted to add an attribute to specify which properties were to trigger the notification.

public class MyBetterClass : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;

    [Notify]

    public virtual string MyValue { get; private set; }

}

Now, let's see how we create the object.

static void Main(string[] args)

{

    var proxy = new ProxyGenerator();

 

    MyBetterClass myClass = proxy.CreateClassProxy<MyBetterClass>(new NotifyPropertyChangedInterceptor());

 

    myClass.PropertyChanged += (src,prop) => Console.WriteLine(prop.PropertyName);

 

    myClass.MyValue = "testValue";

}

Fairly simple so far. Now let's see the meat of the code, the interceptor.

public class NotifyAttribute : Attribute { }

public class NotifyPropertyChangedInterceptor : IInterceptor

{

    public void Intercept(IInvocation invocation)

    {

        // let the original call go through first, so we can notify *after*

        invocation.Proceed();

 

        if (invocation.Method.Name.StartsWith("set_"))

        {

            string propertyName = invocation.Method.Name.Substring(4);

            var pi = invocation.TargetType.GetProperty(propertyName);

 

            // check that we have the attribute defined

            if (Attribute.GetCustomAttribute(pi, typeof(NotifyAttribute)) == null)

                return;

 

            // get the field storing the delegate list that are stored by the event.

            FieldInfo info = invocation.TargetType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)

                .Where(f => f.FieldType == typeof(PropertyChangedEventHandler))

                .FirstOrDefault();

 

            if (info != null)

            {

                // get the value of the field

                PropertyChangedEventHandler evHandler = info.GetValue(invocation.InvocationTarget) as PropertyChangedEventHandler;

                // invoke the delegate if it's not null (aka empty)

                if (evHandler != null)

                    evHandler.Invoke(invocation.TargetType, new PropertyChangedEventArgs(propertyName));

            }

        }

    }

}

And that's it. Get the field in which the event is stored and invoke it whenever a property has been modified.

Sunday, 4 May 2008

Thought of the evening

MSBuild + SqlCompare + DataContext == FluidDatabaseDesign

The tale of the 6.4 Megapixel desktop

Just upgraded my development environment, here's the picture.

013

The laptop looks tiny next to the screen, but it is in fact a high res MacBook Pro, 1920x1200, driving as a secondary screen an Apple Cinema Display 30" for an added 2560 x 1600.

That's freakin' 6.4 megapixels of vista goodness! Surprisingly enough, Aero runs without a hitch.

Couple of other interesting points: new apple keyboard as I fell in love with the feel of the MBA keyboard, the mouse is not the one i usually have (but ran out of batteries). And Prada sunglasses for the one day of sun we've had in London so far.

As for drinks, the coffee mug is the property of the client at which I keep this equipment, and the can of Redbull kinda explains the name behind my company name: caffeine IT :)

Saturday, 3 May 2008

IIS and asp.net URL validation weirdness and links

In my Migrating to IIS7 post, I highlighted that building REST frameworks that do meaningful things with Urls is hard on microsoft's platforms.

I encourage you to go and read the comments left by Mike Volodarsky on the issue. He's a Program Manager at Microsoft. Having people from the team building IIS7 responding to people like me highlighting issues shows how some teams really engage proactively with their customers. Kudos!

The other team at Microsoft that understand REST a bit (and IMO the most out of all the teams working on this), is the Astoria team. And of course, because they do funky stuff with their URLs, they hit the same issues as me. So here's a link on how to deactivate some of the checks asp.net does. Nasty registry editing...

I really wish asp.net could recognize when an IHttpHandler does not want validation and let it handle the request, its validation and etc.

Alt.net London Beers #1

[Update: new location, see below]

Here's the latest development. The alt.net London Beers event is being moved!

Skills Matter is organizing a talk by Gojko Adzic on the Castle Framework on the day we originally planned for the drinks. As everybody has shown strong interest in attending both events, Skills Matter has been kind enough to help us organize the drinks in the Crown Pub in front of their office, so you can now attend both events.

Not only that, but they have also opened the possibility for another presentation on an alt.net subject, so if you feel like presenting, drop me a mail!

I have to thank Catriona at Skills Matter for sponsoring the alt.net London Beers event and inviting all the alt.netters to attend the Castle presentation, as well as Gojko for suggesting the merge of the two events.

So here's the recap:

We'll probably move back to the planned Tottenham Court Road location for our second meet, on the 16th of June. Keep your calendars open!

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...