<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John Bennett&#039;s blog &#187; dependency-injection</title>
	<atom:link href="http://jtbennett.com/blog/tag/dependency-injection/feed" rel="self" type="application/rss+xml" />
	<link>http://jtbennett.com/blog</link>
	<description>Software and web development</description>
	<lastBuildDate>Tue, 08 Feb 2011 00:50:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex,follow" />
		<item>
		<title>What is dependency injection?</title>
		<link>http://jtbennett.com/blog/2009/02/what-is-dependency-injection</link>
		<comments>http://jtbennett.com/blog/2009/02/what-is-dependency-injection#comments</comments>
		<pubDate>Mon, 16 Feb 2009 22:29:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dependency-injection]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2009/02/what-is-dependency-injection/</guid>
		<description><![CDATA[[I recently wrote this up for some folks at work, and thought it was worth re-posting here.] Dependency injection is a hot topic these days.&#160; You hear terms like &#8220;dependency injection&#8221;, &#8220;inversion of control&#8221;, &#8220;IoC container&#8221;, &#8220;DI container&#8221;, etc. a &#8230; <a href="http://jtbennett.com/blog/2009/02/what-is-dependency-injection">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>[I recently wrote this up for some folks at work, and thought it was worth re-posting here.]</p>
<p>Dependency injection is a hot topic these days.&nbsp; You hear terms like &#8220;dependency injection&#8221;, &#8220;inversion of control&#8221;, &#8220;IoC container&#8221;, &#8220;DI container&#8221;, etc. a lot.&nbsp; But like with &#8220;SOA&#8221;, people tend to define the terms however suits them.&nbsp; I&#8217;m going to do the same. <img src='http://jtbennett.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>The first thing I want to do is distinguish between dependency injection and a container.&nbsp; <strong>Dependency injection is a pattern.</strong>&nbsp; You don&#8217;t need any software tools other than your favorite language and compiler to &#8220;do dependency injection.&#8221;&nbsp; The dependency injection pattern is a subcategory of the inversion of control (IoC) pattern.&nbsp; A lot of people use DI and IoC interchangeably, and that&#8217;s fine with me, as DI is by far the most common type of IoC.</p>
<p><strong>An container is a software tool.</strong>&nbsp; Examples of .NET IoC/DI containers are Spring.NET, StructureMap, Castle Windsor, Autofac, and Unity (part of Enterprise Library).&nbsp; While all of these have their own unique bits of functionality, they have a large overlap in that they are all container implementations.</p>
<p>An analogy: You&#8217;ve probably heard of the Repository design pattern for data access.&nbsp; And you&#8217;ve probably heard of object-relational mapping (ORM) tools like NHibernate, LLBLGen Pro, Linq to SQL and Entity Framework.&nbsp; The relationship between them is analogous to the relationship between the dependency injection design pattern and IoC container implementations:&nbsp; <strong>If you&#8217;re using the design pattern, the tool makes life easier for you.&nbsp; </strong>But it&#8217;s entirely possible to use the pattern without using the tool.</p>
<p>So what is the dependency injection design pattern?</p>
<p>Let&#8217;s start with the problem.&nbsp; Most classes have to collaborate with other classes in order to fulfill their responsibilities.&nbsp; But having one object instantiate another creates a hard dependency that can limit flexibility, testability, and transparency to consuming developers.</p>
<p>Let&#8217;s write some code for a big important Boss who asks her Gopher to go get lunch:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> PizzaService</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> DeliverFood()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>         <span style="color: #0000ff">return</span> <span style="color: #006080">"Large pepperoni."</span>;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span> }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Gopher</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> GetLunch()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>         var pizzaService = <span style="color: #0000ff">new</span> PizzaService();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span>         <span style="color: #0000ff">return</span> pizzaService.DeliverFood();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  15:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  16:</span> }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  17:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  18:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Boss</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  19:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  20:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> HaveLunch()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  21:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  22:</span>         var gopher = <span style="color: #0000ff">new</span> Gopher();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  23:</span>         var myLunch = gopher.GetLunch();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  24:</span>         <span style="color: #0000ff">this</span>.Eat(myLunch);</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  25:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  26:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  27:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Eat(<span style="color: #0000ff">string</span> food)</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  28:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  29:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  30:</span> }</pre>
</div>
</div>
<p>One big problem with this code is that the only thing the Boss can ever have for lunch is pizza.&nbsp; Another drawback to this code is that Gopher&#8217;s dependency on PizzaService is opaque and hidden.&nbsp; The only way to know there is a dependency is to open up the code of the Gopher class and read it.&nbsp; It doesn&#8217;t appear anywhere in the constructor or method signatures.&nbsp; We want as much as possible to be obvious and explicit.&nbsp; We don&#8217;t want developers using our APIs to have to sift through our code to figure out all the dependencies.</p>
<p>We can start to address the first concern by creating an ILunchService interface:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> ILunchService</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">string</span> DeliverFood();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span> }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> PizzaService : ILunchService</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> DeliverFood()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span>         <span style="color: #0000ff">return</span> <span style="color: #006080">"Large pepperoni."</span>;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span> }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Gopher</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  15:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  16:</span>     <span style="color: #0000ff">private</span> ILunchService lunchService;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  17:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  18:</span>     <span style="color: #0000ff">public</span> Gopher()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  19:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  20:</span>         lunchService = <span style="color: #0000ff">new</span> PizzaService();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  21:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  22:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  23:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> GetLunchForTheBoss()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  24:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  25:</span>         <span style="color: #0000ff">return</span> lunchService.DeliverFood();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  26:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  27:</span> }</pre>
</div>
</div>
<p>But we still have the same problem of pizza every day, because the Gopher is still creating the instance of PizzaService.&nbsp; Even if the Boss is a real pizza fanatic, we can&#8217;t unit test Gopher without actually having a pizza made and delivered.&nbsp; That could get pretty expensive.</p>
<p>In more real-world terms, we can&#8217;t write tests without creating and accessing real instances of expensive resources (like a database).&nbsp; That means the unit tests will be slow, and that&#8217;s very bad.&nbsp; We want to run hundreds or thousands of unit tests in a few seconds.&nbsp; Even with larger, slower integration tests we don&#8217;t actually want to have hundreds of pizzas delivered when our automated test suite runs every night&#8230;</p>
<p>And we also haven&#8217;t addressed the opaque dependency of Gopher on PizzaService.</p>
<p>So the next step is for the Gopher to require that somebody tell him what kind of lunch service to use.&nbsp; (This isn&#8217;t the most proactive gopher in the company.)</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Gopher</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">private</span> ILunchService lunchService;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>     <span style="color: #0000ff">public</span> Gopher(ILunchService lunchService)</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span>         <span style="color: #0000ff">this</span>.lunchService = lunchService;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> GetLunch()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span>         <span style="color: #0000ff">return</span> lunchService.DeliverFood();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span> }</pre>
</div>
</div>
<p><strong>At this point, we are using the dependency injection pattern in the Gopher class.</strong>&nbsp; Specifically, we are using <em>constructor injection</em>.&nbsp; That is, in our constructor, we are asking for someone to pass in (inject) an instance that we depend on.&nbsp; That&#8217;s all dependency injection is.&nbsp; Big words, simple concept.&nbsp; We&#8217;ve inverted the usual way things are done.&nbsp; Gopher doesn&#8217;t control how its dependencies are created, the consumer of Gopher does.&nbsp; &#8220;Inversion of control&#8221; is a fancy phrase for letting the consumer take control.</p>
<p>We could also have used <em>property injection</em> (setting a property value with the dependency) or <em>method injection</em> (passing the dependency as a parameter to a method).&nbsp; But the best practice is to use constructor injection for required dependencies &#8212; don&#8217;t allow someone to create an object if it doesn&#8217;t have its required dependencies fulfilled &#8212; and property injection for optional dependencies.&nbsp; Method injection is really only recommended when you&#8217;re adding a container implementation to an existing code base.&nbsp; It&#8217;s yucky (because it&#8217;s less obvious), and shouldn&#8217;t typically be used in new code.</p>
<p>There are two big benefits to our use of the dependency injection pattern at this point:&nbsp; First, the Boss can get any kind of lunch she wants by simply telling the Gopher what kind of service to use.&nbsp; And second, other developers who want to use the Gopher class can&#8217;t help but see that the Gopher depends on an ILunchService &#8212; you just can&#8217;t create a Gopher instance without one.&nbsp; This is the kind of explicit, obvious dependency we want.</p>
<p>But we still have a problem.&nbsp; We&#8217;ve made a pretty career-limiting move for the Gopher.&nbsp; We gave the Boss more work to do.&nbsp; The Boss now has to create the PizzaService in order to get lunch:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Boss</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> HaveLunch()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>         var pizzaService = <span style="color: #0000ff">new</span> PizzaService();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>         var gopher = <span style="color: #0000ff">new</span> Gopher(pizzaService);</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span>         var myLunch = gopher.GetLunch();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>         <span style="color: #0000ff">this</span>.Eat(myLunch);</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Eat(<span style="color: #0000ff">string</span> food)</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span> }</pre>
</div>
</div>
<p>You might say &#8220;That&#8217;s only one more line of code than the Boss had before.&#8221;&nbsp; Well, I&#8217;ve found that giving Bosses (or developers using your API) even a tiny bit more work to do is generally a bad idea.&nbsp; And while we&#8217;re on the subject, why should the Boss have to create the Gopher, too?&nbsp; The Gopher should <em>just be there</em>, ready to do the Boss&#8217;s bidding.&nbsp; In fact, isn&#8217;t the Boss <strong>dependent on</strong> the Gopher?</p>
<p>Oh, wait a minute, we already know what to do with hard dependencies caused by using the new operator &#8212; we use dependency injection:</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Boss</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">private</span> Gopher gopher;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>     <span style="color: #0000ff">public</span> Boss(Gopher gopher)</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span>         <span style="color: #0000ff">this</span>.gopher = gopher;</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   8:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   9:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  10:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> HaveLunch()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  11:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  12:</span>         var myLunch = gopher.GetLunch();</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  13:</span>         <span style="color: #0000ff">this</span>.Eat(myLunch);</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  14:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  15:</span>&nbsp; </pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  16:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Eat(<span style="color: #0000ff">string</span> food)</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  17:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  18:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">  19:</span> }</pre>
</div>
</div>
<p>We&#8217;ve applied the dependency injection pattern to the Boss, too, and another dependency (of Boss on Gopher) has been dragged into the light of day for all to see.&nbsp; In this case we haven&#8217;t created an IGopher interface, but that&#8217;s okay.&nbsp; Sometimes you don&#8217;t need to use an interface (although often you should).&nbsp; With or without an interface, developers using the Boss class now have a much clearer picture of what&#8217;s going on &#8212; without digging into the actual code.&nbsp; Everything is explicit and obvious.</p>
<p>You might start to wonder whether some objects that do a lot of things are going to have 10 constructor parameters.&nbsp; Well, yes.&nbsp; But that&#8217;s a code smell: if you have an object with that many dependencies, it&#8217;s probably doing too much.&nbsp; It&#8217;s very likely that it has multiple responsibilities, and your classes should typically adhere to the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> as much as possible.&nbsp; Split that class into several that each does one thing only.&nbsp; This makes your software easier to change, too.&nbsp; Smaller, simpler classes mean each class has fewer reasons to change, and fewer collaborators means fewer potential ripple effects when you do make changes.</p>
<p>Here&#8217;s one of the big ideas behind dependency injection:&nbsp; separating the object graph from the execution graph.&nbsp; In code where you see <font face="Consolas">new Foo()</font> all over the place, the object graph and the execution graph are tightly intertwined.&nbsp; That&#8217;s usually a bad thing, because objects rarely reference each other in the exactly the same hierarchical structure that they call each other&#8217;s methods.&nbsp; Testing or changing a little thing in that kind of code can be a real pain.</p>
<p>A common solution for separating object graph creation from the execution graph is to use <strong>factory classes</strong>.&nbsp; The Abstract Factory pattern is one of the older and better known design patterns.&nbsp; All of the instantiation and injection of the dependencies would happen in the factories, out of the way of your executing business logic.</p>
<div style="border-bottom: gray 1px solid; border-left: gray 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: consolas, 'Courier New', courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: gray 1px solid; cursor: text; border-right: gray 1px solid; padding-top: 4px">
<div style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px">
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> BossFactory</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   2:</span> {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> Boss GetBoss()</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   4:</span>     {</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   5:</span>         <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> Boss(<span style="color: #0000ff">new</span> Gopher(<span style="color: #0000ff">new</span> PizzaService()));</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   6:</span>     }</pre>
<pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: consolas, 'Courier New', courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060">   7:</span> }</pre>
</div>
</div>
<p>In this code, the boss is still having pizza every day for lunch, but it&#8217;s easy to imagine how we could use configuration or a UI input value to select a different implementation of ILunchService each day.&nbsp; The key is that the selection of that implementation doesn&#8217;t really have anything to do with the process of actually having lunch.&nbsp; And now our code separates those two processes very cleanly.</p>
<p>Further reading on dependency injection:</p>
<ul>
<li><a href="http://jamesshore.com/Blog/Dependency-Injection-Demystified.html">Dependency Injection Demystified</a> by James Shore
<li><a href="http://en.wikipedia.org/wiki/Dependency_injection">Dependency injection</a> on wikipedia
<li>Misko Hevery&#8217;s blog, especially
<ul>
<li><a href="http://misko.hevery.com/2008/11/11/clean-code-talks-dependency-injection/">Talk on dependency injection</a>
<li><a href="http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/">How to Think About the “new” Operator</a>
<li><a href="http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/">Singletons are Pathological Liars</a>
<li><a href="http://misko.hevery.com/code-reviewers-guide/">Guide: Writing Testable Code</a> </li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2009/02/what-is-dependency-injection/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Removing dependencies between controllers and Linq DataContext classes with dependency injection</title>
		<link>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection</link>
		<comments>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection#comments</comments>
		<pubDate>Sat, 22 Dec 2007 15:30:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[dependency-injection]]></category>
		<category><![CDATA[linq]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[mvccontrib]]></category>
		<category><![CDATA[mvctoolkit]]></category>
		<category><![CDATA[windsor]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection/</guid>
		<description><![CDATA[In ScottGu&#8217;s most recent post on ASP.NET MVC, he demonstrates using a partial class for the NorthwindDataContext created by the Linq to Sql designer.&#160; In the partial class he creates some simple wrapper methods for the ProductsController to use when &#8230; <a href="http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx">ScottGu&#8217;s most recent post on ASP.NET MVC</a>, he demonstrates using a partial class for the NorthwindDataContext created by the Linq to Sql designer.&nbsp; In the partial class he creates some simple wrapper methods for the ProductsController to use when retrieving and persisting data.&nbsp; However, the ProductsController is still tightly coupled to NorthwindDataContext.&nbsp; Let&#8217;s decouple them using an interface and some dependency injection&#8230;</p>
<p>If you want to follow along, you&#8217;ll need to <a href="http://www.scottgu.com/blogposts/mvc4/mvcapplication5.zip">download ScottGu&#8217;s sample</a>, which I&#8217;ll use as my starting point.&nbsp; The sample (MvcApplication5) uses the MvcToolkit, but I found I had to <a href="http://www.asp.net/downloads/3.5-extensions/MVCToolkit.zip">download MvcToolkit</a> and repair the reference to before I could successfully build and run the sample.</p>
<h3>Creating the IProductsRepository interface</h3>
<p>The first step is to create an IProductsRepository interface.&nbsp; We&#8217;ll use VS2008&#8242;s refactoring support to extract an interface from Scott&#8217;s NorthwindDataContext partial class.&nbsp; Open that file in the editor, right-click on the partial class declaration and choose Refactor &gt; Extract Interface.</p>
<p><a href="http://jtbennett.com/blog/wp-content/uploads/2010/07/1RefactorContextMenu_22.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="1-RefactorContextMenu_2[2]" border="0" alt="1-RefactorContextMenu_2[2]" src="http://jtbennett.com/blog/wp-content/uploads/2010/07/1RefactorContextMenu_22_thumb.png" width="244" height="174"></a> </p>
<p>Name the interface IProductsRepository and select just the five methods that Scott added in the partial class.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/2-ExtractInterfaceDialog_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Select methods to include in interface" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/2-ExtractInterfaceDialog_thumb.png" width="189" height="244"></a></p>
<p>That will create IProductsRepository.cs in the Models folder with the new interface.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/3-IProductsRepository_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="The new IProductsRepository interface" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/3-IProductsRepository_thumb.png" width="244" height="98"></a></p>
<p>It also adds the interface to the NorthwindDataContext declaration.&nbsp; Now we can go to the ProductsController in the Controllers directory and change the northwind field to be of type IProductsRepository.</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/4-ChangeFieldToInterface_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Change private field to interface type" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/4-ChangeFieldToInterface_thumb.png" width="244" height="141"></a></p>
<p>At this point, we have a problem.&nbsp; Both the Create() and Update() action methods call SubmitChanges() on the data context.&nbsp; When we try to build, the compiler tells us that the SubmitChanges method isn&#8217;t part of the IProductsRepository interface.&nbsp; The whole goal here is to reduce the coupling between the controller and the Linq-generated DataContext.&nbsp; So we&#8217;re going to move the Linq code into the partial class and access it through the interface we just created.</p>
<p>Let&#8217;s start with Create().&nbsp; Create() calls AddProduct() on the data context, which looks like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/6-AddProductMethodBefore_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="AddProduct() before" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/6-AddProductMethodBefore_thumb.png" width="244" height="31"></a></p>
<p>Let&#8217;s add a call to SubmitChanges() to AddProduct():</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/7-AddProductMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="AddProduct() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/7-AddProductMethodAfter_thumb.png" width="244" height="42"></a></p>
<p>We have to remove SubmitChanges() from Create():</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/8-CreateMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Create() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/8-CreateMethodAfter_thumb.png" width="244" height="70"></a></p>
<p>There is no method in our IProductsRepository interface that the controller can call when updating a product, so we&#8217;ll create a SaveProduct() method in the interface and implement it in NorthwindDataContext.&nbsp; The only thing our implementation of SaveProduct() will do is call SubmitChanges().&nbsp; So Update() looks like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/9-UpdateMethodAfter_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Update() after" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/9-UpdateMethodAfter_thumb.png" width="244" height="68"></a></p>
<p>And SaveProduct() like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/10-SaveProductMethod_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="SaveProduct() method" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/10-SaveProductMethod_thumb.png" width="244" height="33"></a></p>
<h3>Setting up for dependency injection with Windsor</h3>
<p>At this point, everything works as before, we&#8217;ve just added an interface and moved some calls to SubmitChanges().&nbsp; ProductsController and NorthwindDataContext are still tightly coupled.&nbsp; For the next part, we&#8217;re going to use <a href="http://en.wikipedia.org/wiki/Dependency_injection">dependency injection</a> and our new interface to break the coupling.&nbsp; For some background on dependency injection and why you might want to use it, see this article and links by <a href="http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html">James Shore</a>.</p>
<p>There are a number of tools that will do dependency injection for you.&nbsp; We&#8217;re going to use Windsor from the <a href="http://www.castleproject.org/">Castle Project</a>.&nbsp; We&#8217;ll also use MvcContrib, a community-driven project on CodePlex that is developing useful add-ons to ASP.NET MVC.&nbsp; One of those add-ons is a WindsorController, which allows us to easily use dependency injection on our controllers.</p>
<p>You&#8217;ll also need to download the latest release of the <a href="http://www.codeplex.com/MVCContrib/">MvcContrib project</a>.&nbsp; I&#8217;m using the beta version 0.0.1.32 in this sample.&nbsp; We need to add a couple of references to the MvcToolkit assemblies.&nbsp; When you download the binaries version, you&#8217;ll have a bin directory with the assemblies and a Samples directory with some code that we&#8217;ll use below.</p>
<p>Add references in MvcApplication5 to:</p>
<ul>
<li>Castle.Core.dll
<li>Castle.MicroKernel.dll
<li>Castle.Windsor.dll
<li>MvcContrib.dll
<li>MvcContrib.Castle.dll. </li>
</ul>
<p>Now we need to modify our Global.asax.cs file so that our web application automatically creates a Windsor Container.&nbsp; All of these changes are below are also shown in the sample app provided in the MvcContrib download.</p>
<ul>
<li>Add using statements for the Castle.Core and Castle.Windsor namespaces.
<li>Implement the IContainerAccessor interface, which has a single property named Container.
<li>Add a static field to hold the container, and a static property to wrap it. </li>
</ul>
<p>Here&#8217;s what they look like so far:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/12-ImplementIContainerAccessor_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Changes to Global.asax.cx" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/12-ImplementIContainerAccessor_thumb.png" width="244" height="199"></a></p>
<p>Next up is to instantiate the container and make it aware of all the controller classes in our application.&nbsp; This is done by looking for all types in the current assembly that can be cast to the IController interface.</p>
<ul>
<li>Add a using statement for the MvcContrib.ControllerFactories namespace.
<li>Copy in the InitializeWindsor() method from the sample app.
<li>Refactor the route handling setup from Application_Start() to a separate method named AddRoutes().
<li>Change the Application_Start() handler to call InitializeWindsor() and AddRoutes(). </li>
</ul>
<p>The end result in Global.asax.cs is:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-AddInitializeWindsorMethod_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InitializeWindsor() method" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-AddInitializeWindsorMethod_thumb.png" width="244" height="136"></a></p>
<p>Two changes to the sample code are required.&nbsp; The first change is to tell the WindsorContainer to use the web.config file to get the configuration values.&nbsp; We&#8217;ll go into the config settings in the next section.&nbsp; Here all we need to do is pass into the WindsorContainer constructor a new XmlInterpreter().&nbsp; This tells the container to use the current app.config or web.config file.</p>
<p>The sample uses a controller class named WindsorController to get access to the assembly containing all the controllers.&nbsp; Since we don&#8217;t have a WindsorController type, our second change is to:</p>
<ul>
<li>Add a using statement for the MvcApplication5.Controllers namespace.
<li>In the InitializeWindsor() method (line 42 in the screenshot) change &#8220;typeof(WindsorController)&#8221; to &#8220;typeof(HomeController)&#8221;.&nbsp; I use HomeController, since most ASP.NET MVC applications will have one of those. </li>
</ul>
<p>After these changes, the two lines in InitializeWindsor() look like this:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-InitializeWindsorChanges_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="InitializeWindsor() changes" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/13-InitializeWindsorChanges_thumb.png" width="244" height="19"></a></p>
<h3>Injecting the repository into ProductsController</h3>
<p>Getting back to our ProductsController class, remember that we changed the northwind field to be of type IProductsRepository, but we still populated it with an instance of NorthwindDataContext. What we want is for ProductsController to know nothing about NorthwindDataContext.&nbsp; Any class that implements IProductsRepository should work just fine for retrieving and saving products.</p>
<p>First, we&#8217;ll remove the assignment of the NorthwindDataContext instance.&nbsp; While doing this, we&#8217;ll change the field name from &#8220;northwind&#8221; to &#8220;repository&#8221; to make it more generic.&nbsp; VS2008&#8242;s refactoring support makes this a breeze.&nbsp; Then we&#8217;ll add a constructor that takes a parameter of type IProductsRepository.&nbsp; (Make sure the IProductsRepository interface is declared as public, since we didn&#8217;t do that earlier.)&nbsp; The result is:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/14-AddProductsControllerConstructor_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Add constructor for DI" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/14-AddProductsControllerConstructor_thumb.png" width="244" height="68"></a></p>
<p>We&#8217;re now ready to tell Windsor: &#8220;Whenever you create a ProductsController, pass a NorthwindDataContext into its constructor.&#8221;&nbsp; We do that through a config section in web.config.&nbsp; First declare a section for castle in the &lt;configSections&gt; element and add a &lt;castle&gt; element as follows:</p>
<p><a href="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/15-CastleWindsorConfig_2.png"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" alt="Configure Windsor" src="http://jtbennett.com/files/media/image/WindowsLiveWriter/InjectingMVCcontrollerswithaLINQdatacont_11F3E/15-CastleWindsorConfig_thumb.png" width="244" height="73"></a></p>
<p>What we&#8217;re telling Windsor here is that whenever a controller has a constructor parameter of type IProductsRepository, give it a new instance of NorthwindDataContext. </p>
<p>At this point, we can run the application to see that it all works just like it did in Scott&#8217;s original version.&nbsp; The difference now is that our controller and data context are no longer tightly coupled.&nbsp; If we wanted to change from Linq to some other ORM tool, or to move the Products table to a different Linq data context class than the rest of Northwind, before we&#8217;d have to make a bunch of code changes.&nbsp; Now all we have to do is update our web.config file to point Windsor at a class that implements IProductsRepository and we&#8217;re done.</p>
<p>Enjoy.&nbsp; And please comment on what&#8217;s confusing, what I glossed over too quickly, and what I spent too much time explaining.&nbsp; I&#8217;m still getting the hang of this and welcome any suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2007/12/removing-dependencies-between-controllers-and-linq-datacontext-classes-with-dependency-injection/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

