Development Blog

 Thursday, November 29, 2007

So the other day, my computer started acting up, swapping like mad and that sort of thing. Turns out one of my drives had just up and disappeared. Luckily, I didn't lose anything important. My life pretty much revolves around subversion repositories at work and my university. But, it's still annoying to have to rebuild that local "cache" that my hard drive acts as. Especially since the failure was obvious and appeared to be fixable. The male SATA connector on the drive had broken. The small piece of plastic that the contacts rest on had snapped off inside of the cable. This left the gold pins floating helplessly in the air. I tried everything to get those seven posts on the drive to make contact with the cable. Lots of careful positioning and heavy application of electrical tape, etc... I went to the local Electronics Warehouse and they told me I was out of luck. I gave up.

A week or so later my dad hands me the same drive:

He had snipped off the end of a SATA cable and soldered the conductors directly onto the drive. He said it took him about an hour. Hah! My dad is a retired electrician who now works on industrial automation for rock and batch plants - PLC's and that sort of thing, a very different kind of programming. I plugged it in and it worked perfectly! I didn't think keeping the drive in service was a good idea so I just copied the data off. Thanks dad!

by Jacob on Thursday, November 29, 2007 11:18:26 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Sunday, November 18, 2007

I haven't posted in a while and decided to write a post about one of the little side projects I've worked on recently. I've been lurking around on the ALT.NET mailing list and one of the discussions I take time to keep up on is on Dependency Injection. Something I worked on a few weeks ago has some applications in that area and so I decided to see what others thought.

I was talking with Aaron several months ago about how many problems constructors in static languages cause. Ruby people are fortunate in that their constructors are much more flexible than their C# counterparts. Want something to be a singleton? Just return the same instance from the constructor! Lifecycle management and dependencies can be the responsibility of the constructor itself, rather than a function of a container.

Over the weekend a few weeks ago I wrote a library and MsBuild task that factors constructor calls out of code and into a pluggable factory system. You write code like this:

public class EmailSender
{
  public void TellEveryone(string message)
  {
    TemplateRenderer renderer = new TemplateRenderer();
    Console.WriteLine(renderer.Render(message));
  }
}
public class EmailSenderFactory : IObjectFactory<EmailSender>
{
  public EmailSender Create()
  {
    return new EmailSender();
  } 
}
EmailSender emailer = new EmailSender();
emailer.TellEveryone("Hello, World!");

What the MsBuild task will do is this:

  1. Load the target Assemblies using Mono.Cecil
  2. Find implementations of IObjectFactory<T> and add them to the FactoryMap.
  3. Find all instances of new T() for each of those factories and replace them with a call to the Factories.Create<T>(), ignoring calls inside of factories themselves.
  4. Weave the FactoryMap (just the Factory Type and its Object Type) into the Assembly.

So during runtime we can use the FactoryMap that was serialized in step #4 to create the factories and use them to create instances as they're demanded. It is important to note that your objects need default constructors, even though they may never be called after the code is weaved. One can also replace the factory implementations with IoC backed versions, etc...

Why don't you just create a New.Instance<T> method and use that instead of new T() and save yourself the pain of weaving and having a task and all that, moron?

Good question! I mostly did this as an exercise in code weaving using Cecil. It's a great library, although testing code using it can be a little tedious. I'm tossing around some other projects that I'd love to give a shot and this was a good introduction. You could achieve the same thing using reflection to build your factory map and remember to use New.Instance<T>() instead of the new operator in your code. Granted, the manual approach plasters the concern all over the place and weaving keeps the original code free from that. Which may be an OK trade-off for the simplified process.

Another thing to consider, is that perhaps the weaving approach has its applications elsewhere? Use it specifically for creating domain classes to transparently provide domain services? Another idea I've been tossing around is if you're writing code for platforms where garbage collection isn't as performant (xbox for example) you may be able to transparently add object pooling and other patterns after the fact and not clutter up the original code.

I want to release the code anyway, but I'm tired of uploading zip files. All my future source releases will probably be via Google Code or some public svn repository. Stay tuned.... In the meantime, feel free to opine.

by Jacob on Sunday, November 18, 2007 3:49:46 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, November 02, 2007
by Aaron on Friday, November 02, 2007 2:31:28 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |  Trackback