August 2008 Entries

Just read Ayende's post about it and thought I would reiterate.

Version 2.0 of NHibernate (the awesomest ORM tool) is released.

I've been using the alpha and beta and it is quite sweet (even in the alpha stages).

You can get it here.

Enjoy!

~Lee

I've been using StructureMap for my dependency injection container for a little while now and I wanted to discover all the ways (I could find) to register my dependencies. Here's is what I came up with (If you know of more or see something wrong drop me a comment):

I've got a project with a console app, a project for my dependencies (memento and concrete types), and a project that does my dependency registration (when I do it in code). My console app just gets the default concrete type first, then gets a named instance. Each implement the IInjectable interface.

   1:  public static void Main(string[] args) {
   2:   
   3:      //Registrar.RegisterByAddingARegistry();
   4:      //Registrar.RegisterBySearchingAnAssembly();
   5:   
   6:      // get the default concrete type
   7:      var defaultInjector = ObjectFactory.GetInstance<IInjectable>();
   8:   
   9:      // get a named concrete type
  10:      var namedInjector = ObjectFactory.GetNamedInstance<IInjectable>("Other");
  11:   
  12:      // output the types so we know we got the right ones
  13:      Console.WriteLine(defaultInjector.WhatsMyType());
  14:      Console.WriteLine(namedInjector.WhatsMyType());
  15:   
  16:      // pause so we can see
  17:      Console.WriteLine("press any key to continue...");
  18:      Console.ReadKey();
  19:  }

Output

Once the program runs, I should see (no matter which registration method I am using) a console output that looks like the screen shot to the right.

 

 

 

 

First, is the good, old-fashioned StructureMap.config file. This is probably the simplest solution and the one most people will use. It looks like:

   1:  <?xml version="1.0" encoding="utf-8" ?>
   2:  <StructureMap>
   3:    <Assembly Name="ConsoleTester" />
   4:    <PluginFamily Assembly="Dependencies.Project" Type="Dependencies.Project.IInjectable" DefaultKey="Default">
   5:      <Plugin Assembly="Dependencies.Project" Type="Dependencies.Project.InjectorOne" ConcreteKey="Default"/>
   6:      <Plugin Assembly="Dependencies.Project" Type="Dependencies.Project.InjectorTwo" ConcreteKey="Other"/>
   7:    </PluginFamily>
   8:  </StructureMap> 

Put this config file in any project that needs to have dependencies injected, and make sure to change the "Copy to Output Directory" property of the file to "Copy if newer" or "Copy always". This ensures the project needing dependency injection can use the config file.

Second, I can add a Registry to my configuration using the following code. It will override using the XML configuration file and to call AddRegistry Method. (notice the first line of the configure() override: I reset the plug in graph no need to do this if you take the StructureMap.config XML file out.):

   1:  public static void RegisterByAddingARegistry()
   2:  {
   3:      ObjectFactory.Reset();
   4:      StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
   5:      StructureMapConfiguration.AddRegistry(new InjectableRegistry());
   6:  }

where my InjectableRegistry class looks like:

   1:  public class InjectableRegistry : Registry
   2:  {
   3:      protected override void configure() {
   4:          ObjectFactory.Reset();
   5:          RegisterDefault<IInjectable, InjectorOne>();
   6:          Register<IInjectable, InjectorTwo>("Other");
   7:      }
   8:   
   9:      private static void RegisterDefault<MementoType, ConcreteType>() where ConcreteType : MementoType
  10:      {
  11:          StructureMapConfiguration
  12:              .ForRequestedType<MementoType>()
  13:              .TheDefaultIsConcreteType<ConcreteType>()
  14:              .CacheBy(InstanceScope.Singleton);
  15:      }
  16:      private static void Register<MementoType, ConcreteType>(string instanceName) where ConcreteType : 
  17:          MementoType
  18:      {
  19:          StructureMapConfiguration
  20:              .ForRequestedType<MementoType>()
  21:              .AddConcreteType<ConcreteType>(instanceName)
  22:              .CacheBy(InstanceScope.Singleton);
  23:      }
  24:  }

The Registry type is in the StructureMap.Configuration.DSL assembly. It basically allows the fluent interface to the StructureMapConfiguration class. This setup should receive the exact same screen output as before once that is done.

Lastly, I can tell StructureMap to set up all plug in families and plug ins by searching an assembly. StructureMap uses Attributes on the classes to create the configuration. Like so:

   1:  [PluginFamily("Default", IsSingleton = true)]
   2:  public interface IInjectable {
   3:      string WhatsMyType();
   4:  }
   5:   
   6:  [Pluggable("Default")]
   7:  public class InjectorOne : IInjectable {
   8:      public string WhatsMyType()
   9:      {
  10:          return "I am InjectorOne";
  11:      }
  12:  }
  13:   
  14:  [Pluggable("Other")]
  15:  public class InjectorTwo :IInjectable {
  16:      public string WhatsMyType()
  17:      {
  18:          return "I am InjectorTwo";
  19:      }
  20:  }

 

The Registrar method looks like:
   1:  public static void RegisterBySearchingAnAssembly()
   2:  {
   3:      ObjectFactory.Reset();
   4:      StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
   5:      StructureMapConfiguration.ScanAssemblies();
   6:  }

 David Hayden's post helped me a lot with this.

Hope this helps someone. It will probably help me when I forget one of these! :0)

Download the code here.

 

~Lee

I got tagged by Rob Reynolds && Doug Butscher with the "How I Got Started Programming" blog meme, so here is my story.

How old were you when you started programming?

I wrote my first BASIC program when I was 10. It was a program that scrolled test from the bottom to the top of the screen. I think it was on a Trash-80.

What was your first language?

Basic. I did it with the Trash-80 and spent a summer taking a Basic programming class for Apple IIe. (I'm such a geek).

What was the first real program you wrote?

Back when I did that other programming, I didn't really care for it too much. Everything was text and boring, so I didn't really do much after that summer class when I was about 13, but there were always computers around my house cause my dad was a Network Admin for the government.

About 1993, I got my first real PC (had a LOT of Macs up until then), and my first AOL account (don't laugh). I thought it was fun, but no real way to make a living at it, so I continued my day job as a auto mechanic (not a certified one) and then got a job in a machine shop MAKING auto parts and writing programs that told the machine where to drill and mill to make the parts. That was my first professional programming gig (whether I knew it or not).

But my first REAL programming job was in 1998 when I rewrote SkillPath Seminars' website in ColdFusion 4.0.

If you knew then what you know now, would you have started programming?

Absotively. I would've started sooner. I think of all the time I spent trying to figure out what I wanted to do, and how I LOVE to code now and I think, "What took you so freaking long?!!?"

If there is one thing you learned along the way that you would tell new developers, what would it be?

Start with a low-level language (like Assembly). It may be boring and you may not be able to make the cool stuff (without a LOT of work), but it will give you an understanding of memory management and how computers do what they do that will be invaluable later in your career. I STILL want to go back and do some serious Assembly or ANSI-C programming to really deepen my knowledge of that stuff.

What's the most fun you've ever had ... programming?

Working at Premier Studios, I got to help create an IT department where none existed before. As a team, we decided what technologies to use, we created a code base and standards and experimented with methodologies and basically turned it into a REAL profit center for the company. I LOVED that.

tagged next:

I have looked at others' strategies for arranging projects within a solution, and I have experimented with my own until I cam up with the following (mostly based on my own OCD about organization, but somewhat based on actual development reasoning).

I must preempt by saying that I am using the MVP pattern for my projects, so that influences my arrangement somewhat. I will also say that I enjoy using periods in my project names. Mostly because it looks clean to me, but also because I have a need sometimes for using projects in multiple solutions. This need led to several decisions that some people may not agree with. when deciding what things go in a particular project, I useProjectStructure that as my guideline: If I have to move this project to another solution, will I need to take this with it? I may have a data and domain project that is called [CompanyName].Data and [CompanyName].Domain and use those in three or four different solutions for different software I develop for them. Then I may have a [ProjectName].NHibernate.Data project in that solution as well.

First, I have four basic projects: [ProjectName].Domain, [ProjectName].Data, [ProjectName].Presentation and [ProjectName].UI. The Domain project is my business objects and logic layer. anything that has to do with the business domain of the project and will only be used with that project. The Presentation project has my presenters in it (pretty straight forward). My Data project is the Interfaces that my presenters will use for data access and will get its implementation from a project with concrete classes in it. Finally, my UI project contains the interfaces that my presenters will use to display data. I will have one or more projects that contains concrete implementations for these interfaces.

I will add test projects for each of these. At first glance, this seems like an inordinate amount of projects in a solution. I've seen lots of developers add one project called UnitTests to a solution and have folders organizing the unit tests for each project. That's not bad, but what if I need to take that project to another solution? I want to take the unit tests for it with me, but I don't want to take ALL the unit tests with me, so that VSProjectStructure won't work for me. I could also add a UnitTests folder to each project. This is a little bit better. It would definitely cut down on the amount of projects in my solution. The problem I have with it is that tests are supposed to simulate how a user or another object interacts with that object or interface. With my tests INSIDE my project, I might get a test that passes because it is within the same assembly as the system under test (SUT). I choose to make separate assemblies for my tests to give myself greater confidence that the SUT will work as expected when I am ready to deliver the software (and that's what TDD is all about). I also use a Solution Folder to organize my test projects away from the code projects. This is only due to my own OCD and the ability to collapse the folder and only look at the code projects in the solution.

Now there are some things I don't like about my organization, but I haven't found a better solution (here's where you come in). I'll have a concrete Data project (e.g. [ProjectName].NHibernate.Data) this will have a test project (e.g. [ProjectName].NHibernate.Data.Test). This LOOKS the same as all the other unit test projects, but this is technically an integration test (testing to see if my project integrates with the database), so it's possible it could use another convention to distinguish it. It may not. I also STILL think there are probably too many projects in my solution (or at least the potential for lots), but every separation has been made for a reason.

 

~Lee

About a month ago I bought a new keyboard for my home computer, and I loved it so much I immediately went and got one for work. These keyboards are awesome!!

Let me qualify that by saying that I DO NOT TYPE CORRECTLY! I am a mile-a-minute, hunt-and-peck typist. My fingers start our over the home row, but they do not move the way they're supposed to.

That said, this keyboard is a monster!. the action is just right for me, the keys are cushioned just enough that when I type I feel in total control. I'm addicted. The absolute best part about these keyboards? They're only $20!!!

What's you're favorite keyboard?

I know this is a fluff post, but things are really getting busy. More substantial posts coming very soon!

~Lee