TDD and Dependency Injection with ASP.NET MVC

One of the guiding principles in the design of the new ASP.NET MVC Framework is enabling TDD (Test Driven Development) when building a web application. If you want to follow along, this post makes use of ASP.NET MVC CodePlex Preview 4 which you’ll need to install from CodePlex. I’ll try and keep this post up to date with the latest releases, but it may take me time to get around to it.

This post will provide a somewhat detailed walk-through of building a web application in a Test Driven manner while also demonstrating one way to integrate a Dependency Injection (DI) Framework into an ASP.NET MVC app. At the very end, you can download the code.

I chose StructureMap 2.0 for the DI framework simply because I’m familiar with it and it requires very little code and configuration. If you’re interested in an example using Spring.NET, check out Fredrik Normen’s post. I’ll try and post code examples in the future using Castle Windsor and ObjectBuilder.

Start Me Up! with apologies to The Rolling Stones

Once the CTP is released and you have it installed, open Visual Studio 2008 and select the File | New Project menu item. In the dialog, select the ASP.NET MVC Web Application project template.

New Project

At this point, you should see the following unit test project selection dialog.

Select Unit Test Project

In a default installation, only the Visual Studio Unit Test project option is available. But MbUnit, xUnit.NET and others have installers available to get their test frameworks in this dialog.

As you might guess, I’ll start off building the canonical blog demo. I am going to start without using a database. We can always add that in later.

The first thing I want to do is add a few classes to the main project. I won’t add any implementation yet, I just want something to compile against. I’m going to add the following:

  • BlogController.cs to the Controllers directory
  • IPostRepository.cs to the Models directory
  • Post.cs to the Models directory
  • BlogControllerTests to the MvcApplicationTest project.

After I’m done, my project tree should look like this.

 Project Tree

At this point, I want to implement just enough code so we can write a test. First, I define my repository interface.

using System;
using System.Collections.Generic;

namespace MvcApplication.Models
{
  public interface IPostRepository
  {
    void Create(Post post);

    IList<Post> ListRecentPosts(int retrievalCount);
  }
}

Not much of a blog post repository, but it’ll do for this demo. When you’re ready to write the next great blog engine, you can revisit this and add more methods.

Also, I’m going to leave the Post class empty for the time being. We can implement that later. Let’s implement the blog controller next.

using System;
using System.Web.Mvc;

namespace MvcApplication.Controllers 
{
  public class BlogController : Controller 
  {
    public ActionResult Recent() 
    {
      throw new NotImplementedException("Wait! Gotta write a test first!");
    }
  }
}

Ok, we better stop here. We’ve gone far enough without writing a unit test. After all, I’m supposed to be demonstrating TDD. Let’s write a test.

Let’s Get Test Started, In Here. with apologies to the Black Eyed Peas

Starting with the simplest test possible, I’ll make sure that the Recent action does not specify a view name because I want the default behavior to apply (this snippet assumes you’ve imported all the necessary namespaces).

[TestClass]
public class BlogControllerTests 
{
  [TestMethod]
  public void RecentActionUsesConventionToChooseView() 
    {
    //Arrange
    var controller = new BlogController();

    //Act
    var result = controller.Recent() as ViewResult;

    //Assert
    Assert.IsTrue(String.IsNullOrEmpty(result.ViewName));
  }
}

When I run this test, the test fails.

failed-test

This is what we expect, after all, we haven’t yet implemented the Recent method. This is the RED part of the RED, GREEN, REFACTOR rhythm of TDD.

Let’s go and implement that method.

public ActionResult Recent() 
{
  //Note we haven’t yet created a view
  return View();
}

Notice that at this point, we’re focusing on the behavior of our app first rather than focusing on the UI first. This is a stylistic difference between ASP.NET MVC and ASP.NET WebForms. Neither one is necessarily better than the other. Just a difference in approach and style.

Now when I run the unit test, it passes.

passing-test 

Ok, so that’s the GREEN part of the TDD lifecycle and a very very simple demo of TDD. Let’s move to the REFACTOR stage and start applying Dependency Injection.

It’s Refactor Time! with apologies to the reader for stretching this theme too far

In order to obtain the recent blog posts, I want to provide my blog controller with a “service” instance it can request those posts from. 

At this point, I’m not sure how I’m going to store my blog posts. Will I use SQL? XML? Stone Tablet?

Dunno. Don’t care... yet.

We can delay that decision till the last responsible moment. For now, I’ll create a repository abstraction to represent how I will store and retrieve blog posts in the form of an IPostRepository interface. We’ll update the blog controller to accept an instance of this interface in its constructor.

This is the dependency part of Dependency Injection. My controller now has a dependency on IPostRepository. The injection part refers to the mechanism you use to pass that dependency to the dependent class as opposed to having the class create that instance directly and thus binding the class to a specific implementation of that interface.

Here’s the change to my BlogController class.

public class BlogController : Controller 
{
  IPostRepository repository;

  public BlogController(IPostRepository repository) 
  {
    this.repository = repository;
  }

  public ActionResult Recent() 
  {
    //Note we haven’t yet created a view
    return View();
  }
}

Great. Notice I haven’t changed Recent yet. I need to write another test first. This will make sure that we pass the proper data to the view.

Note: If you're following along, you’ll notice that the first test we wrote won't compile. Comment it out for now. We can fix it later.

I’m going to use a mock framework, so before I write this test, I need to reference Moq.dll in my test project, downloaded from the MoQ downloads page.

Note: I’ve included this assembly in the example project at the end of this post.

Here’s the new test.

[TestMethod]
public void BlogControllerPassesCorrectViewData() 
{
  //Arrange
  var posts = new List<Post>();
  posts.Add(new Post());
  posts.Add(new Post());

  var repository = new Mock<IPostRepository>();
  repository.Expect(r => r.ListRecentPosts(It.IsAny<int>())).Returns(posts);

  //Act
  BlogController controller = new BlogController(repository.Object);
  var result = controller.Recent() as ViewResult;

  //Assert
  var model = result.ViewData.Model as IList<Post>;
  Assert.AreEqual(2, model.Count);
}

What this test is doing is dynamically stubbing out an implementation of the IPostRepository interface. We then tell it that no matter what argument is passed to ListRecentPosts, return two posts. We can then pass that stub to our controller.

Note: We haven’t yet needed to implement this interface. We don’t need to yet. We’re interested in isolating our test to only test the logic in the action method, so we fake out the interface for the time being.

At this point, the test fails as we expect. We need to refactor Recent to do the right thing now.

public ActionResult Recent() 
{
  IList<Post> posts = repository.ListRecentPosts(10); //Doh! Magic Number!
  return View(posts);
}

Now when I run my test, it passes!

Inject That Dependency

But we’re not done yet. When I load up a browser and try to navigate to this controller action (on my machine, http://localhost:64701/blog/recent/), I get the following error page.

No parameterless constructor defined for this object. - Mozilla Firefox

Well of course it errors out! By default, ASP.NET MVC requires that controllers have a public parameter-less constructor so that it can create an instance of the controller. But our constructor requires an instance of IPostRepository. We need someone, anyone, to pass such an instance to our controller.

StructureMap (or DI framework of your choice) to the rescue!

Note: Make sure to download and reference the StructureMap.dll assembly if you’re following along. I've included the assembly in the source code at the end of this post.

The first step I’m going to do is create a StructureMap.config file and add it to the root of my application. Here are the contents of the file.

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap>
  <Assembly Name="MvcApplication" />
  <Assembly Name="System.Web.Mvc
              , Version=1.0.0.0
              , Culture=neutral
              , PublicKeyToken=31bf3856ad364e35" />

  <PluginFamily Type="System.Web.Mvc.IController" 
                Assembly="System.Web.Mvc
                  , Version=1.0.0.0
                  , Culture=neutral
                  , PublicKeyToken=31bf3856ad364e35">
    <Plugin Type="MvcApplication.Controllers.BlogController" 
            ConcreteKey="blog" 
            Assembly="MvcApplication" />
  </PluginFamily>

  <PluginFamily Type="MvcApplication.Models.IPostRepository" 
                Assembly="MvcApplication" 
                DefaultKey="InMemory">
    <Plugin Assembly="MvcApplication" 
            Type="MvcApplication.Models.InMemoryPostRepository" 
            ConcreteKey="InMemory" />
  </PluginFamily>

</StructureMap>

I don’t want to get bogged down in describing this file in too much detail. If you want a deeper understanding, check out the StructureMap documentation.

The bare minimum you need to know is that each PluginFamily node describes an interface type and a key for that type. A Plugin node describes a concrete type that will be used when an instance of the family type needs to be created by the framework.

For example, in the second PluginFamily node, the interface type is  IPostRepository which we defined. The concrete type is InMemoryPostRepository. So anytime we use StructureMap to construct an instance of a type that has a dependency on IPostRepository, StructureMap will pass in an instance of InMemoryPostRepository.

Well if that’s true, we better then create that class. Normally, I would use a SqlPostRepository. But for purposes of this demo, we’ll store blog posts in memory using a static collection. We can always implement the SQL version later.

Note: This is where I would normally write tests for InMemoryPostRepository but this post is already long enough, right? Don’t worry, I included unit tests in the downloadable code sample.

public class InMemoryPostRepository : IPostRepository
{
  //simulates database storage
  private static IList<Post> posts = new List<Post>();

  public void Create(Post post)
  {
    posts.Add(post);
  }

  public System.Collections.Generic.IList<Post> 
    ListRecentPosts(int retrievalCount)
  {
    if (retrievalCount < 0)
      throw new ArgumentOutOfRangeException("retrievalCount"
          , "Let’s be positive, ok?");

    IList<Post> recent = new List<Post>();
    int recentIndex = posts.Count - 1;
    for (int i = 0; i < retrievalCount; i++)
    {
      if (recentIndex < 0)
        break;
      recent.Add(posts[recentIndex--]);
    }
    return recent;
  }

  public static void Clear()
  {
    posts.Clear();
  }
}

Quick, We Need A Factory

We’re almost done. We now need to hook up StructureMap to ASP.NET MVC by writing implementing IControllerFactory. The controller factory is responsible for creating controller instances. We can replace the built in logic with our own factory.

public class StructureMapControllerFactory : DefaultControllerFactory
{
  protected override 
    IController CreateController(RequestContext requestContext, string controllerName) 
  {
    try
    {
      string key = controllerName.ToLowerInvariant();
      return ObjectFactory.GetNamedInstance<IController>(key);
    }
    catch (StructureMapException)
    {
      //Use the default logic.
      return base.CreateController(requestContext, controllerName);
    }
  }
}

Finally, we wire it all up together by adding the following method call within the Application_Start method in Global.asax.cs.

protected void Application_Start() {
  ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());

  RegisterRoutes(RouteTable.Routes);
}

And we’re done! Now that we have hooked up the dependency injection framework into our application, we can revisit our site in the browser (after compiling) and we get...

View Not Found Message

Excellent! Despite the Yellow Screen of Death here, this is a good sign. We know our dependency is getting injected because this is a different error message than we were getting before. This one in particular is informing us that we haven’t created a view for this action. So we need to create a view.

Sorry! Out of scope. Not in the spec.

I leave it as an exercise for the reader to create a view for the page, or you can look at the silly simple one included in the source download.

Although this example was a ridiculously simple application, the principle applies in building a larger app. Just take the techniques here and rinse, recycle, repeat your way to TDD nirvana.

To see the result of all this, download the source code.

What others have said

Requesting Gravatar... Evan Dec 07, 2007 1:23 PM
# re: TDD and Dependency Injection with ASP.NET MVC
You rock! ;-)
Requesting Gravatar... Jeffrey Palermo Dec 07, 2007 1:46 PM
# re: TDD and Dependency Injection with ASP.NET MVC
@Phil,
The first item to get committed to the trunk of mvccontrib was a StructureMapControllerFactory.

You can check it out here:http://www.codeplex.com/MVCContrib

We're going to go public and advertise more once we can build against the public CTP. Then it will make more sense for the public to use it.
Requesting Gravatar... Fredrik Normén Dec 07, 2007 3:23 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Your blog post is so much nicer than mine ;)

Something that I don’t like is that the ControllerFactory will get the Type of the Controller. You need here as with Spring.Net use the Type.Name to get the name and let another framework once again locate the type and then create an instance of the controller. I think it’s the ControllerFactory’s responsibility to locate the Controller and that you should make sure to pass the name of the controller as the argument to the factory, not the type.
Requesting Gravatar... Haacked Dec 07, 2007 4:31 PM
# re: TDD and Dependency Injection with ASP.NET MVC
@Fredrik - Yes, I saw your comment in Connect. I thought I responded to it. We'll change that in the next milestone. Thanks for submitting the feedback! :)
Requesting Gravatar... DotNetKicks.com Dec 07, 2007 6:56 PM
# TDD and Dependency Injection with ASP.NET MVC
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Requesting Gravatar... Jeremy D. Miller Dec 08, 2007 2:25 AM
# re: TDD and Dependency Injection with ASP.NET MVC
Cool post, says the horribly biased guy.

Just so folks with angle bracket allergies know, you don't have to use Xml configuration for the simple use cases with StructureMap anymore:

http://codebetter.com/blogs/jeremy.miller/archive/2007/04/09/Introduction-to-StructureMap-2.0-_2800_Part-1_2900_.aspx
Requesting Gravatar... ScottGu's Blog Dec 08, 2007 4:14 AM
# December 8th Links: ASP.NET, ASP.NET AJAX, ASP.NET MVC, .NET, VS 2008
Here is the latest in my link-listing series .&amp;#160; Also check out my ASP.NET Tips, Tricks and Tutorials
Requesting Gravatar... Sean Chambers Dec 08, 2007 4:44 AM
# re: TDD and Dependency Injection with ASP.NET MVC
Excellent stuff Phil!

I am definately looking forward to this. Even though I am very biased and love monorail. I think you guys have finally hit the nail on the head this time. Couple this with the fact that you are now at MS, I think this will be very good! =)

The only thing I really don't like, and I'm sure you've heard this already, is the fact that every action requires a [ControllerAction] attribute. IMO, this is a lot of extra typing that isn't necessarily needed. I know you guys are trying to help out by making sure the developer knows what exactly they are exposing, but education would be more powerful here than requiring a specific attribute on every method. Just my 2 cents tho!

Is there anyway that we can make it so any public methods are automatically set as actions in a configuration or something along those lines?

Also, is there a way to set values to send back to the view in an array rather than passing them to RenderView? Like PropertyBag[] in MonoRail?

Other then that everything looks pretty good! Great Job!! Looking forward to the CTP
Requesting Gravatar... Sean Chambers Dec 08, 2007 4:59 AM
# Phil Haack posts about ASP.NET MVC
Phil Haack has a tutorial type post of usage of the new MS MVC with TDD, DI and the Repository Pattern
Requesting Gravatar... Haacked Dec 08, 2007 6:31 AM
# re: TDD and Dependency Injection with ASP.NET MVC
@Sean - thanks for the feedback. Yep, I've heard a lot about the [ControllerAction] attribute from some people. Rather than attempt to address it everytime it comes up, I'll write a blog post that addresses that single item.

Keep in mind though, we'd love to hear feedback on other areas of the framework. It seems that one thing gets a disproportionate amount of attention. I have to say, if that's the only thing we get "wrong", then I'm happy. But I would bet there are bigger things we missed and I hope to hear feedback on them when the CTP is released.
Requesting Gravatar... Javier Lozano Dec 08, 2007 6:47 AM
# re: TDD and Dependency Injection with ASP.NET MVC
Phil, great post! I've always liked your style of writing. You're very good at taking abstract concepts and explain them in terms people can relate to.

This is a great asset for people trying to grok the benefits of using ASP.NET MVC!
Requesting Gravatar... Jason Haley Dec 08, 2007 12:11 PM
# Interesting Finds: December 8, 2007
Requesting Gravatar... Christopher Steen Dec 08, 2007 2:20 PM
# Link Listing - December 8, 2007
ASP.NET TDD and Dependency Injection with ASP.NET MVC [Via: Haacked ] Link Blogs Silverlight Cream...
Requesting Gravatar... Tony Testa's World Dec 08, 2007 3:16 PM
# ASP.NET MVC Framework (Delayed)
ASP.NET MVC Framework (Delayed)
Requesting Gravatar... ScottGu's Blog Dec 09, 2007 12:55 PM
# ASP.NET 3.5 Extensions CTP Preview Released
Earlier today we released the first CTP preview of an &amp;quot;ASP.NET 3.5 Extensions&amp;quot; release that
Requesting Gravatar... Marlon Grech Dec 09, 2007 2:55 PM
# re: TDD and Dependency Injection with ASP.NET MVC
This is totally cool... You are the BEST!!!!!
Requesting Gravatar... Maor David Dec 09, 2007 6:54 PM
# ASP.NET 3.5 Extensions Preview Released
The ASP.NET 3.5 Extensions Preview is a preview of new functionality being added to ASP.NET 3.5 and ADO
Requesting Gravatar... Javier-Romero Dec 09, 2007 10:04 PM
#
ASP.NET 3.5 Extensions CTP Preview Lanzado ...
Requesting Gravatar... Eilon Lipton's Blog Dec 10, 2007 10:30 AM
# ASP.NET MVC Design Philosophy
This week the first preview of the ASP.NET MVC framework was released to the web as part of the ASP.NET
Requesting Gravatar... di .NET e di altre Amenit Dec 11, 2007 4:44 PM
# ASP.NET 3.5: Un po' di link alla rinfusa #4
ASP.NET 3.5: Un po' di link alla rinfusa #4
Requesting Gravatar... Matt Blodgett Dec 12, 2007 12:02 AM
# re: TDD and Dependency Injection with ASP.NET MVC
As a neophyte interested in unit testing and dependency injection, I have to admit that I'm really taken aback by the amount of _stuff_ you had to write to get this simple bit of functionality set up.

I'm struggling to understand how it could possibly be worth it. Would someone please enlighten me?
Requesting Gravatar... Haacked Dec 12, 2007 1:15 AM
# re: TDD and Dependency Injection with ASP.NET MVC
@Matt You should search my blog for TDD and you'll see I've written extensively about the benefits of TDD.

AS for this example, I was taking an extremely detailed "first-principles" style approach. So in the real-world, the code would be much less in the test by employing helper methods and the like.

Also, some of the extra verbosity may be due to issues in the ASP.NET MVC design we plan to improve.
Requesting Gravatar... StevenHarman.net Dec 12, 2007 1:54 PM
# TDD DI ASP.NET MVC Made Better with StructureMap's Fluent API, Oh My!
TDD DI ASP.NET MVC Made Better with StructureMap's Fluent API, Oh My!
Requesting Gravatar... nibblers revenge Dec 18, 2007 11:24 PM
# ASP.NET 3.5 Extensions CTP Preview Released
ASP.NET 3.5 Extensions CTP Preview Released
Requesting Gravatar... Developer Blogs Dec 20, 2007 11:42 PM
# ASP.NET 3.5 Extensions CTP Preview Released
Earlier today we released the first CTP preview of an &amp;quot;ASP.NET 3.5 Extensions&amp;quot; release that
Requesting Gravatar... My World Jan 03, 2008 2:14 PM
# TDD for ASP.NET MVC using StructureMap
Ok, so I just posted less than an hour ago, but now I've found something worth talking about. :) After
Requesting Gravatar... HUMAN-DEBUGGER.NET Jan 05, 2008 7:25 AM
# MVC (asp.net MVC Framework) - Controller Factory 2
Requesting Gravatar... Omid Zaman Jan 06, 2008 7:46 AM
#
ASP.NET MVC Is Available (CTP)
Requesting Gravatar... RainSunny Jan 09, 2008 12:54 PM
# ASP.NET 3.5 Extensions CTP Preview Released
Requesting Gravatar... HUMAN-DEBUGGER.NET Jan 14, 2008 3:55 AM
# MVC (asp.net MVC Framework) - Controller Factory
Requesting Gravatar... HUMAN-DEBUGGER.NET Jan 17, 2008 3:55 PM
# MVC (asp.net MVC Framework) - Controller Factory
Requesting Gravatar... ASP.NET Chinese Blogs Jan 18, 2008 2:16 AM
# ASP.NET 3.5 Extensions CTP预览版发布了
【原文地址】 ASP.NET 3.5 Extensions CTP Preview Released 【原文发表日期】 Sunday, December 09, 2007 8:55 PM 今天早些时候
Requesting Gravatar... Basharat Hussain Jan 20, 2008 3:09 PM
# TDD and Dependency Injection with ASP.NET MVC - error in compilation
Hi,
I could not compile the sample. I have following errors in config files. Please help me in this regard.
In StructureMap.config file - <StructureMap> says element is not declared
In Web.Config file - <dynamicData attribute gives following error "the element 'system.web.extensions' has invalid child dynamicData, List of possible elements expected: 'Scripting'"

Please guide me to solve these issues. thanks.

BR/Bash


Requesting Gravatar... Noticias externas Jan 22, 2008 5:38 PM
# ASP.NET ed i Patterns: ASP.NET MVC (Model, View, Controller) Framework (Parte 2)
Nella prima parte del post ho introdotto il nuovo ASP.NET MVC Framework fino all&amp;#39;implementazione
Requesting Gravatar... CodeClimber Jan 28, 2008 3:04 AM
# ASP.NET MVC Link collection
ASP.NET MVC Link collection
Requesting Gravatar... Nick Berardi Jul 25, 2008 3:27 AM
# re: TDD and Dependency Injection with ASP.NET MVC
Thanks for the source, I have just got started on TDD and basically the Alt.NET way of doing things. So I am hoping this will help me move in the right direction.
Requesting Gravatar... Praveen Angyan Aug 25, 2008 8:06 AM
# I think I am missing a crucial point here.
So, I finally get it. It all snapped into place: DI, Mocking, using Interfaces for the parts of the code that we want to decouple etc. I've been rereading this post and others for the past two weeks and I suddenly got it and started using it in my production code.

However there is one crucial point I'm missing here in this method: BlogControllerPassesCorrectViewData

Isn't the whole point of writing an InMemoryPostRepository class to be able to use it in the unit tests, more specifically in BlogControllerPassesCorrectViewData in your case? This would get rid of a whole lot of code required for mocking, the tests would still run as fast. What do you lose by coupling your unit test to a lightweight repository instance?

This really came up because when I tested an action that takes values from an HTML form and creates a new entry in the repository and I used your patterns, I had a whole lot of code to mock the different instances. And in the end I couldn't even test a crucial bit of functionality.



Requesting Gravatar... Shay Jacoby Oct 12, 2008 11:06 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Hi, Thanks for the article.
I think that your StructureMapControllerFactory class is not a good idea because it generates exception (doesn't matter if You put try/catch) on every unmapped controller.
Requesting Gravatar... serhat Dec 03, 2008 2:01 AM
# re: TDD and Dependency Injection with ASP.NET MVC
How about if I go like this:

private IPostRepository repository;

BlogController()
{
this.repository = new InMemoryPostRepository();
/* or new RepositoryFactory().GetRepository(SomeResource.DefaultRepositoryName); */
}

BlogController(IPostRepository repository)
{
this.repository = repository;
}

And use the latter constructor when testing, so I do not need to use StructureMap and do not bother writing config files?
Requesting Gravatar... Ben Norman Dec 04, 2008 6:15 AM
# re: TDD and Dependency Injection with ASP.NET MVC
I have not been able to move your sample to StructureMap 2.5. The DataContext is not able to find the ConnectionString. What are the chances of another 20 minutes on StructureMap 2.5 and if possible without a config file.
Requesting Gravatar... Marko Jan 26, 2009 9:51 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Wow!
Great post :)
Requesting Gravatar... Jei Feb 09, 2009 2:57 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Hi Phil,

I have been keenly following the use of StructureMap as an IOC container for Dependency Injection. I have looked at illustrations by Jeremy Miller and Rob Connery among others and I get expect results when I do the injection from code but not when I try to use StructureMap.config. For instance, with your sample here, an exception is thrown at the line:

return ObjectFactory.GetNamedInstance<IController>(key);

in StructureMapControllerFactory class. The following are the exception details:

StructureMap configuration failures:
Error: 210
Source:
The designated default instance 'InMemory' for PluginType MvcApplication.Models.IPostRepository, MvcExample1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null cannot be found.

am using StructureMap Version 2.5.3 (I don't know whether this might be the problem)
... Sorry for reviving this blog.

Best Regards,
Jei.

Requesting Gravatar... Dsmacks May 02, 2010 10:00 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Great post, easy to read and follow! However the download source code link isn't working.
Requesting Gravatar... Tombo Jun 27, 2011 9:04 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Can't seem to get the download to work! :\
Requesting Gravatar... Vivien Adnot Aug 11, 2011 9:25 PM
# re: TDD and Dependency Injection with ASP.NET MVC
Hi Phil,

Your article is excellent but the download link doesn't work.

I've read a bit of StructureMap documentation and I found these

ObjectFactory.Initialize(x =>

{

x.ForRequestedType<IRepository>().Use<Repository>()

.WithCtorArg("connectionString").EqualTo("a connection string");



// Or, since it's smelly to embed a connection string directly into code,

// we could pull the connection string from the AppSettings

x.ForRequestedType<IRepository>().Use<Repository>()

.WithCtorArg("connectionString").EqualToAppSetting("CONNECTION-STRING");

});


var repository = ObjectFactory.GetInstance<IRepository>();

This example seems pretty great too, it seems that the ugly xml file isn't necessary anymore. Do you agreee with that ?
Requesting Gravatar... Don Rolling Jan 13, 2012 4:21 AM
# re: TDD and Dependency Injection with ASP.NET MVC
However you might feel about TDD, love it or hate it, you have to admit that it's a lot of work to setup.

The funny thing is that it doesn't keep errors from occurring.

The funnier thing is that the link to the code download on this site is currently broken and I can't download it.

I guess you should have written a test that Asserts that your links are valid. :)

What do you have to say?

(will show your gravatar)
Please add 7 and 8 and type the answer here: