From Windsor XML to Binsor In 4 Hours
I’m getting ready to take a break from my current project and switch gears
for a little while, but there were a number of “clean up” type tasks I wanted to
do before I wrapped things up.
One of the main things I wanted to do was to get rid of the XML configuration
files I had for Windsor and use Boo and Binsor instead. Any
chance I get to work with Boo is a joy. Almost makes me wish Boo would’ve taken
off instead of C# as the “default” .NET language (I can hear all the VB’ers
screaming now… :).
As of today, I’ve got 67 components configured for Windsor to manage for me
spread across 13 different XML configuration files, just to keep it somewhat
organized. Needless to say, I was very much looking forward to nixing the angle
brackets and verbosity of XML. So I approached it the same way I do any other
time I need to do some refactoring or configuration changes. Make one little
change, test, repeat.
About 4 hours later I had everything 100% switched over to Binsor, in a
*single* file (I still may [break
it up into multiple files](http://www.ayende.com/Blog/archive/2007/10/10/Multi-file-DSLs.aspx), but this works for now). This was my very first
time even trying out Binsor, so I’m sure next time I’ll be able to do this kind
of thing much faster. Here are a couple cool things I learned…
-
When trying to configure the LoggingFacility using Binsor, I figured out
that in order to set the loggingApi attribute correctly you need to use the
brackets syntax like this:
Facility(logging_facility, LoggingFacility, { @loggingApi:"log4net" })
I’m very familiar with this since I use Brail as my view engine of choice.
🙂
-
One cool thing I learned was that you don’t even need brackets when
specifying parameter values and dependency overrides for your components. I’m
not sure if this is a Boo thing or something Ayende enabled, but you can use a
hash without brackets as the last parameter, similar to how I can in Ruby. An
example might make this more clear…
Component(primary_catalog, ICatalog, Catalog, name:"Primary Catalog", otherParam1:"blah", otherParam2:"blah")
-
In a couple areas I have a set of mappers that just have default
implementations right now and don’t have any special configuration, so I
used the power of Boo to dynamically configure them for me ([a
technique I first saw Ayende use](http://www.ayende.com/Blog/archive/2007/10/08/Zero-Friction-Configurations.aspx))
for type in System.Reflection.Assembly.Load("Service.Implementations").GetTypes():
continue unless type.Namespace == "Service.Implementations.Mappers"
continue if type.IsInterface or type.IsAbstract or type.GetInterfaces().Length == 0
Component(type.FullName, type.GetInterfaces()[0], type)
-
One gotcha I had to easily work around was specifying decimal values for my
components parameters. I have a couple stubbed out calculation strategy
components that take in a decimal rate during construction. It may just be my
lack of Boo knowledge, but every time I would try to use something like 0.06 or
0.06m I would get cast exceptions. Eventually I remembered that I had the power
of the Boo language so I just cast it myself and it seemed to work.
Component(tax_calculation, ITaxCalculationStrategy, TaxCalculationStrategy, taxRate:cast(decimal, 0.06))
(**If anyone out there can correct me on this, that would be
great!**) 😀
So I’m pretty happy with how it turned out. Much more concise than its XML
counterpart.