Wednesday, May 09, 2007

Exploring Castle Windsor/MicroKernel Auto-wiring

Castle Windsor/MicroKernel is a great tool for dependency injection. For most applications, the auto-wiring features of MicroKernel will perfectly for the your situation out-of-the-box. However, imagine a scenario where the dependencies of some components are services defined by an interface, while the dependencies of other components depend not on the interface, but rather on the specific implementation. Let's explore how we can get MicroKernel to help us out. So let's say we have this interface:

    public interface ISender

    {

        void SendMessage(string recipient, string message);

    }


and we have a couple of implementations:

    public class EmailSender : ISender

    {

        public void SendMessage(string recipient, string message)

        {

            // ... send email message ...

        }

    }


    public class InstantMessageSender : ISender

    {

        public void SendMessage(string recipient, string message)

        {

            // ... send instant message ...

        }

 

        public bool IsOnline(string recipient)

        {

            // ... check is user is online ...

            return false;

        }

    }


Suppose we have a component that requires a set a ISender services:

    public class AlertSystem

    {

        private ISender[] _senders;

 

        public AlertSystem(ISender[] senders)

        {

            _senders = senders;

        }

 

        public ISender[] Senders

        {

            get { return _senders; }

        }

 

        /// ... implementation ...

    }


OK, so far so good. Wiring this up with Windsor is a piece of cake:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <components>

    <component id="instant.message.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="email.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="alert.system"

              type="Eg.AlertSystem, Eg">

      <parameters>

        <senders>

          <array type="Eg.ISender, Eg">

            <item>${instant.message.sender}</item>

            <item>${email.sender}</item>

          </array>         

        </senders>

      </parameters>

    </component>

  </components>

</configuration>


But what if I have another component that requires a specific implementation of ISender like this:

    public class InstantMessageComponent

    {

        private InstantMessageSender _sender;

 

        public InstantMessageComponent(InstantMessageSender sender)

        {

            _sender = sender;

        }

 

        public InstantMessageSender Sender

        {

            get { return _sender; }

        }

 

        // ... implementation ...

    }


How can we get this wired up? Well, you might think just added the new component would work:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <components>

    <component id="instant.message.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="email.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="alert.system"

              type="Eg.AlertSystem, Eg">

      <parameters>

        <senders>

          <array type="Eg.ISender, Eg">

            <item>${instant.message.sender}</item>

            <item>${email.sender}</item>

          </array>

        </senders>

      </parameters>

    </component>

    <component id="instant.message.component"

              type="Eg.InstantMessageComponent, Eg"/>

  </components>

</configuration>


However, there is a slight problem with this. MicroKernel will not auto-wire components that have a dependency of InstantMessageSender because it is instead registered in the config for the service it provides, namely ISender. In this case, I can force the kernel to wire it up using the following configuration:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <components>

    <component id="instant.message.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="email.sender"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="alert.system"

              type="Eg.AlertSystem, Eg">

      <parameters>

        <senders>

          <array type="Eg.ISender, Eg">

            <item>${instant.message.sender}</item>

            <item>${email.sender}</item>

          </array>

        </senders>

      </parameters>

    </component>

    <component id="instant.message.component"

              type="Eg.InstantMessageComponent, Eg">

      <parameters>

        <sender>${instant.message.sender}</sender>

      </parameters>

    </component>

  </components>

</configuration>


This works, but it's not autowired. If you have a lot of this going on in your system, you'll find yourself taking on more and more of the responsibility of wiring your components, even though you originally wanted to leverage MicroKernel to handle much of this for you. So let's say we want our configuration to look like the first configuration I presented. Well, we're going to have to change the way MicroKernel registers services. This concern is specifically handled via the NamingSubSystem. We will do the job by extending MicroKernel's default INamingSubSystem implementation, DefaultNamingSubSystem:

    public class CustomNamingSubSystem : DefaultNamingSubSystem

    {

        public override void Register(string key, IHandler handler)

        {

            Type implementation = handler.ComponentModel.Implementation;

 

            if (!service2Handler.Contains(implementation))

            {

                this[implementation] = handler;

            }

 

            base.Register(key, handler);

        }

    }


In this method, all we're doing is additionally adding the implementation to resolvable services if it isn't already. The DefaultNamingSubsystem only adds the service and not the implementation except in cases where you don't specify a service. Also note that this method should also take care of mapping the component id to the proper component. Here's the default implementation:

        public virtual void Register(String key, IHandler handler)

        {

            Type service = handler.ComponentModel.Service;

 

            if (key2Handler.Contains(key))

            {

                throw new ComponentRegistrationException(

                    String.Format("There is a component already registered for the given key {0}", key));

            }

 

            if (!service2Handler.Contains(service))

            {

                this[service] = handler;

            }

 

            this[key] = handler;

        }


And here's how I got Windsor to use my new DefaultNamingSubSystem:

    public class ApplicationContainer : WindsorContainer

    {

        public ApplicationContainer(string xmlFile) : base(xmlFile)

        {

        }

 

        protected override void RunInstaller()

        {

            Kernel.AddSubSystem(SubSystemConstants.NamingKey, new CustomNamingSubSystem());

            base.RunInstaller();

        }

    }


By the way, we could have gotten this all wired up if we registered the implementations twice: once for the service it provides and another time for the implementation, like this:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <components>

    <component id="instant.message.sender.service"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="email.sender.service"

              service="Eg.ISender, Eg"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="alert.system"

              type="Eg.AlertSystem, Eg">

      <parameters>

        <senders>

          <array type="Eg.ISender, Eg">

            <item>${instant.message.sender}</item>

            <item>${email.sender}</item>

          </array>

        </senders>

      </parameters>

    </component>   

    <component id="instant.message.component"

              type="Eg.InstantMessageComponent, Eg"/>

    <component id="instant.message.sender"

              type="Eg.InstantMessageSender, Eg"/>

    <component id="email.sender"

              type="Eg.InstantMessageSender, Eg"/>

  </components>

</configuration>


I wouldn't recommend this approach though.

Monday, May 07, 2007

Compressing SQL Server Backups With Windows PowerShell and 7-zip

We run monthly full backups, daily differential backups, and transaction log backups every hour. The backup drive fills up quickly. So I decided that I wanted to compress all of the .bak and .trn files into their own .7z files using 7-zip. Doing something like this in a bash shell is trivial. Windows PowerShell makes it trivial as well (as long as you have it installed). Here's what I did:


get-childitem -recurse |
where { $_.extension -match ".(bak|trn)" -and
-not (test-path ($_.fullname -replace "(bak|trn)", "7z")) } |
foreach { F:\7za.exe a ($_.fullname -replace "bak", "7z") $_.fullname }


Here's a breakdown of what's going on:

get-childitem -recurse: Retreives all files recursively from the current directory

where { $_.extension -match ".(bak|trn)" -and -not (test-path ($_.fullname -replace "(bak|trn)", "7z")): Filters the filelist to only include files that end in .bak and .trn and also where there isn't already a file with the same name but with an extension of .7z

foreach { F:\7za.exe a ($_.fullname -replace "bak", "7z") $_.fullname }: Run the 7za.exe command line utility to add the .bak or .trn into a .7z file.

After this command completed, I ran the following command to remove all of the original .bak or .trn files if they have a corresponding .7z file:


get-childitem -recurse |
where { $_.extension -match ".(bak|trn)" -and
(test-path ($_.fullname -replace "(bak|trn)", "7z")) } |
foreach { del $_.fullname }


By the way, the 7-zip command line utility is good about deleting .7z files that were not properly created (e.g. you cancelled the compression before it finished.)

Saturday, May 05, 2007

Finding Good Developers

I will very soon have the need to find qualified software developers for an upcoming large project. I've tried to hire software developers before, but I think I must be going about this the wrong way.

I've tried the Monster approach, but I mainly got a group of unqualified developers that didn't have command of what I specifically stated as a requirement for the job. For example, if I put that knowing SQL is a requirement, I expect you to know at a minimum how to write SELECT, INSERT, UPDATE, etc. statements without having to Google it. It was surprising how many of the candidates failed to meet this requirement.

In addition, I received a bunch of emails from staffing agencies that wanted to charge us 2x-3x the amount that the developer they were pitching was going to end up making. The facts that I know we're overpaying and that I've had a very bad experience with these staffed developers in the past really make me want to avoid this route.

I guess I'll just have to get lucky when I start looking again. I don't mind teaching sharp guys new concepts, but even finding them is next to impossible it seems. Anyway, if you're in the Houston area and looking, definitely drop me a line.

Wednesday, May 02, 2007

One of the Funniest Comics Ever



I couldn't stop laughing when I saw this. There's lots more at XKCD.

Tuesday, May 01, 2007

Top Down vs. Bottom Up

I used to start building new applications by writing the model and persistence layer. I'd flush out my model, then build the persistence on top, and then go about writing the view. I will not likely use this approach ever again.

I'm currently working on a MonoRail application where I'm taking a different approach. I've been start at the controller and view level and been working downward. When I reach a point where I need to work with the model and persistence, I instead define an interface and an appropriate model that would be ideal for the specific use case I'm working on.

I've found myself stubbing out implementations to these interfaces, instead of actually creating the database and persistence logic. A huge win that I've found is that I'm able to test the web application without a database! It makes changes and refactoring take a fraction of the time because I don't have to worry about updating the ORM mapping, database tables, etc. I also save myself from writing unneeded functionality in the model and persistence layer. But being able to see the application interface using mock data and not ever actually hitting the database have both been a huge benefit. The time to do a write/compile/test cycle has been greatly reduced. I have less code in my codebase that I'm not actually using.

I believe this approach matches the TDD style of development a bit better than what I'm used to doing as well. Write the API that want to use from the top down, not the API that you think you'll use from the bottom up.

My inspiration was this post was list of best practices that John-Paul S. Boodhoo jotted down about a course he was taking. There's lots of other great stuff his notes as well.