<?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; Uncategorized</title>
	<atom:link href="http://jtbennett.com/blog/category/uncategorized/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>New msnbc.com developer blog</title>
		<link>http://jtbennett.com/blog/2011/02/new-msnbc-com-developer-blog</link>
		<comments>http://jtbennett.com/blog/2011/02/new-msnbc-com-developer-blog#comments</comments>
		<pubDate>Tue, 08 Feb 2011 00:50:49 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[msnbc]]></category>

		<guid isPermaLink="false">http://jtbennett.com/blog/?p=45</guid>
		<description><![CDATA[We just launched a new blog to talk about the technical details of how we build msnbc.com: Development @ msnbc.com.  I&#8217;m going to be posting there, along with some of my colleagues: Paul Kearney, Bryan Wheeler, and others coming soon&#8230; Until &#8230; <a href="http://jtbennett.com/blog/2011/02/new-msnbc-com-developer-blog">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We just launched a new blog to talk about the technical details of how we build msnbc.com: <a href="http://development.msnbc.msn.com">Development @ msnbc.com</a>.  I&#8217;m going to be posting <a href="http://development.msnbc.msn.com">there</a>, along with some of my colleagues: Paul Kearney, Bryan Wheeler, and others coming soon&#8230;</p>
<p>Until we get our cross-posting in order, I&#8217;ll post links here to each of my posts over there, starting with these:</p>
<ul>
<li><a href="http://development.msnbc.msn.com/_news/2011/02/01/5969438-our-service-bus-introduction">How we built a service bus for all of our application instances to talk to one another</a> (a series of 5 posts and counting)</li>
<li><a href="http://development.msnbc.msn.com/_news/2011/02/06/6000743-how-msnbccom-handled-the-2010-us-election-results">How we got ready for the huge traffic spike on US election night in November 2010</a></li>
<li><a href="http://development.msnbc.msn.com/_news/2011/02/01/5969335-solid-state-drives-for-developers-are-a-big-win">How much faster Visual Studio is when running on solid state drives</a></li>
</ul>
<p>But please subscribe over there to get all the goodies from the whole team.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2011/02/new-msnbc-com-developer-blog/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>US Election Day &#8211; or &#8220;What I did since my summer vacation&#8221;</title>
		<link>http://jtbennett.com/blog/2010/11/us-election-day-or-what-i-did-since-my-summer-vacation</link>
		<comments>http://jtbennett.com/blog/2010/11/us-election-day-or-what-i-did-since-my-summer-vacation#comments</comments>
		<pubDate>Tue, 02 Nov 2010 12:30:48 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[msnbc]]></category>

		<guid isPermaLink="false">http://jtbennett.com/blog/2010/11/us-election-day-or-what-i-did-since-my-summer-vacation</guid>
		<description><![CDATA[My wife and I had a wonderful vacation in France this summer.&#160; Since then, I’ve been neck deep helping msnbc.com get ready for the US elections on November 2.&#160; I’ll talk more in the future about the Elections service and &#8230; <a href="http://jtbennett.com/blog/2010/11/us-election-day-or-what-i-did-since-my-summer-vacation">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My wife and I had a wonderful vacation in France this summer.&nbsp; Since then, I’ve been neck deep helping msnbc.com get ready for the US elections on November 2.&nbsp; I’ll talk more in the future about the Elections service and how it fits into <a href="http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms">the grand scheme of things</a>.&nbsp; This is just a shameless plug for <a href="http://elections.msnbc.com/">Decision 2010 on msnbc.com</a>.&nbsp; A lot of people worked long and hard to make this look great, and to make sure the results are updated as fast as we’re allowed to show them.</p>
<p>To all you US citizens over 18:&nbsp; VOTE!&nbsp; And then watch the <a href="http://elections.msnbc.msn.com/2010/all">election results as they come in</a>.&nbsp; Works well on your mobile phone or iPad, too.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2010/11/us-election-day-or-what-i-did-since-my-summer-vacation/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Identifying the services within a service oriented CMS</title>
		<link>http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms</link>
		<comments>http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms#comments</comments>
		<pubDate>Mon, 26 Jul 2010 14:52:43 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[msnbc]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms</guid>
		<description><![CDATA[In my previous post I talked about avoiding a database oriented architecture (DOA) and choosing a service oriented architecture (SOA) for our content management system (CMS). The next big question is: How do we divide our CMS into large-grained sets &#8230; <a href="http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a title="Credit: Nick Sherman" href="http://www.flickr.com/photos/nicksherman/"><img style="float: right" title="Dividing the service pie" border="0" alt="Dividing the service pie" align="right" src="http://jtbennett.com/blog/wp-content/uploads/2010/07/4480673517_3e35ac3d99_d1.jpg" width="244" height="184"></a>In my previous post I talked about avoiding a <a href="http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa">database oriented architecture</a> (DOA) and choosing a service oriented architecture (SOA) for our content management system (CMS).</p>
<p>The next big question is: How do we divide our CMS into large-grained sets of discrete functionality – business services? </p>
<p>A good CMS cleanly separates content from presentation.&nbsp; Even simple blog-oriented CMSs have this separation.&nbsp; This blog is currently hosted in <a href="http://wordpress.org/">WordPress</a>.&nbsp; By simply downloading a different WordPress theme, I can change not only colors and fonts, but the entire structure of the site.&nbsp; I can add widgets to the sidebar, change the header image, show either full posts or excerpts on the main page, add buttons to share on Twitter and Facebook, change URLs or move pages around into an entirely different hierarchical structure – all without touching the content of a single post.</p>
<p>With a large news-oriented CMS, this separation is even more important.&nbsp; We deliver news not just to browsers, but to all kinds of applications and devices – from iPads to Bing Maps and Google Earth, from Microsoft Surface tables to a 70s-style arcade game machine in Rockefeller Center.&nbsp; But our reporters and editors shouldn’t have to worry about – or even be aware of – all of that.&nbsp; They just need to worry about crafting great stories.</p>
<p>Thus, the most obvious business services within our CMS are what we call <strong>Editorial</strong> and <strong>Delivery</strong>.</p>
<p>As a news organization, we not only deliver the news – we consume it in enormous quantities.&nbsp; Feeds like the AP, UPI, Agence France-Presse, and hundreds of other text and photo sources all flow in 24 hours a day.&nbsp; Then there are data sources like weather, stock market tickers, lottery results, etc.; it all has to be gathered, organized, searched, categorized, edited, and made available for publishing.&nbsp; Elections produce enormous amounts of data that we need to sort, search, and aggregate.&nbsp; All of this functionality makes up the <strong>Ingest</strong> business service.</p>
<p>One type of ingested content absent from the list above is video.&nbsp; NBC News (a parent of ours) is one of the largest producers of video news content in the world.&nbsp; We support the websites for msnbc.com, cnbc.com, todayshow.com, plus shows like Rachel Maddow, Countdown, Dateline, Nightly News, Meet the Press, and more.&nbsp; Video is different from text and photo content in many ways:&nbsp; sheer file size, bandwidth consumption, encoding standards (and the computing powered needed for encoding), editing tools, advertising model, etc.</p>
<p>As a result of this complexity, video is a technical and editorial specialty unto itself.&nbsp; I’m no expert in video, so I’ll leave the detailed discussion to others.&nbsp; But as a major functional area that has to integrate with everything else in our CMS, <strong>Video </strong>is a business service.</p>
<p>Our other parent (Microsoft) gives us access to a wealth of technology.&nbsp; Not only the platform building blocks of Windows Server, ASP.NET, WCF, etc.; but also cool stuff like the ability to scan huge amounts of content and determine the most important people, places and concepts mentioned.&nbsp; And to automatically determine which stories, photos, and videos are related to one another.&nbsp; Check out the Related and Topics areas near the bottom of a <a href="http://www.msnbc.msn.com/id/38382217/ns/technology_and_science-wireless/">story page</a> to see what I mean.&nbsp; Like video, we want this capability integrated with many other parts of the system, yet it is more or less a world unto itself.&nbsp; This is the <strong>Topics </strong>business service.</p>
<p>With any non-trivial system, we also need to concern ourselves with day to day operations and maintenance.&nbsp; How do we easily deploy to and configure all those servers in multiple data centers?&nbsp; How do we monitor them and get notified when something isn’t working?&nbsp; How do we get detailed troubleshooting data for a server or process gone awry?&nbsp; While some of these capabilities need to be part of the implementation of every service, the data aggregation, monitoring and notifications are business functionality that forms the <strong>Operations</strong> service.</p>
<p>In future posts, I’ll dig into these services and their component applications, focusing first on the Delivery service.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2010/07/identifying-the-services-within-a-service-oriented-cms/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database Oriented Architecture is DOA</title>
		<link>http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa</link>
		<comments>http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa#comments</comments>
		<pubDate>Sun, 11 Jul 2010 16:37:05 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[msnbc]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa</guid>
		<description><![CDATA[As we began work on a new CMS for msnbc.com, one of the major pain points with the existing system that we wanted to address was its database oriented architecture – or DOA.&#160;&#160; No, not the popular video game (searching &#8230; <a href="http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.imdb.com/title/tt0094933/"><img style="margin: 0px 0px 0px 5px; float: right" title="D.O.A movie poster from IMDB" border="0" alt="D.O.A movie poster from IMDB" align="right" src="http://jtbennett.com/blog/wp-content/uploads/2010/07/MV5BMTMxNDk4NDEzNF5BMl5BanBnXkFtZTYwNTc2NDg5._V1._SX216_SY325_1.jpg" width="164" height="244"></a>
<p>As we began work on a new CMS for msnbc.com, one of the major pain points with the existing system that we wanted to address was its database oriented architecture – or DOA.&nbsp;&nbsp; No, not the popular video game (searching for DOA is borderline NSFW).&nbsp; Rather, “dead on arrival” – the morbid term for an ambulance patient who doesn’t survive the trip to the hospital.</p>
<p>A multitude of dependencies on a single central database is, indeed, DOA.&nbsp; First, it doesn’t scale well up to billions of page views per month, or make it easy to achieve redundancy across data centers.&nbsp; Doing so requires all sorts of magic with clusters, mirroring, replication, etc. – in other words, expensive hardware and even more expensive people.&nbsp; (The reason it has worked up to now is our top-notch operations team.)</p>
<p>Second, all of those dependencies mean that changes to the database schema are effectively impossible.&nbsp; </p>
<p>A CMS like ours isn’t a single application.&nbsp; It’s an ecosystem of applications, built by different teams over a long period of time and performing a wide variety of functions: filtering and aggregating hundreds of inbound news wires in different formats, encoding all the video from one of the largest news organizations in the world, supporting journalists on tight deadlines around the clock, and – oh, yeah – serving up all that content to millions of people a day.&nbsp; </p>
<p>Most of those applications create or manipulate content that is stored in the central database.&nbsp; Thus, any change to the database is likely to have side-effects.&nbsp; A change to support one application, simple on its own, turns out to require a major refactoring effort in an unrelated application.&nbsp; Fixing bugs becomes a game of <a href="http://www.addictinggames.com/whackamole.html">whack-a-mole</a>; new features become more expensive and take longer and longer to release.&nbsp; Worse, a great new feature may not get built at all.</p>
<p>This isn’t really a problem with databases, of course.&nbsp; It’s a problem with dependency management.&nbsp; But it is exacerbated by the fact that accessing a database is inherently a blocking operation – you have to wait for the result.&nbsp; Any single resource that must be available all the time in order for any other part of the system to function correctly is going to cause these types of problems.</p>
<p>For all of these reasons, we opted instead for a service oriented architecture (SOA).&nbsp; That doesn’t mean simply exposing everything as a web service.&nbsp; It means partitioning the system into “business services” – large grained, autonomous sets of functionality.&nbsp; Being autonomous includes having one’s own private database (assuming there is some data for that service to persist).&nbsp; Private means private – the database is not shared with other services.</p>
<p>SOA is not exactly a radical choice, but it does require a radical change in thinking – for developers, for admins, even for end users.&nbsp; It requires letting go of 100% consistency 100% of the time in favor of eventual consistency, letting go of “one database to rule them all,” and accepting that maintaining multiple, service-specific versions of the data won’t be the end of the world.</p>
<p>It takes a lot of time and constant effort to completely change your world view.&nbsp; It’s not unlike a procedural developer being introduced to object orientation.&nbsp; It takes a lot of practice, and dozens of “Aha!” moments to cross the conceptual chasm.&nbsp; As an organization, we’re still in mid-air.&nbsp; I expect we’ll eventually land safely on the other side, and not wind up DOA.</p>
<p>In a future post, I’ll write about how we drew the boundaries between our business services.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2010/07/database-oriented-architecture-is-doa/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New publishing platform for msnbc.com and todayshow.com</title>
		<link>http://jtbennett.com/blog/2010/07/new-publishing-platform-for-msnbc-com-and-todayshow-com</link>
		<comments>http://jtbennett.com/blog/2010/07/new-publishing-platform-for-msnbc-com-and-todayshow-com#comments</comments>
		<pubDate>Sun, 04 Jul 2010 13:10:59 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[msnbc]]></category>

		<guid isPermaLink="false">http://jtbennett.com/blog/2010/07/new-publishing-platform-for-msnbc-com-and-todayshow-com</guid>
		<description><![CDATA[For the past 18 months or so I’ve been nose-to-the-grindstone on a project to rebuild the publishing platform for msnbc.com, which is also used to run todayshow.com and a bunch of other NBC News sites.&#160; Just over a week ago… &#8230; <a href="http://jtbennett.com/blog/2010/07/new-publishing-platform-for-msnbc-com-and-todayshow-com">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For the past 18 months or so I’ve been nose-to-the-grindstone on a project to rebuild the publishing platform for <a href="http://msnbc.com/">msnbc.com</a>, which is also used to run <a href="http://todayshow.com">todayshow.com</a> and a bunch of other NBC News sites.&nbsp; Just over a week ago… we shipped!</p>
<p>The visible part of the change is an entirely new look for stories.&nbsp; You can <a href="http://today.msnbc.msn.com/id/37616868/ns/about_us">take a tour</a>.&nbsp; There are some great new features, including the ability to easily embed video, like so:</p>
<p><object width="420" height="245" id="msnbc5c4b16" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0"><param name="movie" value="http://www.msnbc.msn.com/id/32545640" /><param name="FlashVars" value="launch=38027587&amp;width=420&amp;height=245"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="wmode" value="opaque" /><embed name="msnbc5c4b16" src="http://www.msnbc.msn.com/id/32545640" width="420" height="245" FlashVars="launch=38027587&amp;width=420&amp;height=245" allowscriptaccess="always" allowFullScreen="true" wmode="opaque" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"></embed></object>
<p style="text-align: center; margin-top: 5px; width: 420px; font-family: arial, helvetica, sans-serif; background: none transparent scroll repeat 0% 0%; color: #999; font-size: 11px">Visit msnbc.com for <a style="border-bottom: #999 1px dotted; height: 13px; color: #5799db !important; font-weight: normal !important; text-decoration: none !important" href="http://www.msnbc.msn.com">breaking news</a>, <a style="border-bottom: #999 1px dotted; height: 13px; color: #5799db !important; font-weight: normal !important; text-decoration: none !important" href="http://www.msnbc.msn.com/id/3032507">world news</a>, and <a style="border-bottom: #999 1px dotted; height: 13px; color: #5799db !important; font-weight: normal !important; text-decoration: none !important" href="http://www.msnbc.msn.com/id/3032072">news about the economy</a></p>
<p>Alas, I had nothing to do with all those great features…&nbsp; My contribution was in the invisible parts – the underlying platform on top of which some smart, creative folks have built the new pages.&nbsp; There’s quite a bit more to it than meets the eye.&nbsp; </p>
<p>I’ll be posting on a bunch of topics related to what we did, how we did it, and why we did it that way.&nbsp; The highlight reel will include: SOA, EDA, messaging, service bus, WCF, MSMQ, ASP.NET MVC, unit testing, TFS, performance testing and profiling, Avicode, automated deployments, and a lot more.&nbsp; To the extent I’m allowed to, I’ll share some code, too.&nbsp; Stay tuned…</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2010/07/new-publishing-platform-for-msnbc-com-and-todayshow-com/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Business services, EDA and asynchronous messaging</title>
		<link>http://jtbennett.com/blog/2009/04/business-services-eda-and-asynchronous-messaging</link>
		<comments>http://jtbennett.com/blog/2009/04/business-services-eda-and-asynchronous-messaging#comments</comments>
		<pubDate>Sun, 12 Apr 2009 16:10:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[eda]]></category>
		<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2009/04/business-services-eda-and-asynchronous-messaging/</guid>
		<description><![CDATA[Business services are not the same thing as web services.&#160; A business service is a high-level concept: a large-grained, cohesive set of business functionality.&#160; Everywhere you see the word &#8220;service&#8221; in this post you should think &#8220;big chunk of business &#8230; <a href="http://jtbennett.com/blog/2009/04/business-services-eda-and-asynchronous-messaging">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Business services are not the same thing as web services.&nbsp; A business service is a high-level concept: a large-grained, cohesive set of business functionality.&nbsp; Everywhere you see the word &#8220;service&#8221; in this post you should think &#8220;big chunk of business functionality&#8221;.&nbsp; Each business service is likely implemented as a set of smaller-grained components (some of which might be web services).&nbsp; Business service is very macro.&nbsp; Web service is very micro.</p>
<p>In an event-driven architecture (EDA), business services communicate with one another through asynchronous messaging, in order to reduce the coupling between them.&nbsp; By communicating asynchronously, a business service can continue to operate (for some period of time) without any contact with other business services.&nbsp; That&#8217;s where their &#8220;autonomous&#8221; quality comes from.</p>
<p>For example, a retailer might have an Inventory service, an Order service, an Inventory service, a Billing service, and a Shipping service.&nbsp; The Order service can take orders even if the other services are unavailable.&nbsp; When those services become available, queued messages can be exchanged &#8212; inventory gets allocated, orders get shipped and customers get billed.</p>
<p>Suppose an order is placed over the web.&nbsp; The Order service might publish an OrderReceived message.&nbsp; The Inventory service would then publish either an InventoryAssignedToOrder or an ItemOutOfStock message, depending on what was actually available.&nbsp; The Order service would subscribe to those types of messages.&nbsp; If it received the first, it would then publish an OrderApproved message.&nbsp; If it received the second, it might take other action, such as sending an email to the customer.</p>
<p>You may have noticed that we just created a messaging protocol.&nbsp; That is, the Order service must correlate multiple messages related to the same business process, and keep track of state related to those messages.&nbsp; Within the Order service, the logic would be something like this:</p>
<ul>
<li>When an order is placed (in an inbound web request), save it, publish an OrderReceived message, and send the customer a response message that the order was successfully received.
<li>When an InventoryAssignedToOrder message is received, look up the order and record the assigned inventory quantity next to the quantity ordered.
<li>When inventory has been assigned for all quantities of all products in the order, publish an OrderApproved message.
<li>When an ItemOutOfStock message is received, send an email to the customer.
<li>When an hour passes after sending an OrderReceived message, if not all quantities in the order have been assigned inventory and no ItemOutOfStock message has been received, publish an OrderDelayed message. </li>
</ul>
<p>This is a <strong>saga</strong> &#8212; a long-running process within a single service that requires the service to correlate messages and track state across those messages.&nbsp; Note that this is just one side of the equation.&nbsp; The Inventory service might have its own saga.&nbsp; </p>
<p>Notice how each of the saga&#8217;s business rules start with &#8220;When&#8221;.&nbsp; These rules are what make the architecture <strong>event-driven</strong>.&nbsp; Notice also how simple the rules are.&nbsp; Especially interesting is that the technical implementation maps almost directly to the business rules.&nbsp; We would create an OrderProcessingSaga class, which has methods for Handle&lt;OrderReceived&gt;(), Handle&lt;InventoryAssignedToOrder&gt;(), etc.&nbsp; The simple logic of each method is described in one of the bullets above.&nbsp; (The final bullet is implemented in Handle&lt;Timeout&gt;().)</p>
<p>How would we accomplish the same process in a synchronous RPC (remote procedure call) architecture?&nbsp; In RPC (like typical HTTP-based web services), a request is issued and the requestor waits for the response. </p>
<ul>
<li>When an order is placed (in an inbound web request), save it.&nbsp; The inbound connection remains open.
<li>The Order service opens a new connection to the Inventory service.&nbsp; The connection remains open while the Inventory service determines whether inventory is available for all the quantities in the order.&nbsp; The response to the Order service includes data on any product SKUs that are out of stock.&nbsp; The response is sent and the connection from Order service to Inventory service is closed.
<li>The Order service looks for any out of stock SKUs in the response.&nbsp; Based on that, it creates the appropriate message (&#8220;order confirmed&#8221; or &#8220;items out of stock&#8221;), sends the customer a response message. </li>
</ul>
<p>At first glance this might seem no different than the message-based process above.&nbsp; But there are a number of problems with the RPC approach that reach across most of the -ilities:</p>
<p><strong>Reliability.</strong>&nbsp; Even with all the redundant hardware in the world, at some point the Inventory service will be down.&nbsp; During that time, no orders can be accepted.&nbsp; If each of the two services has 99% uptime, the total uptime for the system from the customer&#8217;s perspective is 99% x 99% = 98.01%.&nbsp; The system as a whole is <em>less reliable the least reliable component.&nbsp; </em>To get the system to 99% uptime, both services need uptime of at least 99.5%.&nbsp; That means a greater investment in hardware, maintenance, etc.</p>
<p>In the message-based approach, the Order service can happily process orders without the Inventory service for up to an hour (or whatever rule is applied in the saga).&nbsp; The services are not temporally coupled &#8212; they don&#8217;t always have to be running at the same time.&nbsp; From the customer&#8217;s perspective, the uptime is 99%.&nbsp; </p>
<p>The Inventory service can be taken down for maintenance.&nbsp; Perhaps it could be deployed to two cheap servers instead of to an expensive active-passive cluster.&nbsp; All without affecting the uptime of the Order service.</p>
<p><strong>Performance.</strong>&nbsp; In the RPC approach, the customer submits an order and then waits: while the Order service records the order, while the Order service contacts the Inventory service, while the Inventory service responds, and while the Order service figures out what message to return.&nbsp; What if the Inventory service takes 5 seconds to determine whether inventory is available?&nbsp; The customer sees a spinning ball.&nbsp; In the message-based approach, the customer waits only for the Order service to record the order.&nbsp; A response is them immediately sent to the customer.&nbsp; </p>
<p>Now add the latency of communication between the services.&nbsp; If they are in different data centers, that could add half a second to the customer&#8217;s wait time in the RPC approach.&nbsp; It adds zero time in the message-based approach.</p>
<p><strong>Scalability.</strong>&nbsp; In the RPC approach, connections between the customer and the Order service remain open for longer (as described above).&nbsp; Let&#8217;s say the Order service receives 10 orders/second.&nbsp; If the connection remains open for 2 seconds, the Order service has to support 20 simultaneous connections.&nbsp; If the message-based approach reduced the connection time to 1 second, the Order service only has to support 10 simultaneous connections &#8212; for the same volume of orders.&nbsp; This disparity can become much worse under real-world traffic peaks.&nbsp; Customer requests may wind up queuing (decreasing performance further) or even timing out.</p>
<p>The same problem occurs between the Order service and the Inventory service, as connections are consumed there in the same proportion.</p>
<p><strong>Transparency.</strong>&nbsp; Take another look at the logic for the RPC and message-based approaches.&nbsp; In which one is the business logic more readily apparent?&nbsp; Which one would do you think a sales rep would more easily understand?&nbsp; I believe that the message-based approach wins handily on both counts.&nbsp; As mentioned above, the business logic maps almost directly to the actual implementation classes and methods.&nbsp; While a good RPC design can also have this quality, transparency is very natural and very easy in the message-based approach.</p>
<p><strong>Maintainability.</strong>&nbsp; Let&#8217;s add shipping to our business process.&nbsp; In the RPC approach, during the order request, just after we assign the inventory to the order, we would open a connection to the Shipping service, ask it to ship the order, wait for its response, and then send the response to the customer.&nbsp; With this third service, we&#8217;ve exacerbated all of the reliability, performance and scalability issues described above.&nbsp; </p>
<p>All three systems have to be running.&nbsp; At 99% uptime for each service, our overall our system is now down to 97.03% uptime.&nbsp; We don&#8217;t want to ship the order unless we actually have all products in stock, so we have to wait for the request to the Inventory service to return before we talk to the Shipping service.&nbsp; Our connections from the customer are now up to 3 seconds each, and our Order service has to support 30 simultaneous connections.</p>
<p>What happens when we&#8217;ve assigned inventory and then the call to the shipping service fails?&nbsp; We have to free the inventory somehow, so we place the whole order request in a transaction.&nbsp; That transaction flows across each service call, so that if shipping fails the inventory assignment is rolled back.&nbsp; The transaction management adds half a second to the customer&#8217;s wait time, and we&#8217;re up to needing 35 simultaneous connections on our Order service.</p>
<p>In the message-based approach, we create a new saga within the Shipping service.&nbsp; It has a rule saying: When an OrderApproved message is received, try to ship the order.&nbsp; If successful, publish an OrderShipped message; otherwise publish an OrderFailed message.</p>
<p>We add rules to the OrderProcessingSaga:&nbsp; When an OrderShipped message is received, update the order status; and when an OrderFailed message is received, update the order status and send an email to the customer.&nbsp; </p>
<p>And we add a rule to the Inventory service&#8217;s saga:&nbsp; When an OrderFailed message is received, release any inventory assigned to the order.</p>
<p>We haven&#8217;t had to make a single change to the processing logic for the customer&#8217;s initial request to place the order.&nbsp; We haven&#8217;t had to create distributed transactions, because the business rules in the various sagas handle failures correctly.&nbsp; We haven&#8217;t reduced our system uptime.&nbsp; We haven&#8217;t lengthened the time a customer waits for a response, and therefore we don&#8217;t have to support more simultaneous connections from customers.</p>
<h3>Conclusions</h3>
<p>The business process described here is pretty simple.&nbsp; Real world processes get much more complicated:&nbsp; Add a credit check before assigning inventory.&nbsp; Bill the customer after the order ships, after getting sales tax computation from an external service.&nbsp; Substitute an equivalent product if the one ordered has been discontinued.&nbsp; Yikes!&nbsp; </p>
<p>If you read &#8220;service-oriented&#8221; as &#8220;synchronous RPC-style web services,&#8221; you&#8217;ll quickly be in big trouble with a system of any significant size.&nbsp; However, if you read &#8220;service-oriented&#8221; as &#8220;event-driven, autonomous business services communicating with asynchronous message across service boundaries,&#8221; you&#8217;ll have a much better chance of actually enjoying the maintenance of your system.&nbsp; I&#8217;ll take the latter, thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2009/04/business-services-eda-and-asynchronous-messaging/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Configuration</title>
		<link>http://jtbennett.com/blog/2009/04/on-configuration</link>
		<comments>http://jtbennett.com/blog/2009/04/on-configuration#comments</comments>
		<pubDate>Sat, 11 Apr 2009 16:16:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[operations]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2009/04/on-configuration/</guid>
		<description><![CDATA[[I recently wrote this up for work, and thought it was worth re-posting here.] These ideas come almost entirely from Udi Dahan and how he implemented nServiceBus, but unfortunately I can&#8217;t find where he said it.&#160; It may have been &#8230; <a href="http://jtbennett.com/blog/2009/04/on-configuration">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>[I recently wrote this up for work, and thought it was worth re-posting here.]</p>
<p>These ideas come almost entirely from <a href="http://www.udidahan.com/?blog=true">Udi Dahan</a> and how he implemented nServiceBus, but unfortunately I can&#8217;t find where he said it.&nbsp; It may have been when I attended his class in Austin last October.</p>
<p>I define configuration as &#8220;stuff that needs to be easy to change.&#8221;&nbsp; Udi says there are two major categories of configuration, with very different characteristics.&nbsp; One category has to do with operational concerns, such as:</p>
<ul>
<li>The specifics of the physical deployment environment (URLs, machine names, connection strings, etc.)
<li>Monitoring and troubleshooting (logging verbosity and where log entries are stored, etc.)
<li>Scaling out (how many app instances or threads should be running, etc.) </li>
</ul>
<p>These are things that administrators care about deeply.&nbsp; They want to be able to move things to different machines, spin up a new instance of your service, failover a database server, etc. And as a developer, you want them to be able to do all of those things without calling you.&nbsp; <img src='http://jtbennett.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &nbsp; These &#8220;administrator config&#8221; settings <strong>have no effect on the semantics of your application</strong>.&nbsp; They change &#8220;physical&#8221; characteristics, not business-logical characteristics.</p>
<p>A second category of configuration does affect the semantics of your application.&nbsp; Udi calls this &#8220;developer config.&#8221;&nbsp; Changing it <strong>will </strong>have an effect on what the application does.&nbsp; These are things like:</p>
<ul>
<li>Using a different implementation of a interface (e.g., a gateway that talks to a database vs a remote web service)
<li>Whether a particular operation requires a transaction (e.g., the WCF settings for a specific service) </li>
</ul>
<p>Changes to these often need to be one-line-of-code simple, which makes them &#8220;configuration&#8221; in my mind.&nbsp; But they also imply a requirement change because they change how the application works.&nbsp; (Yes, adding or removing a transaction is a semantic change.)&nbsp; Therefore you definitely don&#8217;t want administrators to go and change them on production servers.&nbsp; The best way to prevent them from changing these settings it to give them no way to do it!</p>
<p>The most common objection to putting the developer config in code is that you have to redeploy your application.&nbsp; Yep, exactly.&nbsp; Changing developer config alters the semantics of your application.&nbsp; Any such change should go through all of your testing and validation processes before being released.</p>
<p>Digging a little deeper, a lot of the resistance to putting developer config in code stems from fear of deployment.&nbsp; If deployment is hard, error-prone, and stressful then you try to avoid it by putting as many things in your config file as possible.&nbsp; (The same rationale is often given for putting business logic in stored procedures.)&nbsp; <strong>If you cross your fingers every time you deploy, you&#8217;re doing it wrong.</strong>&nbsp; </p>
<p>Deployments (and rollbacks) should be easy and reliable.&nbsp; That means largely automated.&nbsp; Once you have automated builds, lots of automated tests, and (mostly) automated deployment/rollback, &#8220;hard coded&#8221; is no longer a scary concept.&nbsp; See <a href="http://ayende.com/Blog/archive/2008/08/21/Enabling-change-by-hard-coding-everything.aspx">this</a> and <a href="http://ayende.com/Blog/archive/2008/08/21/Enabling-change-by-hard-coding-everything-the-smart-way.aspx">this</a>. JFHCI. <img src='http://jtbennett.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Ever opened up a config file that looked really scary?&nbsp; How about a default WCF config with dozens and dozens of settings for a single service endpoint?&nbsp; How many of those things do you really want someone to change on the production servers?&nbsp; 5% of them?&nbsp; Once you&#8217;ve removed all of that developer config, the administrators will thank you for removing all that noise you told them to absolutely, positively never touch.&nbsp; They&#8217;re also a lot less likely to catastrophically fat-finger a random character that will be lost in a sea of angle brackets.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2009/04/on-configuration/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The life and times of an ASP.NET MVC Framework request</title>
		<link>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request</link>
		<comments>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request#comments</comments>
		<pubDate>Mon, 16 Feb 2009 22:45:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asp-net]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request/</guid>
		<description><![CDATA[[I recently wrote this up for some folks at work, and thought it was worth re-posting here.] In this post I&#8217;ll detail what happens during a request to the default ASP.NET MVC site that you get when you create a &#8230; <a href="http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request">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>In this post I&#8217;ll detail what happens during a request to the default ASP.NET MVC site that you get when you create a new MVC project in Visual Studio.&nbsp; My goal is to list the major classes involved and how they interact.&nbsp; There is a lot more that goes on during a request, and I&#8217;ve completely skipped action filters.&nbsp; This is just the highlights. </p>
<p>First, there are some steps that happen at application start: </p>
<ul>
<li>The web.config file adds System.Web.Routing.UrlRoutingModule.&nbsp; During initialization, <strong>UrlRoutingModule</strong> attaches event handlers for HttpApplication&#8217;s PostResolveRequestCache and PostMapRequestHandler events.&nbsp; These handlers do some magic (using pre-existing extension points in ASP.NET) to ensure that requests in both IIS6 and IIS7, and for various versions of .NET, all wind up in the right place.
<li>The web.config file also adds <strong>MvcHttpHandler</strong>.&nbsp; Requests matching *.mvc are handled with it.&nbsp; This is also part of the goo that makes MVC work with different versions of IIS and .NET.
<li>Application_Start().&nbsp; This <strong>HttpApplication</strong> event handler is overridden in the Global class (Global.asax.cs).&nbsp; It calls the RegisterRoutes() method, also defined on the Global class.
<ul>
<li><strong>RegisterRoutes</strong>() informs the routing infrastructure which requests to route to which controllers and actions, how to populate action method parameters from the URL, and what the default parameter values are.&nbsp; It does this by adding Route objects to an ordered collection. </li>
</ul>
</li>
</ul>
<p>The application is now setup to begin accepting requests.&nbsp; Here are pseudocode and descriptions for what happens on each request.&nbsp; Note that wherever you see &#8220;httpContext&#8221;, the object is actually derived from the <strong>HttpContextBase</strong> class defined in System.Web.Abstractions.&nbsp; This avoids the web forms dependency on HttpContext, and allows for code execution and testing outside the context of a web request. </p>
<p>This could use a sequence diagram, and I hope to create one soon.&nbsp; In the meantime, you can try to follow along in Reflector (or the MVC source if you&#8217;ve downloaded it). </p>
<ul>
<li>The <strong>UrlRoutingModule</strong> event handlers do their magic, the result of which is the creation of an MvcHttpHandler object and a call to its ProcessRequest() method.&nbsp; MvcHttpHandler derives from UrlRoutingHandler, which is part of the routing API and implements IHttpHandler.
<li><strong>mvcHttpHandler.ProcessRequest</strong>():
<ul>
<li>routeData = <strong>RouteCollection.GetRouteData</strong>(httpContext);
<ul>
<li>In turn, calls <strong>route.GetRouteData</strong>() on each route in the collection. The collection is whatever we added during RegisterRoutes() at application startup, in order. The first route to return a non-null value wins the request.&nbsp; RouteData contains the names of the controller and action (both required), along with the values of any other tokens defined in the route URL format.
<ul>
<li>RouteData is important, as it carries request-specific data (e.g., URL token values) that are not present in HttpContext.&nbsp; The <strong>RequestContext</strong> object is an aggregation of HttpContext and RouteData, and is available to all later processing of the request. </li>
</ul>
</li>
</ul>
<li>mvcRouteHandler = routeData.RouteHandler; (MvcRouteHandler implements IRouteHandler, which is part of the routing API.&nbsp; MvcRouteHandler is just a very thin adapter between routing and Mvc.)
<li>mvcHandler = mvcRouteHandler.GetHttpHandler();
<li><strong>mvcHandler.ProcessRequest</strong>(httpContext);&nbsp; (MvcHandler implements IHttpHandler.)
<ul>
<li>Gets the controller name from the RouteData.
<li>Gets the singleton instance of <strong>DefaultControllerFactory</strong>.
<li>controller = <strong>factory.CreateController</strong>(requestContext, controllerName);
<li><strong>controller.Execute</strong>(requestContext);
<ul>
<li>Creates a ControllerContext, which is just the RequestContext plus a reference to the controller instance.
<li>Gets the action name from the RouteData.
<li>Creates an ActionInvoker
<li><strong>actionInvoker.InvokeAction</strong>(controllerContext, actionName)
<ul>
<li>Maps values in the RouteData to parameters on the action method with matching names
<li>If there are complex parameter types that can&#8217;t be directly mapped from RouteData values, the invoker instantiates an IModelBinder for each parameter and calls <strong>BindModel()</strong> on it to get the parameter value.
<li>Invokes the action method with all the parameters.
<ul>
<li>In typical usage, action methods get data, add that data to the ViewData dictionary and/or the Model property. Then the action method calls the controller&#8217;s View() method.
<li><strong>controller.View()</strong> method:
<ul>
<li>Gives each registered view engine an opportunity to &#8220;claim&#8221; the view. The default WebFormViewEngine uses the virtual path to locate the view. The default virtual paths it checks are:
<ul>
<li>~/views/{controller}/{action}.aspx and .ascx
<li>~/views/shared/{action}.aspx and .ascx </li>
</ul>
<li>View() returns a ViewResult object (derived from ActionResult) containing a reference to the view engine and the virtual path to the view. </li>
</ul>
<li>The action method typically returns the ViewResult it gets from View(). </li>
</ul>
<li>The invoker calls <strong>result.ExecuteResult</strong>():
<ul>
<li>When called on a ViewResult, this method asks the view to render itself:
<li><strong>view.Render</strong>(outputWriter)
<ul>
<li>Performs the rendering and writes the output directly to the outputWriter (which is the HTTP response stream). </li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2009/02/the-life-and-times-of-an-asp-net-mvc-framework-request/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Follow up on Silverlight and SaaS</title>
		<link>http://jtbennett.com/blog/2008/12/follow-up-on-silverlight-and-saas</link>
		<comments>http://jtbennett.com/blog/2008/12/follow-up-on-silverlight-and-saas#comments</comments>
		<pubDate>Sun, 14 Dec 2008 17:42:00 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[saas]]></category>
		<category><![CDATA[silverlight]]></category>

		<guid isPermaLink="false">http://173.203.71.169/blog/2008/12/follow-up-on-silverlight-and-saas/</guid>
		<description><![CDATA[Back in May, I wrote a post speculating about using Silverlight on the server to allow tenants in a multitenant SaaS application to write and run custom code on shared servers.&#160; Silverlight provides a subset of the full .NET framework &#8230; <a href="http://jtbennett.com/blog/2008/12/follow-up-on-silverlight-and-saas">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Back in May, I wrote a post speculating about <a href="http://jtbennett.com/blog/could-silverlight-be-used-as-a-server-side-sandbox-for-saas/">using Silverlight on the server</a> to allow tenants in a multitenant SaaS application to write and run custom code on shared servers.&nbsp; Silverlight provides a subset of the full .NET framework and provides a security sandbox &#8212; both very useful in that kind of scenario.</p>
<p>At the time I thought the idea was a little hare-brained.&nbsp; It had occurred to me while I was brushing my teeth one morning and it seemed interesting enough.&nbsp; I felt a little bit less hare-brained when <a href="http://www.hanselman.com/blog/">Scott Hanselman</a> posted in September about his discovery of <a href="http://www.hanselman.com/blog/WindowsLiveMeshSilverlightAndTheCoreCLR.aspx">Silverlight living outside the browser</a> in several ways, most notably the Mesh Operating Environment.</p>
<p>I&#8217;m pretty sure that MOE is the same thing as the Live Operating Environment that is part of the <a href="http://dev.live.com/liveframework/">Live Framework</a>.&nbsp; In effect, the LOE is a mini-CLR &#8212; just like Silverlight is.&nbsp; LOE lives either on a device (computer, phone, etc.) or on the Live Mesh servers.&nbsp; In both cases it provides a stripped down CLR with extra security.&nbsp; (I know this is an oversimplification, but I think it is generally correct.)</p>
<p>I feel even less crazy now that <a href="http://www.lhotka.net/weblog/default.aspx">Rocky Lhotka</a> has posted <a href="http://www.lhotka.net/weblog/SomeThoughtsOnWindowsAzure.aspx">Some thoughts on Windows Azure</a> and a <a href="http://www.lhotka.net/weblog/WindowsAzureAndTheValueOfRestrictedPlatformsarchitectures.aspx">follow up</a>.&nbsp; (The <a href="http://en.wikipedia.org/wiki/Marchitecture">marchitecture</a> diagram on the <a href="http://www.microsoft.com/azure/whatisazure.mspx">Windows Azure site</a> shows Live Services &#8212; which contains the LOE &#8212; as just one component that runs on top of Azure.&nbsp; I&#8217;m conflating the LOE and Azure, but I don&#8217;t think that affects the point.)&nbsp; Rocky says of Azure:</p>
<blockquote><p>Remember that we’re talking about a restricted runtime, with a restricted architecture and API. Basically a controlled subset of .NET. We’re already seeing this work – in the form of Silverlight.</p>
</blockquote>
<p>And later:</p>
<blockquote><p>So what we need, I think, is this server equivalent to Silverlight. Azure is not that &#8211; not today &#8211; but I think it may start us down that path, and that&#8217;d be cool!</p>
</blockquote>
<p>Scott and Rocky go much further than I did, and are certainly better writers.&nbsp; But with those two seeing the same coolness I do in the idea, I have much less reason to question my sanity.</p>
]]></content:encoded>
			<wfw:commentRss>http://jtbennett.com/blog/2008/12/follow-up-on-silverlight-and-saas/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

