<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Jon Kruger's Blog</title>
	
	<link>http://jonkruger.com/blog</link>
	<description />
	<pubDate>Mon, 08 Feb 2010 15:08:14 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JonKrugersBlog" /><feedburner:info uri="jonkrugersblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>The automated testing triangle</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/tKflft-5vfo/</link>
		<comments>http://jonkruger.com/blog/2010/02/08/the-automated-testing-triangle/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 15:08:14 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Quality]]></category>

		<category><![CDATA[TDD]]></category>

		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=453</guid>
		<description><![CDATA[Recently I had the privilege of hearing Uncle Bob Martin talk at the Columbus Ruby Brigade.  Among the many nuggets of wisdom that I learned that night, my favorite part was the Automated Testing Triangle.  I don&#8217;t know if Uncle Bob made this up or if he got it from somewhere else, but [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had the privilege of hearing <a href="http://www.objectmentor.com/omTeam/martin_r.html" target="_blank">Uncle Bob Martin</a> talk at the <a href="http://columbusrb.com" target="_blank">Columbus Ruby Brigade</a>.  Among the many nuggets of wisdom that I learned that night, my favorite part was the Automated Testing Triangle.  I don&#8217;t know if Uncle Bob made this up or if he got it from somewhere else, but it goes something like this.</p>
<p><img src="http://jonkruger.com/blog/wp-content/uploads/2010/02/testing_triangle-300x233.jpg" alt="The Automated Testing Triangle" title="The Automated Testing Triangle" width="300" height="233" style="float: right;" />At the bottom of the triangle we have <b>unit tests</b>.  These tests are testing <i>code</i>, individual methods in classes, really small pieces of functionality.  We mock out dependencies in these tests so that we can test individual methods in isolation.  These tests are written using testing frameworks like NUnit and use mocking frameworks like Rhino Mocks.  Writing these kinds of tests will help us prove that our code is working and it will help us design our code.  They will ensure that we only write enough code to make our tests pass.  Unit tests are the foundation of a maintainable codebase.</p>
<p>But there will be situations where unit tests don&#8217;t do enough for us because we will need to test multiple parts of the system working together.  This means that we need to write <b>integration tests</b> &#8212; tests that test the <i>integration</i> between different parts of the system.  The most common type of integration test is a test that interacts with the database.  These tests tend to be slower and are more brittle, but they serve a purpose by testing things that we can test with unit tests.</p>
<p>Everything we&#8217;ve discussed so far will test technical behavior, but doesn&#8217;t necessarily test <i>functional business specifications</i>.  At some point we might want to write tests that read like our technical specs so that we can show that our code is doing what the business wants it to do.  This is when we write <b>acceptance tests</b>.  These tests are written using tools like Cucumber, Fitnesse, StoryTeller, and NBehave.  These tests are usually written in plain text sentences that a business analyst could write, like this:<br />
<code>As a user<br />
When I enter a valid username and password and click Submit<br />
Then I should be logged in<br />
</code></p>
<p>At this point, we&#8217;re are no longer just testing technical aspects of our system, we are testing that our system meets the functional specifications provided by the business.</p>
<p>By now we should be able to prove that our individual pieces of code are working, that everything works together, and that it does what the business wants it to do &#8212; <i>and all of it is automated</i>.  Now comes the manual testing.  This is for all of the random stuff &#8212; checking to make sure that the page looks right, that fancy AJAX stuff works, that the app is fast enough.  This is where you try to break the app, hack it, put weird values in, etc.  </p>
<p><img src="http://jonkruger.com/blog/wp-content/uploads/2010/02/bad_testing_triangle-300x234.jpg" alt="The un-automated testing triangle" title="The un-automated testing triangle" width="300" height="234" style="float: right;" />I find that the testing triangle on most projects tends to look more like this triangle.  There are some automated integration tests, but these tests don&#8217;t use mocking frameworks to isolate dependencies, so they are slow and brittle, which makes them less valuable.  An enormous amount of manpower is spent on manual testing.  </p>
<p>Lots of projects are run this way, and many of them are successful.  So what&#8217;s the big deal?  Becuase what really matters is the <b>total cost of ownership</b> of an application over the entire lifetime of the application.  Most applications need to be changed quite often, so there is much value in doing things that will allow the application be changed easily and quickly.</p>
<p>Many people get hung up on things like, &#8220;I don&#8217;t have time to write tests!&#8221;  This is a short term view of things.  Sometimes we have deadlines that cannot be moved, so I&#8217;m not denying this reality.  But realize that you are making a short term decision that will have long term effects.</p>
<p>If you&#8217;ve ever worked on a project that had loads of manual testing, then you can at least imagine how nice it would be to have automated tests that would test a majority of your application by clicking a button.  You could deploy to production quite often because regression testing would take drastically less time.</p>
<p>I&#8217;m still trying to figure out how to achieve this goal.  I totally buy into Uncle Bob&#8217;s testing triangle, but it requires a big shift in the way we staff teams.  For example, it would really help if QA people knew how to use automated testing tools (which may require basic coding skills).  Or maybe we have developers writing more automated tests (beyond the unit tests that they usually write).  Either way, the benefits of automated testing are tremendous and will save loads of time and money over the life of an application.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=The automated testing triangle&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F02%2F08%2Fthe-automated-testing-triangle%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F02%2F08%2Fthe-automated-testing-triangle%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=tKflft-5vfo:myf7ib3e00U:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=tKflft-5vfo:myf7ib3e00U:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=tKflft-5vfo:myf7ib3e00U:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=tKflft-5vfo:myf7ib3e00U:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=tKflft-5vfo:myf7ib3e00U:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=tKflft-5vfo:myf7ib3e00U:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/tKflft-5vfo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/02/08/the-automated-testing-triangle/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/02/08/the-automated-testing-triangle/</feedburner:origLink></item>
		<item>
		<title>Announcing TDD Boot Camp - comprehensive test-driven development training in .NET</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/ZLeppy2N8QA/</link>
		<comments>http://jonkruger.com/blog/2010/02/02/announcing-tdd-boot-camp-comprehensive-test-driven-development-training-in-net/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 14:55:25 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=450</guid>
		<description><![CDATA[If any of you have tried to learn test-driven development, you&#8217;ve probably discovered that it is not easy to learn.  It&#8217;s not something where you can just go read a book or find a few good blog posts and start doing it tomorrow.  You have to learn to how to write tests first, [...]]]></description>
			<content:encoded><![CDATA[<p>If any of you have tried to learn test-driven development, you&#8217;ve probably discovered that it is not easy to learn.  It&#8217;s not something where you can just go read a book or find a few good blog posts and start doing it tomorrow.  You have to learn to how to write tests first, how to use testing frameworks, how to write testable code, how to do dependency injection, how to use mocking frameworks, and on and on.</p>
<p>People have asked me for advice on how to learn TDD and I really haven&#8217;t had a good answer for them.  I&#8217;ve tried doing lunch and learn sessions on TDD and other people have done half-day sessions on TDD.  All of these are good, but there&#8217;s no way that you can cover all of the subjects that you would need to understand in order to do TDD on real world projects in such a short amount of time.  Sure, there&#8217;s definitely value in these sessions, but when I did my lunch and learn session on TDD, I felt like people went away feeling more confused about all of the stuff that they just realized that they didn&#8217;t understand.</p>
<p>Which is why I&#8217;m developing the <a href="http://tddbootcamp.com">TDD Boot Camp</a>, a comprehensive, three day training course that will cover everything that you need to know in order to do TDD on <b>real world .NET projects</b>.  It will be very hands-on with a lot of coding exercises that will help you understand all of the hows and whys of test driven development in .NET.  My goal is to teach all of the concepts, tools, and techniques that you need to know to do TDD so that, with some practice, you will effectively be able to do TDD (and hopefully teach others how to do it too!).</p>
<p>I&#8217;m working on scheduling some events, so keep an eye on the <a href="http://tddbootcamp.com" target="_blank">website</a> as I get things set up.  I can also come out to your site if that would work better.  Hopefully this will fill in the TDD learning gap so that more people can start realizing the benefits of test driven development.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Announcing TDD Boot Camp - comprehensive test-driven development training in .NET&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F02%2F02%2Fannouncing-tdd-boot-camp-comprehensive-test-driven-development-training-in-net%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F02%2F02%2Fannouncing-tdd-boot-camp-comprehensive-test-driven-development-training-in-net%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ZLeppy2N8QA:x6goNNssAoA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ZLeppy2N8QA:x6goNNssAoA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=ZLeppy2N8QA:x6goNNssAoA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ZLeppy2N8QA:x6goNNssAoA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=ZLeppy2N8QA:x6goNNssAoA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ZLeppy2N8QA:x6goNNssAoA:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/ZLeppy2N8QA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/02/02/announcing-tdd-boot-camp-comprehensive-test-driven-development-training-in-net/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/02/02/announcing-tdd-boot-camp-comprehensive-test-driven-development-training-in-net/</feedburner:origLink></item>
		<item>
		<title>The business value of test-driven development</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/ceXxpnrCrBo/</link>
		<comments>http://jonkruger.com/blog/2010/01/25/the-business-value-of-test-driven-development/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 15:37:00 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=438</guid>
		<description><![CDATA[Most businesses are creating software for one primary reason &#8212; to make money.  In order to make money, we need software that meets the needs of the business and can be developed and maintained in a reasonable amount of time with a high level of quality.  Test-driven development is a discipline that will [...]]]></description>
			<content:encoded><![CDATA[<p>Most businesses are creating software for one primary reason &#8212; to make money.  In order to make money, we need software that meets the needs of the business and can be developed and maintained in a reasonable amount of time with a high level of quality.  Test-driven development is a discipline that will help you achieve these goals.</p>
<p><a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">Test-driven development</a> involves writing automated unit tests to prove that code is working.  The test code is written <i>before</i> the implementation code is written.  By writing the tests first, you will know when the code is working once the tests pass.  Test names are <a href="http://dannorth.net/introducing-bdd" target="_blank">written as sentences in plain English</a> so that the tests describe what the code is supposed to do.  Over time, you will end up with a large suite of automated tests which you can run in a short amount of time.  These tests will prove to you that your code is working and will continue to work as you modify or refactor the code base.</p>
<p>Most software applications are intended to be used for many years, and throughout most of their existence, someone will be changing them.  The total cost of ownership of an application goes far beyond the cost of the initial effort to create the initial version of the software.  The first release is the easy part &#8212; you can build the application from the ground up, you don&#8217;t have many hindrances, and developers feel very productive.  But as time goes on, productivity tends to decrease due to complexity, developer turnover, poor software design, and any number of other reasons.  This is where software development really becomes expensive.  So much focus is placed on the original cost of building an application without considering how the original development effort will affect the cost of maintaining that application over several years.</p>
<p>Test-driven development can <a href="http://haacked.com/archive/2005/12/06/unit-tests-cost-more-to-write.aspx" target="_blank">reduce the total cost of ownership</a> of an application.  New developers on the team will be able to change the code without fear of breaking something important.  The application will have fewer defects (and far fewer major defects), reducing the need for manual QA testing.  Your code will be self-documenting because the tests will describe the intended behavior of the code.  All of this leads to flexible, maintainable software that can be changed in less time with higher quality.</p>
<p>Software is intended to deliver business value, and test-driven development will help you write higher quality, more maintainable software that can be changed at the fast pace of the business.  Test-driven development will lead to successful software projects and enable you to write software that will withstand the test of time.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=The business value of test-driven development&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F25%2Fthe-business-value-of-test-driven-development%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F25%2Fthe-business-value-of-test-driven-development%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ceXxpnrCrBo:mUgl-C5wKzc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ceXxpnrCrBo:mUgl-C5wKzc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=ceXxpnrCrBo:mUgl-C5wKzc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ceXxpnrCrBo:mUgl-C5wKzc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=ceXxpnrCrBo:mUgl-C5wKzc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=ceXxpnrCrBo:mUgl-C5wKzc:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/ceXxpnrCrBo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/01/25/the-business-value-of-test-driven-development/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/01/25/the-business-value-of-test-driven-development/</feedburner:origLink></item>
		<item>
		<title>Going independent</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/V9u6S5mTj0w/</link>
		<comments>http://jonkruger.com/blog/2010/01/22/going-independent/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 03:37:38 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=434</guid>
		<description><![CDATA[Three years ago, my three year plan was to go off on my own as an independent consultant.  Well, it&#8217;s year 3 and the time has come to make it happen.
For the past four years, I have worked at Quick Solutions and I have loved it.  I came into Quick Solutions never having [...]]]></description>
			<content:encoded><![CDATA[<p>Three years ago, my three year plan was to go off on my own as an independent consultant.  Well, it&#8217;s year 3 and the time has come to make it happen.</p>
<p>For the past four years, I have worked at <a href="http://quicksolutions.com" target="_blank">Quick Solutions</a> and I have loved it.  I came into Quick Solutions never having done ASP.NET and ended up getting all kinds of experience in all kinds of different technologies.  I never could&#8217;ve learned as much as I did and I certainly would not be in this spot today if it weren&#8217;t for all of the really smart people that I got to work with.</p>
<p>So what am I going to be doing now?  I&#8217;m still going to be leading a .NET project for Quick Solutions.  There will be plenty of blogging and I have some side business ideas to work on.  You will most likely see plenty of me at various community events, lunches, <a href="http://codeandcoffee.info" target="_blank">code and coffee</a>, and whatever else is going on.  </p>
<p>I don&#8217;t know what the future will hold, but I always remember the line in <i>Good Will Hunting</i> where Robin Williams says that he&#8217;s going to put his money on the table and see what cards he&#8217;ll get.  I&#8217;m really looking forward to it.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Going independent&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F22%2Fgoing-independent%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F22%2Fgoing-independent%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=V9u6S5mTj0w:I0pIWFpTJp8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=V9u6S5mTj0w:I0pIWFpTJp8:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=V9u6S5mTj0w:I0pIWFpTJp8:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=V9u6S5mTj0w:I0pIWFpTJp8:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=V9u6S5mTj0w:I0pIWFpTJp8:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=V9u6S5mTj0w:I0pIWFpTJp8:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/V9u6S5mTj0w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/01/22/going-independent/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/01/22/going-independent/</feedburner:origLink></item>
		<item>
		<title>Speakers appreciate your feedback</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/nw0e-hY0Wxo/</link>
		<comments>http://jonkruger.com/blog/2010/01/17/speakers-appreciate-your-feedback/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 00:42:26 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Speaking]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=429</guid>
		<description><![CDATA[I was fortunate enough to have been given the opportunity to speak at CodeMash this past week.  One thing I&#8217;ve noticed is that pretty much every time I speak (regardless of where it is), people will come up to me and offer feedback, advice, etc.
Personally, I really appreciate this.  I&#8217;ve done my share [...]]]></description>
			<content:encoded><![CDATA[<p>I was fortunate enough to have been given the opportunity to speak at <a href="http://codemash.org" target="_blank">CodeMash</a> this past week.  One thing I&#8217;ve noticed is that pretty much every time I speak (regardless of where it is), people will come up to me and offer feedback, advice, etc.</p>
<p>Personally, I really appreciate this.  I&#8217;ve done my share of speaking over the years (both technical and non-technical), so I don&#8217;t think that I&#8217;m a bumbling idiot, but I certainly am aware that I have a lot of room for improvement.  My biggest fear when giving a talk is that people won&#8217;t understand or I&#8217;ll say something wrong and no one will ever let me know what I&#8217;m doing wrong.  </p>
<p>So I don&#8217;t care if you have been speaking for 20 years or if you have never given a talk in your life, I appreciate your feedback and especially your suggestions.  If you come up to me and say, &#8220;That talk was terrible,&#8221; I might not be so happy!  But if you come to me and tell me what I can do to improve, I&#8217;ll all ears.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Speakers appreciate your feedback&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F17%2Fspeakers-appreciate-your-feedback%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F17%2Fspeakers-appreciate-your-feedback%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=nw0e-hY0Wxo:R491BK_BLMM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=nw0e-hY0Wxo:R491BK_BLMM:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=nw0e-hY0Wxo:R491BK_BLMM:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=nw0e-hY0Wxo:R491BK_BLMM:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=nw0e-hY0Wxo:R491BK_BLMM:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=nw0e-hY0Wxo:R491BK_BLMM:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/nw0e-hY0Wxo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/01/17/speakers-appreciate-your-feedback/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/01/17/speakers-appreciate-your-feedback/</feedburner:origLink></item>
		<item>
		<title>Convincing others how to do TDD, OOP/SOLID talks @ CodeMash</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/MU8ertc73bw/</link>
		<comments>http://jonkruger.com/blog/2010/01/09/convincing-others-how-to-do-tdd-oopsolid-talks-codemash/#comments</comments>
		<pubDate>Sat, 09 Jan 2010 20:51:44 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=427</guid>
		<description><![CDATA[If you&#8217;re going to CodeMash next week, I&#8217;ll be speaking at a couple of sessions.  On Wednesday morning, I&#8217;ll be doing a PreCompiler session on object-oriented programming and the SOLID principles.  I&#8217;m not big on 101 level talks, so this will be very little beginner material and mostly advanced OOP ninja stuff.  [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re going to <a href="http://codemash.org" target="_blank">CodeMash</a> next week, I&#8217;ll be speaking at a couple of sessions.  On Wednesday morning, I&#8217;ll be doing a PreCompiler session on <a href="http://codemash.org/Precompiler#OOP" target="_blank">object-oriented programming and the SOLID principles</a>.  I&#8217;m not big on 101 level talks, so this will be very little beginner material and mostly advanced OOP ninja stuff.  I know this doesn&#8217;t sound very sexy, but learning advanced OOP and SOLID has drastically improved the code that I write, which is why I&#8217;m talking about it.  We&#8217;ll do some hands-on coding too, so bring your laptop and get ready to learn from each other.</p>
<p>I&#8217;ll also be doing a short 30-minute session on how to convince others to do test-driven development.  This is a touchy, difficult task that requires lots of tact, patience, and passion for TDD, but it can be done!  I&#8217;m not sure what time I&#8217;ll be doing this, but check the schedule when you get there and you should find it (it will be in the vendor session timeslot).</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Convincing others how to do TDD, OOP/SOLID talks @ CodeMash&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F09%2Fconvincing-others-how-to-do-tdd-oopsolid-talks-codemash%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2010%2F01%2F09%2Fconvincing-others-how-to-do-tdd-oopsolid-talks-codemash%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=MU8ertc73bw:nkI-oW1CPGs:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=MU8ertc73bw:nkI-oW1CPGs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=MU8ertc73bw:nkI-oW1CPGs:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=MU8ertc73bw:nkI-oW1CPGs:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=MU8ertc73bw:nkI-oW1CPGs:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=MU8ertc73bw:nkI-oW1CPGs:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/MU8ertc73bw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2010/01/09/convincing-others-how-to-do-tdd-oopsolid-talks-codemash/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2010/01/09/convincing-others-how-to-do-tdd-oopsolid-talks-codemash/</feedburner:origLink></item>
		<item>
		<title>Make TDD your meal ticket in 2010</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/XYaZPQMyBLg/</link>
		<comments>http://jonkruger.com/blog/2009/12/21/make-tdd-your-meal-ticket-in-2010/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 18:51:42 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=413</guid>
		<description><![CDATA[It&#8217;s almost the time of the year where people start making new year&#8217;s resolutions and setting goals for the upcoming year.  Allow me to propose something for your list: make TDD your meal ticket in 2010.
Why do I say this?  Because TDD has revolutionized the way I develop software and has helped me [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost the time of the year where people start making new year&#8217;s resolutions and setting goals for the upcoming year.  Allow me to propose something for your list: make TDD your meal ticket in 2010.</p>
<p>Why do I say this?  Because TDD has revolutionized the way I develop software and has helped me write flexible and maintainable software with fewer defects and is a less stressful way to get things done.  I can&#8217;t imagine ever going back to writing code without tests, and as a result it&#8217;s really difficult to work with developers who don&#8217;t write tests because they will write code that is hard to test, which means I won&#8217;t be able to write tests either.</p>
<p>In today&#8217;s economy, it&#8217;s important to differentiate yourself from the crowd if you&#8217;re looking for a job, hoping to get a raise, trying to get a promotion, etc.  TDD can be that thing that differentiates you from everyone else out there.  At <a href="http://quicksolutions.com" target="_blank">Quick Solutions</a>, we are always looking for developers who practice TDD, but developers with any amount of TDD experience are very hard to find.  So once you learn TDD (or if you already know it), please <a href="http://jonkruger.com/blog/send-me-an-email">send me an email</a> and I will try to find you a place on my team.</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Make TDD your meal ticket in 2010&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F12%2F21%2Fmake-tdd-your-meal-ticket-in-2010%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F12%2F21%2Fmake-tdd-your-meal-ticket-in-2010%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=XYaZPQMyBLg:HP83WmOwl2A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=XYaZPQMyBLg:HP83WmOwl2A:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=XYaZPQMyBLg:HP83WmOwl2A:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=XYaZPQMyBLg:HP83WmOwl2A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=XYaZPQMyBLg:HP83WmOwl2A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=XYaZPQMyBLg:HP83WmOwl2A:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/XYaZPQMyBLg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2009/12/21/make-tdd-your-meal-ticket-in-2010/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2009/12/21/make-tdd-your-meal-ticket-in-2010/</feedburner:origLink></item>
		<item>
		<title>Why you need to go to CodeMash</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/3VKeKShvnHE/</link>
		<comments>http://jonkruger.com/blog/2009/11/20/why-you-need-to-go-to-codemash/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 14:54:56 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=410</guid>
		<description><![CDATA[This is your annual reminder that you need to go to CodeMash this coming January.  I&#8217;ve gone the last two years and I look forward to it every year.  In three days time you can get exposed to pretty much anything relating to software development, and as far as conferences go, it&#8217;s really [...]]]></description>
			<content:encoded><![CDATA[<p>This is your annual reminder that you need to go to <a href="http://codemash.org">CodeMash</a> this coming January.  I&#8217;ve gone the last two years and I look forward to it every year.  In three days time you can get exposed to pretty much anything relating to software development, and as far as conferences go, <a href="http://frazzleddad.blogspot.com/2009/11/codemash-2010-registration-open.html" target="_blank">it&#8217;s really cheap</a>.  So if you want to see why people are making such a big deal about Ruby, or you want to learn how to write iPhone apps, or if you want to learn how to do TDD, or just learn more about what you do at your day job, then CodeMash is for you!</p>
<p>Not only are there great sessions, there are open spaces going on throughout the whole conference.  Open spaces are self-organizing discussions where you propose a topic that you want to talk about and put it on the board in a time slot.  So not only will you have the great eyes-forward conference sessions, there are several open spaces in each time slot where you can go and talk with other people on whatever topics you can think up.  Last year I spent almost the entire conference in the open spaces and I had a great time.</p>
<p>Every year people come from all over the country to come to CodeMash, and last year it sold out.  It&#8217;s well on its way to selling out again, so go bug your boss as soon as you can and tell him or her that you need to go to CodeMash.</p>
<p>Oh, and <a href="http://www.codemash.org/Precompiler#OOP" target="_blank">I&#8217;ll be speaking at the PreCompiler</a> (the first day of the event) on OOP, the SOLID principles, and other &#8220;clean code&#8221; tips!  It&#8217;ll be an interactive session when we&#8217;ll do some coding and learn from each other, so it should be fun.  I know I&#8217;m looking forward to it.</p>
<p>Hope to see you at CodeMash!</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Why you need to go to CodeMash&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F20%2Fwhy-you-need-to-go-to-codemash%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F20%2Fwhy-you-need-to-go-to-codemash%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=3VKeKShvnHE:KTMOVOrtzaw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=3VKeKShvnHE:KTMOVOrtzaw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=3VKeKShvnHE:KTMOVOrtzaw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=3VKeKShvnHE:KTMOVOrtzaw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=3VKeKShvnHE:KTMOVOrtzaw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=3VKeKShvnHE:KTMOVOrtzaw:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/3VKeKShvnHE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2009/11/20/why-you-need-to-go-to-codemash/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2009/11/20/why-you-need-to-go-to-codemash/</feedburner:origLink></item>
		<item>
		<title>Make your project pluggable with StructureMap</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/dFGxT1K2-kI/</link>
		<comments>http://jonkruger.com/blog/2009/11/11/make-your-project-pluggable-with-structuremap/#comments</comments>
		<pubDate>Wed, 11 Nov 2009 15:22:28 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Design]]></category>

		<category><![CDATA[StructureMap]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=394</guid>
		<description><![CDATA[We all know that StructureMap is great for implementing dependency injection in your application, making your app more testable, and all that.  But StructureMap can do so much more than that.  StructureMap can help you create pluggable project architectures that can allow you easily modify how your application works in certain situations with [...]]]></description>
			<content:encoded><![CDATA[<p>We all know that <a href="http://dotnetslackers.com/articles/designpatterns/IntroductionToStructureMap.aspx" target="_blank">StructureMap</a> is great for implementing dependency injection in your application, making your app more testable, and all that.  But StructureMap can do so much more than that.  StructureMap can help you create pluggable project architectures that can allow you easily modify how your application works in certain situations with minimal to no configuration.  </p>
<p><img style="float: right;" src="http://jonkruger.com/blog/wp-content/uploads/2009/11/layers.jpg" alt="layers" title="layers" width="380" height="315" class="alignright size-full wp-image-395" />Let me explain.  Most people have some kind of layered setup in their projects.  The basic architecture is 3 tiers &#8212; a UI layer, a business layer, and a data access layer.  </p>
<p>Entity objects are going to flow through these layers.  You will load, save, and delete entities.  And in most cases, the <i>way</i> that you load, save, and delete these entities will be the same &#8212; but not always the same.</p>
<p>What we want to do is write code to handle the normal entities and write it just once.  If we need to modify how things are done for a certain entity, then we&#8217;ll write code for that.  By doing it this way, we should have little or no code duplication.</p>
<p>The diagram on the right shows our project structure.  You will notice that we have some generic interfaces defined in the business layer and data access layer.  That classes that implement these interfaces will perform the specified actions using an entity (the generic parameter T in each interface).</p>
<p>Here&#8217;s an example.  The IRepository&lt;T&gt; interface contains methods that will talk to the database.  I will create a concrete class called Repository&lt;T&gt; that implements the standard method of talking to the database.  This is how most of our entities will be loaded, saved, and deleted.</p>
<p><code>public interface IRepository&lt;T&gt; where T : class<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;T Get(long id);<br />
&nbsp;&nbsp;&nbsp;&nbsp;IList&lt;T&gt; GetAll();<br />
&nbsp;&nbsp;&nbsp;&nbsp;void Save(T target);<br />
&nbsp;&nbsp;&nbsp;&nbsp;void Delete(T target);<br />
}<br />
&nbsp;<br />
public class Repository&lt;T&gt; : IRepository&lt;T&gt; where T : class<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public T Get(long id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public IList&lt;T&gt; GetAll()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Save(T target)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Delete(T target)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Let&#8217;s say that I have a Customer entity that is persisted to a different database than the rest of the application.  I now have a special case where I need to write custom repository code for a Customer.  So I&#8217;ll make a class called CustomerRepository and have it implement IRepository&lt;Customer&gt;.</p>
<p><code>public class CustomerRepository : IRepository&lt;Customer&gt;<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public Customer Get(long id)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do custom stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public IList&lt;Customer&gt; GetAll()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do custom stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Save(Customer target)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do custom stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Delete(Customer target)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do custom stuff here<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Here&#8217;s where StructureMap comes in.  I&#8217;m going to configure StructureMap so that I can ask for IRepository&lt;T&gt; for some entity T and it will give me back the correct concrete class.  This means:</p>
<p>IRepository&lt;Product&gt; maps to Repository&lt;Product&gt;<br />
IRepository&lt;Order&gt; maps to Repository&lt;Order&gt;<br />
IRepository&lt;WhateverOtherEntity&gt; maps to Repository&lt;WhateverOtherEntity&gt;<br />
IRepository&lt;Customer&gt; maps to CustomerRepository (because CustomerRepository implements IRepository&lt;Customer&gt;)</p>
<p>Look at how easy this is going to be!  I&#8217;m not going to have to do any extra configuration or wiring up to change how Customer entities are persisted.  I&#8217;m not going to write any extra plumbing code, I&#8217;m just going to create the CustomerRepository class and implement an interface, and now my app deals with Customer objects differently.</p>
<p>Obviously there is some fancy plumbing going on behind the scenes, so let&#8217;s see how we set this up.</p>
<p>It&#8217;s really not that hard, actually, because most of the hard work is done by StructureMap.  We just have to do some simple configuration.</p>
<p>Here&#8217;s how we initialize StructureMap:</p>
<p><code>public class StandardStructureMapConfiguration<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Configure()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectFactory.Initialize(x =&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.Scan(scan =&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Automatically maps interface IXyz to class Xyz<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.WithDefaultConventions();<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.With(new RepositoryConventionScanner());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.With(new GetObjectServiceConventionScanner());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.With(new SaveObjectServiceConventionScanner());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.With(new DeleteObjectServiceConventionScanner());<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;scan.TheCallingAssembly();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.ForRequestedType(typeof(IRepository&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(Repository&lt;&gt;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.ForRequestedType(typeof(IGetObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(GetObjectService&lt;&gt;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.ForRequestedType(typeof(ISaveObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(SaveObjectService&lt;&gt;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;x.ForRequestedType(typeof(IDeleteObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(DeleteObjectService&lt;&gt;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Let&#8217;s break this down and go over what I&#8217;m doing here.</p>
<p><code>scan.WithDefaultConventions();<br />
</code></p>
<p>This tells StructureMap to automatically map an interface IXyz to class Xyz.  Most of the time, the names of your interfaces are just the concrete class with an &#8220;I&#8221; slapped on the front.  This only applies to non-generic classes, so this isn&#8217;t necessarily helping us with our IRepository&lt;T&gt; example, but I do it on every project, so I thought I&#8217;d throw it in.</p>
<p><code>scan.With(new RepositoryConventionScanner());<br />
scan.With(new GetObjectServiceConventionScanner());<br />
scan.With(new SaveObjectServiceConventionScanner());<br />
scan.With(new DeleteObjectServiceConventionScanner());<br />
</code></p>
<p>We don&#8217;t just want to use the default conventions, we want to add some of our own.  Basically all we&#8217;re doing here is telling StructureMap that if I have a custom concrete class that implements one of these generic interfaces, we want to automatically wire those up.  Here&#8217;s what one of the convention classes looks like:</p>
<p><code>public class RepositoryConventionScanner : ITypeScanner<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public void Process(Type type, PluginGraph graph)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Type interfaceType = type.FindInterfaceThatCloses(typeof (IRepository&lt;&gt;));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (interfaceType != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;graph.AddType(interfaceType, type);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Moving on&#8230;</p>
<p><code>scan.TheCallingAssembly();<br />
</code></p>
<p>We want StructureMap to look inside the assembly that contains this code and apply the conventions to the types in this assembly.  You can also do scan.AssemblyContainingType&lt;T&gt;.</p>
<p><code>x.ForRequestedType(typeof(IRepository&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(Repository&lt;&gt;));<br />
x.ForRequestedType(typeof(IGetObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(GetObjectService&lt;&gt;));<br />
x.ForRequestedType(typeof(ISaveObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(SaveObjectService&lt;&gt;));<br />
x.ForRequestedType(typeof(IDeleteObjectService&lt;&gt;))<br />
&nbsp;&nbsp;&nbsp;&nbsp;.TheDefaultIsConcreteType(typeof(DeleteObjectService&lt;&gt;));<br />
</code></p>
<p>Here we are wiring up the generic interfaces to the default concrete implementations of each interface.  This is for the 95% of the time when we&#8217;re using the normal way of doing these things.</p>
<p>StructureMap needs to be initialized whenever your application starts (Program.cs for WinForms, App.xaml.cs for WPF, Global.asax Application_Start() for web apps).  So in this case, I would new up an instance of the StandardStructureMapConfiguration class that I created here and call the Configure() method, which would do all of the ObjectFactory.Initialize() stuff.</p>
<p>I created a small <a href="http://jonkruger.com/blog/uploads/PluggableArchitecture.zip">sample project</a> with this code.  This is really easy to implement and it makes development a lot easier by reduces the amount of tedious plumbing code that you need to write.  </p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Make your project pluggable with StructureMap&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F11%2Fmake-your-project-pluggable-with-structuremap%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F11%2Fmake-your-project-pluggable-with-structuremap%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=dFGxT1K2-kI:pBcpO9zZSLk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=dFGxT1K2-kI:pBcpO9zZSLk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=dFGxT1K2-kI:pBcpO9zZSLk:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=dFGxT1K2-kI:pBcpO9zZSLk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=dFGxT1K2-kI:pBcpO9zZSLk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=dFGxT1K2-kI:pBcpO9zZSLk:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/dFGxT1K2-kI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2009/11/11/make-your-project-pluggable-with-structuremap/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2009/11/11/make-your-project-pluggable-with-structuremap/</feedburner:origLink></item>
		<item>
		<title>Save time by using IIS instead of Cassini</title>
		<link>http://feedproxy.google.com/~r/JonKrugersBlog/~3/UIYIls4G17I/</link>
		<comments>http://jonkruger.com/blog/2009/11/07/save-time-by-using-iis-instead-of-cassini/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 20:25:05 +0000</pubDate>
		<dc:creator>Jon Kruger</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jonkruger.com/blog/?p=379</guid>
		<description><![CDATA[I&#8217;m always looking for ways (whether or big or small) to make the software development process faster, and here&#8217;s a real easy win &#8212; use IIS instead of Cassini.  Cassini was a good idea in concept (allows you to develop web applications without IIS), but it&#8217;s also really slow.  If you&#8217;ve used it, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m always looking for ways (whether or big or small) to make the software development process faster, and here&#8217;s a real easy win &#8212; use IIS instead of Cassini.  Cassini was a good idea in concept (allows you to develop web applications without IIS), but it&#8217;s also really slow.  If you&#8217;ve used it, you know what I&#8217;m talking about &#8212; every time you debug your application, you have to wait 20 seconds for Cassini to start up.  Fortunately there is a better way, and that way is to use IIS instead.</p>
<p>The first thing is that you need to be developing a <i>web application</i>, not a <i>web site</i>.  I can&#8217;t think of any reason to use a web site over a web application.  So I&#8217;m going to assume that you already have a web application.  I&#8217;m also using IIS 7.  If you&#8217;re using IIS 6, you can still do all of the same things, but you have a different IIS console.  But you should still be able to figure it out.</p>
<p>Step 1: Create a new application pool by right-clicking on &#8220;Application Pools&#8221; in the IIS management console.  I suppose you could use an existing application pool, but I always like to make a new one.  This way, you don&#8217;t have one application pool being used for multiple sites, because then you can&#8217;t change the application pool settings without affecting all of those sites.  After you create the new application pool, click Start in the panel on the right to start the app pool.</p>
<p><img src="http://jonkruger.com/blog/wp-content/uploads/2009/11/newapppool.jpg" alt="Create a new application pool" title="Create a new application pool" width="316" height="285" class="alignright size-full wp-image-380" /></p>
<p>Step 2: Right click on &#8220;Sites&#8221; in the IIS management console and select Add New Site.  The physical path should be the local path on your drive to the folder that contains the web.config file for your site.  In the &#8220;Host name&#8221; text box, just make up some host name.  For example, &#8220;dev.mysite.com&#8221;.  It doesn&#8217;t matter what you pick, just pick a host name that doesn&#8217;t actually exist.  Also, click the &#8220;Select&#8221; button at the top and select your application pool.</p>
<p><img src="http://jonkruger.com/blog/wp-content/uploads/2009/11/addwebsite1.jpg" alt="Add Web Site" title="Add Web Site" width="532" height="517" class="alignright size-full wp-image-385" /></p>
<p>Step 3: Edit your &#8220;hosts&#8221; file.  This file can be found at C:\Windows\System32\drivers\etc\hosts.  Enter this line at the bottom of the file:</p>
<p>127.0.0.1		dev.mysite.com</p>
<p>Use the host name that you entered when you created the new web site.</p>
<p>Step 4: Browse to the URL that you assigned to the site.  In my case, http://dev.mysite.com.  Your website should come up!  Win!</p>
<p>Debugging your site using IIS is slightly different.  In Visual Studio, edit the project properties for your web site and select the Web tab.  Click on the &#8220;Use Local IIS Web Server&#8221; radio button and enter your custom URL as the Project Url (e.g. http://dev.mysite.com).  Notice that there is also a checkbox that says, &#8220;Apply server settings to all users&#8221;.  Ideally everyone on your team will set up IIS (because this way is much faster), but if that is not the case, you will want to uncheck that checkbox.</p>
<p><img src="http://jonkruger.com/blog/wp-content/uploads/2009/11/debugging.jpg" alt="Debugging" title="Debugging" width="686" height="692" class="alignright size-full wp-image-387" /></p>
<p>You can also debug your site by doing Tools / Attach to Process in Visual Studio (that&#8217;s Ctrl-Alt-P) and connecting to the w3wp.exe process (aspnet_wp.exe if you&#8217;re on Windows XP).  If you don&#8217;t see w3wp.exe in the list, make sure that you check the &#8220;Show processes in all sessions&#8221; checkbox in the Attach to Process dialog box.</p>
<p>Happy debugging!</p>
		<br />
		<a href="http://www.dotnetkicks.com/kick/?title=Save time by using IIS instead of Cassini&url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F07%2Fsave-time-by-using-iis-instead-of-cassini%2F"> 
		<img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3A%2F%2Fjonkruger.com%2Fblog%2F2009%2F11%2F07%2Fsave-time-by-using-iis-instead-of-cassini%2F" border="0" alt="Kick It on DotNetKicks.com" /> </a>
		<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=UIYIls4G17I:8M6-oqZGrq0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=UIYIls4G17I:8M6-oqZGrq0:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=UIYIls4G17I:8M6-oqZGrq0:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=UIYIls4G17I:8M6-oqZGrq0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?i=UIYIls4G17I:8M6-oqZGrq0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/JonKrugersBlog?a=UIYIls4G17I:8M6-oqZGrq0:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/JonKrugersBlog?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/JonKrugersBlog/~4/UIYIls4G17I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jonkruger.com/blog/2009/11/07/save-time-by-using-iis-instead-of-cassini/feed/</wfw:commentRss>
		<feedburner:origLink>http://jonkruger.com/blog/2009/11/07/save-time-by-using-iis-instead-of-cassini/</feedburner:origLink></item>
	</channel>
</rss>
