Automated Deployments #3: The Extend Macro in Binsor

In the previous post, I dealt with the standard .NET config file.  It would be lovely if all we needed to deal with was appsettings and connection strings.  Sadly, the world is more complex than that.  Now, quite a few of the systems listed below (pretty much all of the XML-based ones) give you the option of including their config in the app.config or in a separate file.  I can’t say as I see it makes a blind bit of difference.  Each of them has their own XML schema and I doubt you wish to write a diff tool for each of them.

Castle Windsor has a fluent configuration mechanism and an XML format.  Annoyingly, neither of them support environmental diffs.  I can’t quite believe that this isn’t baked in, but then the major competitors don’t seem to address this either.  Furthermore, since there is no facility within Windsor for producing a container that specializes another container, you can’t use specializations to produce environmental deltas.  In particular, you could have the principal configuration using the fluent interface, keeping with ThoughtWorks dictum of not putting anything into a config that can be hardwired.  You could then specialize using the XML format.  There is, however, one other alternative, Binsor.  Now, Binsor is a true .NET language with a couple of specializations to support windsor configuration (or a DSL, if you prefer).  It supports environmental deltas through the Extend macro.  The Extend Macro isn’t really documented, so here’s a quick guide to how to use it:

MainConfiguration.boo:

def DoConfigure():
    Component "service", IService, ConcreteService:
        standardParameter = "Value the same across all deployments"

Environment1.boo

import file from "MainConfiguration.boo"

DoConfigure()

Extend "service":
    environmentalParameter = "Parameter value is different in Environment2.boo"

 

This is incredibly powerful.  In particular it lets you change your mind about which parts of the config are environmentally driven and which aren’t.  Let’s go through it (with some stuff I learnt the hard way)

  • Binsor allows you to include one file in another.  You need to wrap the code in the main configuration in a function that you call from the environmental diff.  This might seem backwards, but it’s pretty much the only way it can work.
  • The import file syntax supports relative paths, but make sure that you pass BooReader an absolute path to the environmental diff, or it may not work the way you’re hoping.
  • Extend is keyed by the name of the component that is declared in the MainConfiguration.boo file.  Thus, in the example, the ConcreteService class has string parameters for standardParameter and environmentalParameter.
  • There is, of course, the outstanding question of how you identify which environmental delta to use.  You’ve basically got two options here: get the install to rename the delta file to a standard name, or put the name into the appsettings.  (I’m finding it remarkably hard to kill off appsettings completely, much as I try…)

I like Binsor in that it’s a complete solution to the problem.  It is, however, quite a heavy-weight solution, and you can’t mix and match it with the fluent configuration since it’s doing all the hard work itself.  Since Castle Windsor’s ComponentModel class is immutable and doesn’t support specialization, it has to build its own component model in order to support this feature.  That shouldn’t bother you until you try stepping through the code and discover that there’s several thousand more lines supporting this syntax than you were expecting.  A more general difficulty is that it uses Boo’s most powerful and most dangerous feature: the ability to change the way the syntax tree is evaluated.  It produces a relatively elegant syntax, but it’s not documented and there’s no editor support for it that I know of.

Cost Benefit calculations when Developing for Browsers

John Resig has just put out a nice post about browser share.  It’s well worth reading and I won’t repeat what he says there.  I do, however, think the cost benefit balancing graph is a worth examining further.  If you take a look, it seems to say that IE7 is a lot of work, but worth targetting, whilst IE6 is not worth the effort.  However, this is very dependent upon the browser share and the traffic to your site.  The yellow bars, the cost, are pretty much constant across browsers.  The blue bars, the benefit, can be expressed as follows:

Number of users of this browser x Revenue per user for this browser

Now, for a seriously low traffic site, that might suggest that you shouldn’t even bother supporting IE7.  In practice, you will, because you won’t feel like you can take yourself seriously if you don’t.  IE6 becomes a complete waste of time.  If you’re google, on the other hand, all of the blue bars are in the stratosphere, and you should support browsers that people haven’t even thought of yet.

In practice, the cost benfit nearly always favours supporting IE6.  Let’s assume it took three months to support IE6 to the extent that someone could use the site, that the conversion rate for IE6 users is 7% and that you got £60 per action.  (These are reasonable numbers for some dotcoms.)  Finally, assume the contractor that does the work costs £300 a day and demands payment up front.  Then, if you had 137 visitors a month after that point, you’d get a 5% annual return on your investment.  That’s assuming a three-year planning horizon.  Obviously, the numbers go down if you have a shorter horizon and up if you have a longer one.

137 visitors a month is nothing.  It’s more than this blog manages, but a half-decent commercial business with a bit of TV advertising would have thousands of visitors.  You only need 4500 visitors to make 5% back the month you go live.  Obviously, you need to run your own numbers: some people will see the quick numbers I’ve made up and not even vaguely recognize their own business.  But I can reasonably guarantee you, if you’ve got a public website, you’re not going to be able to convincingly argue for the demise of IE6 any time soon.

Technorati Tags: ,

Loving Krzysztof’s blog

This is a straight plug, but I’ve got to say, I’m really enjoying reading Krzysztof Koźmic’s blog at the moment.  In particular, his guide to Dynamic Proxy is excellent.  I’ve certainly learned a lot by reading it.  I’ve said before that dynamic proxy is extremely powerful and useful.  It’s good to see someone who properly understands it giving such a lucid step by step guide to how to use it.  Me, whether or not I keep working on AutoGen, I’ll definitely keeping working with DP.  Sadly, it’s still quite hard to find on google.  Let’s hope this post improves that score.  🙂

Technorati Tags:

AutoGen and the Common Service Locator

One of the nice things about finally finishing a major project is that you get to do some work on side projects you find entertaining.  So, today, I finally finished a rather ugly merge and got a new version of AutoGen for Castle out.  Obviously, it isn’t hard to implement the Common Service Locator in Windsor.  However, since the idea of AutoGen was to allow you to use your own abstraction for DI, and so implementing Microsoft’s seemed like a good stress test.  I’ll take a crack at NServiceBus next… 🙂

I shamelessly ripped off Ayende’s tests for the CSL and ran them against an AutoGen version of the implementation.  I identified a number of issues:

  • You couldn’t specify a service type.  This isn’t important if you’re building an application, because you’d just specify a return type and AutoGen would handle it.  However, a framework doesn’t necessarily know the service type in advance, so framework interfaces need that feature.
  • You couldn’t perform a ResolveAll.  Now, if you return IEnumerable<T>, it automatically performs a resolve all.  This would interfere with anyone who registered an IEnumerable<T> service type, but frankly, Castle’s dependency injection pretty much fails when you do that anyway.
  • The Common Service Locator standard specifies the exception that needs to be thrown.

Anyway, the good news is that it this now works:

container.Register(
    Component
        .For<IServiceLocator>()
        .AutoGen()
        .WithWrappedException<ActivationException>()
        );

 

I also took the opportunity to allow you to override the names of the key and serviceType parameters, both in configuration and using the fluent API, since it seemed likely this would come up when implementing third party interfaces.  I’m not massively happy with the wrapped exception qualifier, it feels a bit too special case (time will tell, it may prove useful in a number of circumstances).  It’s implemented as a separate interceptor.  I’d have liked to have properly separated the concerns of resolution and disposal proxying, but it turns out that this is nigh-on impossible.  Basically, since proxying of concrete classes is fraught with difficulty, to say the least, you need to know what the original service type was in order to create a valid proxy.  It automatically adds in proxy interfaces for anything else the implementation exposes, which means that forwarding now works transparently.

Alt.Net and Adoption

Just read this.  Couldn’t agree more.  Quite a few of the Alt.NET groupings have an explicit bias in favour of people who submit patches.  Now these people are, for the most part, giving away radically great stuff for free.  Expecting something in return isn’t unreasonable.  However, without focus on people starting on the curve, or even halfway through,

My own curve is far from “at Z”.  I “get” why persistence ignorance is important, but work on a lot of old sproc code.  I use dependency injection, but haven’t mastered it.  I implement separation of concerns, but I wouldn’t claim perfection there either.  I’ve got a lot of automated tests, but I still favour state-driven tests rather than behaviour-driven tests.  I’m also aware that many of the bloggers I admire (Jeremy Miller) are significantly further along this process.  I do, however, find it slightly depressing that he believes it’s time to give up on evangelism.  This from the guy who wrote one of the single best introductions to test driven development and MVC design.

Now, I know that some people will have to be dragged kicking and screaming into adopting new techniques.  I think this story is occurring in microcosm in most firms up and down the land.  Me, I’m going to continue on my own journey towards Z, or whatever letter the “coalition of the willing” has reached now, and continue to document what I learn.  Why?  Because, actually, these techniques do make you massively more productive.  Inversion of Control solves a lot of configuration problems and drastic reduces the amount of boiler plate code an SoC design would otherwise entail.  Separation of Concerns makes my code more pluggable, more agile (small a) and just plain easier to understand, even for me.  Test driven development has given me the ability to refactor code that in the old days I wouldn’t have dared touch for fear of breaking something.  In short, it actually works, unlike many of the programming fads that have hit over the years.

Technorati Tags:

How to click on whitespace in HTML

Reading Jeff Atwood’s latest post reminded me of this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
  <a href='http://www.colourcoding.net/'><h1>
    Can click on whitespace
  </h1></a>
  
  <h1><a href='http://www.colourcoding.net/'>
  Can't click on whitespace
  </a></h1>
</body>
</html>

This is actually a really useful technique, especially if you’re using a background image behind your title.  You can click anywhere on the first line and it will follow the link.  Is it portable?  To the best of my knowledge every browser interprets this the same way.  Is it standard?

Err… no.  Actually, the standard doesn’t even allow you to put an h1 tag within an a tag.  There are no other ways of doing this (we’ll ignore the possibility of using javascript to cloak it).  I think I lost faith with validation at that point.

Technorati Tags: ,

Concurrency begins at home

I’ve been watching some very excited tweets go past about concurrency improvements in .NET 4.0.  I’ve got to say, I’m quite looking forward to hearing about this once the NDAs drop away (not an MVP, nor am I likely to be).  Retlang is pretty much the only game in town for concurrency right now, and it’s quite hard explaining to people the problem it’s trying to solve.  The standard question is “what’s wrong with using Threads”?  The work the Maestro team is doing looks exciting as well, although I’m a bit dubious about the benefits of a language rather than a C# DSL.  (Isn’t it about time they introduced more DSL-friendly syntax, anyway?  I guess that wouldn’t give Don Box anything to do.)

However, what would really make my day is if they fixed the debugger.  I’m running a piece of code with 30 threads here.  It’s rock solid in production.  Pity it crashes after about 15 minutes in the debugger.  I can work around it but I really shouldn’t have to.