Peter Miller

in

Making Visual Studio and Dependency Injection Play Nice

Dependency injection (DI) is a powerful technique to make your code more testable and your application more adaptable to future changes. Working with an application that uses DI in Visual Studio can be painful. You want to be able to make changes to your dependencies, and have those changes automatically picked up and put in the right place, so that when your application tries to find them, it uses the latest version. And you want that all to happen just when you press F5 to debug.

I posted a question to stackoverflow.com about this, laying out some options, including copying files by hand or creating a post build event per dependency per application. In keeping with stackoverflow rules about open ended questions, I quickly marked an answer as accepted.

The answer I accepted was to change the output directories of the dependency projects to some common folder, which the application would then query for dependencies at runtime:

diBin

This sounded good, but after some thought, I was worried about the unintended consequences of having these projects not build to the normal bin/debug, bin/release folders.

After some experimentation, I ended up with a solution that is similar in spirit, but leaves the normal build output directory alone:

  1. Add post build events to each dependency project to copy the dll and pdb files to a common directory
    1. xcopy  $(TargetDir)*.dll $(SolutionDir)diBin /iy
      xcopy  $(TargetDir)*.pdb $(SolutionDir)diBin /iy
  2. Add a post build event to the application project to copy the DI dll and pdb files to a subdirectory of its bin
    1. xcopy $(SolutionDir)\diBin\*.dll $(TargetDir)diBin\ /iy
      xcopy $(SolutionDir)\diBin\*.pdb $(TargetDir)diBin\ /iy
  3. We use Castle Windsor for DI and to see the dependency files in diBin\ I had to add this to the app.config:
    1. <runtime>
          <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
               <probing privatePath="diBin"/>
         </assemblyBinding>
      </runtime>

All of the projects in our solution live one level below the solution, and all are solutions are in the same folder, so $(SolutionDir) is common.

So far this has worked well. This does NOT solve anything having to do with deployment, but it does make the F5 debug experience much nicer.

 

Relevant Links:

Stack Overflow: How do I get a smooth debug experience in visual studio 2008 when using dependency injection?

MSDN documentation on the probing element

Posted: Jan 14 2010, 07:56 PM by pmiller | with 2 comment(s)
Filed under:

Comments

Tim Byrne said:

What sort of consequences were you worried about with having the projects not build to the normal bin/debug bin/release folders?  I typically go the 'build-to-a-common-folder' route, and haven't really experienced any issues but would gladly change my ways if there was some risk involved...

# January 15, 2010 7:26 AM

pmiller said:

I have a slight worry that it would break some TeamBuild scripts we set up earlier where we were plucking the dependencies out of their original output directories. So nothing in particular is wrong with the 'build to a common folder' route, I just was being extra cautious working in an already evolved code ecosystem.

# January 15, 2010 8:52 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)