<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;DkYCQHo7cCp7ImA9WhRVGUk.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533</id><updated>2012-01-18T22:36:01.408-05:00</updated><category term="Threading" /><category term="calendar" /><category term="dependency injection" /><category term="ienumerable" /><category term="static" /><category term="lists" /><category term="moles" /><category term="multithreading" /><category term="MSBuild" /><category term="jaxcc" /><category term="extension methods" /><category term="VS2008" /><category term="inversion of control" /><category term="mvc" /><category term="c#" /><category term="pair programming" /><category term="WF" /><category term="jquery" /><category term="popup" /><category term="moq" /><category term="ninject" /><category term="mocking" /><category term="generics" /><category term="rss" /><category term="session" /><category term="VS2010" /><category term="unit testing" /><category term="asp.net" /><category term="channel9" /><category term="WPF" /><category term="vista" /><category term="vb.net" /><category term="json" /><category term="aero" /><title>Adventures in .NET</title><subtitle type="html">Tips and Tricks for VB and C# Developers</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>51</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/AdventuresDotNet" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="adventuresdotnet" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CkAMQXw6eCp7ImA9WhZTEk4.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-3241881118181352756</id><published>2011-03-15T19:13:00.001-04:00</published><updated>2011-03-15T19:13:00.210-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-15T19:13:00.210-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="inversion of control" /><category scheme="http://www.blogger.com/atom/ns#" term="static" /><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="dependency injection" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><category scheme="http://www.blogger.com/atom/ns#" term="moles" /><category scheme="http://www.blogger.com/atom/ns#" term="moq" /><category scheme="http://www.blogger.com/atom/ns#" term="mocking" /><title>Mocking Static Methods for Unit Testing</title><content type="html">&lt;p&gt;As you probably know, unit tests are supposed to be fast, lightweight tests of your code logic. They are not supposed to do any disk I/O, network communication, or long-running CPU calculations. If you have cleanly decoupled code that doesn’t call any static methods and everything is programmed to the interface, you can mock the intensive operations very easily.&lt;/p&gt;  &lt;p&gt;Although if you’ve tried unit testing a class that calls static methods that perform such intensive operations, you quickly realize that you must separate them out from your code so that they can be mocked.&amp;#160; But if the methods are in a library you can’t modify, you usually end up very frustrated. There are a few easy ways to mock static methods, and you can choose which option works best for your needs.&lt;/p&gt;  &lt;h2&gt;Background&lt;/h2&gt;  &lt;p&gt;In our example, we have a class that has a single static method. Let’s pretend that this does some intensive activity that you don’t want to do while running your unit test suite. This class is in a library that you can’t modify and make non-static – we’re just looking at the code here as an example.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCantModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeStaticClass&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SomeStaticMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="rem"&gt;// Let's pretend this method hits a database or service.&lt;/span&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(input);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So we have one method that takes a string and returns bool. Keep this in mind.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now, here’s an example of the static method being used. Note that we can not (by default) mock the static call – it’s a tight coupling that can not be easily broken.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCanModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; SomeUntestableClass&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;        {&lt;br /&gt;            var &lt;span class="kwrd"&gt;value&lt;/span&gt; = SomeStaticClass.SomeStaticMethod(input);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; ? 1 : 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Below you will find a variety of options to make this class unit testable without the static call.&lt;/p&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Option 1 – Wrapper Class&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The first option which is extremely easy to do and very Inversion-of-Control-friendly is to make a wrapper class that has the exact same signature as the static methods you’re needing to call, but the only difference is that they are non-static. Each of these methods calls the static version and returns the value (if not void). Then, you can extract an interface to use for wiring up with IoC and mocking (such as with Moq).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In this example, we take the same signature as our static class above, but create a non-static wrapper class.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCanModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; StaticWrapper : IStaticWrapper&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SomeStaticMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; SomeStaticClass.SomeStaticMethod(input);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;With our static wrapper in place, we now extract an interface:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCanModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;interface&lt;/span&gt; IStaticWrapper&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;bool&lt;/span&gt; SomeStaticMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Perfect. Now we have a non-static wrapper class to our static methods that can be mocked. Here’s how to use it in the caller class:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCanModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WrapperMethod&lt;br /&gt;    {&lt;br /&gt;        IStaticWrapper _wrapper;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; WrapperMethod(IStaticWrapper wrapper)&lt;br /&gt;        {&lt;br /&gt;            _wrapper = wrapper;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;        {&lt;br /&gt;            var &lt;span class="kwrd"&gt;value&lt;/span&gt; = _wrapper.SomeStaticMethod(input);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; ? 1 : 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;This class uses constructor injection, but you can do any Inversion-of-Control style you prefer (property injection, etc.). The main point is that we now have a hook where we can insert a mocked wrapper that does &lt;em&gt;not&lt;/em&gt; call the static method. Here’s how our test class might look:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;    [TestClass]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; WrapperMethodTests&lt;br /&gt;    {&lt;br /&gt;        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; TestWrapper : IStaticWrapper&lt;br /&gt;        {&lt;br /&gt;            &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; SomeStaticMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;return&lt;/span&gt; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(input);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        [TestMethod]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod_GivenNull_ShouldReturnZero()&lt;br /&gt;        {&lt;br /&gt;            var wrapper = &lt;span class="kwrd"&gt;new&lt;/span&gt; TestWrapper();&lt;br /&gt;&lt;br /&gt;            var wm = &lt;span class="kwrd"&gt;new&lt;/span&gt; WrapperMethod(wrapper);&lt;br /&gt;&lt;br /&gt;            var output = wm.SomeMethod(&lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            Assert.AreEqual(0, output);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;Notice how the TestWrapper is a private class just used for unit testing, and it does not do any time or I/O intensive operations. This allows our unit tests to execute quickly, providing quick turn-around when things break.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You could also use a mocking framework like Moq to create a mocked IStaticWrapper in the test example above.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Option 2 – Delegates&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If the amount of static operations you’re trying to mock is small, say one or two method calls, you may want to go the delegate route. In this approach, you take optional delegates into the constructor so that by default the class calls the static method, but in your unit tests you can specify a custom delegate (such as a lambda method) that is called instead.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Here’s our caller class using the delegate method:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; SomeLibraryYouCanModify&lt;br /&gt;{&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DelegateMethod&lt;br /&gt;    {&lt;br /&gt;        Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; _delegate;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; DelegateMethod()&lt;br /&gt;        {&lt;br /&gt;            _delegate = SomeStaticClass.SomeStaticMethod;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; DelegateMethod(Func&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;bool&lt;/span&gt;&amp;gt; method)&lt;br /&gt;        {&lt;br /&gt;            _delegate = method;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; SomeMethod(&lt;span class="kwrd"&gt;string&lt;/span&gt; input)&lt;br /&gt;        {&lt;br /&gt;            var &lt;span class="kwrd"&gt;value&lt;/span&gt; = _delegate(input);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; ? 1 : 0;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;If you aren’t familiar with generic delegates, Func&amp;lt;T, TResult&amp;gt; used above is a delegate for a method that takes a parameter of type T and returns a result of type TResult. So now our class, by default, sets the private delegate field to the static method, but in our unit tests we can specify a custom method instead. Here’s a unit test using this approach that passes a lambda into the constructor:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;    [TestClass]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DelegateMethodTests&lt;br /&gt;    {&lt;br /&gt;        [TestMethod]&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod_GivenNull_ShouldReturnZero()&lt;br /&gt;        {&lt;br /&gt;            var dm = &lt;span class="kwrd"&gt;new&lt;/span&gt; DelegateMethod(i =&amp;gt; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(i));&lt;br /&gt;&lt;br /&gt;            var output = dm.SomeMethod(&lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            Assert.AreEqual(0, output);&lt;br /&gt;        }&lt;br /&gt;    }&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt;	font-size: small;&lt;br /&gt;	color: black;&lt;br /&gt;	font-family: consolas, "Courier New", courier, monospace;&lt;br /&gt;	background-color: #ffffff;&lt;br /&gt;	/*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt;	background-color: #f4f4f4;&lt;br /&gt;	width: 100%;&lt;br /&gt;	margin: 0em;&lt;br /&gt;}&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;We get the same result as the wrapper method – the test executes quickly, does not call the static method, and we can verify that the logic inside SomeMethod is correct.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Option 3 – Moles&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Moles is an isolation framework from Microsoft that allows you to mock static method calls without rewriting any implementation code. You can even mock calls to .NET framework methods and properties, like DateTime.Now. The benefits are easy to write unit tests and less refactoring time, although at the expense of maintaining tightly-coupled code. Another drawback of Moles I’ve experienced is that it does not work well in a team environment with Team Foundation Server, because it creates proxy DLLs that are hosted in your unit test project, and multiple users checking out and checking in these DLLs becomes a pain very quickly, especially since the default checkout action is an exclusive lock. However, if you’re a sole developer working on a project, it is a worthwhile choice.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can download Moles (with or without Pex) from &lt;a href="http://research.microsoft.com/en-us/projects/moles/" target="_blank"&gt;Microsoft Research’s Moles Project site&lt;/a&gt;. Make sure that you download the correct version for your CPU (x86 vs x64).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;After installing, you can right click the reference to the library you’d like to mole in your unit test project, and select Add Moles Assembly.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/TX_yesQTsCI/AAAAAAAAAYk/UGRZ06gRpLE/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/TX_yeyTWhZI/AAAAAAAAAYo/ffoNWEUqyCE/image_thumb%5B4%5D.png?imgmax=800" width="404" height="243" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Now that a Moles assembly has been added to the project, you can now create a unit test and mock that call. You must make sure to import the “.Moles” version of the namespace as seen in the example below. All types in the assembly that can be mocked begin with the letter “M”, and for static methods, the method becomes a property (named with the method name followed by all of the parameter types) that is of a delegate type. Then you can “set” that property to a new delegate, such as a lambda in the example below:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;strong&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; SomeLibraryYouCantModify.Moles;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kwrd"&gt;namespace&lt;/span&gt; LibraryTestProject&lt;br /&gt;{&lt;br /&gt;    [TestClass]&lt;br /&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; MoledTests&lt;br /&gt;    {&lt;br /&gt;        [TestMethod]&lt;br /&gt;        &lt;strong&gt;[HostType(&lt;span class="str"&gt;&amp;quot;Moles&amp;quot;&lt;/span&gt;)]&lt;/strong&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; SomeMethod_GivenNull_ShouldReturnZero()&lt;br /&gt;        {&lt;br /&gt;            var c = &lt;span class="kwrd"&gt;new&lt;/span&gt; SomeUntestableClass();&lt;br /&gt;&lt;br /&gt;            &lt;strong&gt;MSomeStaticClass.SomeStaticMethodString&lt;/strong&gt; = i =&amp;gt; !&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(i);&lt;br /&gt;&lt;br /&gt;            var output = c.SomeMethod(&lt;span class="kwrd"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            Assert.AreEqual(0, output);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I’ve bolded the interesting lines. First, you have to import the “.Moles” namespace, as I mentioned earlier. Second, you must add the HostType(“Moles”) to any methods that are to be run in the Moles host. If a test method is not run in the Moles host, it will not be able to use the Moled type, and will let you know with an exception. Finally, the “SomeStaticClass” has a moled “MSomeStaticClass” that provides the mockable methods. The “SomeStaticMethod” method becomes “SomeStaticMethodString”, with the String being added to the name to represent the type of the first and only parameter to the method. This allows for method overloading, as different parameter types will cause different property names on the moled type. Then, the property is set to the given lambda, which is identical to the Delegates example above.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Out of the three methods, I end up preferring the Wrapper method the most, because it is easy to use with IoC containers and Moq. However, it is probably the most amount of work, because you have to create 2 new types, one for the wrapper class and the other for the interface. Also, it means that you have an entire type that has zero coverage, because you can not write unit tests for this wrapper class as it would call the static method.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The delegate method is great for one or two method isolation, as it’s easy to do, doesn’t need to involve the IoC container, and can be easily mocked with constructor overloads. However, it’s the least intuitive code to read, and is clunky to use for more than two method calls.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The Moles method is certainly clever and very impressive on first use. It works great for small projects with one developer, and can allow you to achieve greater code coverage very quickly. However, it is slower to start the unit test run due to the Moles host, it doesn’t help you decouple your code, and it is a pain for multiple developers working on the same project due to source control conflicts.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Obviously, the ideal situation is to have a non-static method to call. If you can get the developer of the library to do it for you, they can create a non-static version of the type/methods that are called by the static version, so that their existing static API is maintained and you get the benefit of being able to wire up the dependency with dependency injection. Clearly, though, this isn’t always possible.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Hope this helps!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-3241881118181352756?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/p2vaLuSOPfhNf7OMSD3NjElSvG8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p2vaLuSOPfhNf7OMSD3NjElSvG8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/p2vaLuSOPfhNf7OMSD3NjElSvG8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/p2vaLuSOPfhNf7OMSD3NjElSvG8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/3241881118181352756/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=3241881118181352756" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3241881118181352756?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3241881118181352756?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2011/03/mocking-static-methods-for-unit-testing.html" title="Mocking Static Methods for Unit Testing" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_xvXvGivrKF0/TX_yeyTWhZI/AAAAAAAAAYo/ffoNWEUqyCE/s72-c/image_thumb%5B4%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0YBQXw_eip7ImA9Wx9QFEs.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-3408567981746800326</id><published>2010-12-27T09:45:00.001-05:00</published><updated>2010-12-27T09:45:50.242-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-27T09:45:50.242-05:00</app:edited><title>ObservableStack&lt;T&gt;</title><content type="html">&lt;p&gt;I had been looking around in the .NET framework for a Stack&amp;lt;T&amp;gt; equivalent of ObservableCollection&amp;lt;T&amp;gt; to use in a WPF application. Couldn’t find one, so I implemented one based on those two classes. Hope this helps!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:aa4e2d90-400a-4d92-a8f0-c4fd8a42b04c" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: csharp; gutter: true; first-line: 1; tab-size: 4;  toolbar: true;  width: 400px; height: 400px;" style=" width: 400px; height: 400px;overflow: auto;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Collections.Specialized;&lt;br /&gt;using System.ComponentModel;&lt;br /&gt;using System.Collections;&lt;br /&gt;&lt;br /&gt;namespace AdventuresDotNet&lt;br /&gt;{&lt;br /&gt;    public class ObservableStack&amp;lt;T&amp;gt; : IEnumerable&amp;lt;T&amp;gt;, ICollection, INotifyCollectionChanged, INotifyPropertyChanged&lt;br /&gt;    {&lt;br /&gt;        T[] _array;&lt;br /&gt;        const int _defaultCapacity = 4;&lt;br /&gt;        static T[] _emptyArray;&lt;br /&gt;        int _size;&lt;br /&gt;        object _syncRoot;&lt;br /&gt;        int _version;&lt;br /&gt;&lt;br /&gt;        static ObservableStack()&lt;br /&gt;        {&lt;br /&gt;            _emptyArray = new T[0];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public ObservableStack()&lt;br /&gt;        {&lt;br /&gt;            _array = _emptyArray;&lt;br /&gt;            _size = 0;&lt;br /&gt;            _version = 0;&lt;br /&gt;            _syncRoot = new object();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public ObservableStack(IEnumerable&amp;lt;T&amp;gt; collection)&lt;br /&gt;        {&lt;br /&gt;            if (collection == null)&lt;br /&gt;                throw new ArgumentNullException(&amp;quot;collection&amp;quot;);&lt;br /&gt;&lt;br /&gt;            var is2 = collection as ICollection&amp;lt;T&amp;gt;;&lt;br /&gt;&lt;br /&gt;            if (is2 != null)&lt;br /&gt;            {&lt;br /&gt;                int count = is2.Count;&lt;br /&gt;                _array = new T[count];&lt;br /&gt;                is2.CopyTo(_array, 0);&lt;br /&gt;                _size = count;&lt;br /&gt;            }&lt;br /&gt;            else&lt;br /&gt;            {&lt;br /&gt;                _size = 0;&lt;br /&gt;                _array = new T[4];&lt;br /&gt;                using (var enumerator = collection.GetEnumerator())&lt;br /&gt;                {&lt;br /&gt;                    while (enumerator.MoveNext())&lt;br /&gt;                    {&lt;br /&gt;                        this.Push(enumerator.Current);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public ObservableStack(int capacity)&lt;br /&gt;        {&lt;br /&gt;            if (capacity &amp;lt; 0)&lt;br /&gt;                throw new ArgumentException(&amp;quot;Invalid capacity.&amp;quot;);&lt;br /&gt;&lt;br /&gt;            _array = new T[capacity];&lt;br /&gt;            _size = 0;&lt;br /&gt;            _version = 0;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void Push(T item)&lt;br /&gt;        {&lt;br /&gt;            if (_size == _array.Length)&lt;br /&gt;            {&lt;br /&gt;                T[] dest = new T[(_array.Length == 0) ? 4 : (2 * _array.Length)];&lt;br /&gt;                Array.Copy(_array, 0, dest, 0, _size);&lt;br /&gt;                _array = dest;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            _array[_size++] = item;&lt;br /&gt;            _version++;&lt;br /&gt;&lt;br /&gt;            OnCollectionAdded(item);&lt;br /&gt;            OnPropertyChanged(&amp;quot;Count&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public T Pop()&lt;br /&gt;        {&lt;br /&gt;            if (_size == 0)&lt;br /&gt;                throw new InvalidOperationException(&amp;quot;Empty stack, can not pop.&amp;quot;);&lt;br /&gt;&lt;br /&gt;            _version++;&lt;br /&gt;            T local = _array[--_size];&lt;br /&gt;            _array[_size] = default(T);&lt;br /&gt;&lt;br /&gt;            OnCollectionRemoved(local, _size);&lt;br /&gt;            OnPropertyChanged(&amp;quot;Count&amp;quot;);&lt;br /&gt;&lt;br /&gt;            return local;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public T Peek()&lt;br /&gt;        {&lt;br /&gt;            if (_size == 0)&lt;br /&gt;                throw new InvalidOperationException(&amp;quot;Empty stack, can not peek.&amp;quot;);&lt;br /&gt;&lt;br /&gt;            return _array[_size - 1];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public event NotifyCollectionChangedEventHandler CollectionChanged;&lt;br /&gt;&lt;br /&gt;        public event PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;&lt;br /&gt;        void OnCollectionReset()&lt;br /&gt;        {&lt;br /&gt;            var c = CollectionChanged;&lt;br /&gt;&lt;br /&gt;            if (c != null)&lt;br /&gt;                c(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void OnCollectionAdded(object item)&lt;br /&gt;        {&lt;br /&gt;            var c = CollectionChanged;&lt;br /&gt;&lt;br /&gt;            if (c != null)&lt;br /&gt;                c(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void OnCollectionRemoved(object item, int index)&lt;br /&gt;        {&lt;br /&gt;            var c = CollectionChanged;&lt;br /&gt;&lt;br /&gt;            if (c != null)&lt;br /&gt;                c(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void OnPropertyChanged(string propertyName)&lt;br /&gt;        {&lt;br /&gt;            var p = PropertyChanged;&lt;br /&gt;&lt;br /&gt;            if (p != null)&lt;br /&gt;                p(this, new PropertyChangedEventArgs(propertyName));&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        public IEnumerator&amp;lt;T&amp;gt; GetEnumerator()&lt;br /&gt;        {&lt;br /&gt;            return new Enumerator(this);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()&lt;br /&gt;        {&lt;br /&gt;            return new Enumerator(this);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        public void Clear()&lt;br /&gt;        {&lt;br /&gt;            Array.Clear(_array, 0, _size);&lt;br /&gt;            _size = 0;&lt;br /&gt;            _version++;&lt;br /&gt;&lt;br /&gt;            OnCollectionReset();&lt;br /&gt;            OnPropertyChanged(&amp;quot;Count&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public bool Contains(T item)&lt;br /&gt;        {&lt;br /&gt;            int index = _size;&lt;br /&gt;&lt;br /&gt;            var comparer = EqualityComparer&amp;lt;T&amp;gt;.Default;&lt;br /&gt;&lt;br /&gt;            while (index-- &amp;gt; 0)&lt;br /&gt;            {&lt;br /&gt;                if (item == null)&lt;br /&gt;                {&lt;br /&gt;                    if (_array[index] == null)&lt;br /&gt;                        return true;&lt;br /&gt;                }&lt;br /&gt;                else if (_array[index] != null &amp;amp;&amp;amp; comparer.Equals(_array[index], item))&lt;br /&gt;                {&lt;br /&gt;                    return true;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public void CopyTo(T[] array, int arrayIndex)&lt;br /&gt;        {&lt;br /&gt;            if (array == null)&lt;br /&gt;                throw new ArgumentNullException(&amp;quot;array&amp;quot;);&lt;br /&gt;&lt;br /&gt;            if (arrayIndex &amp;lt; 0 || arrayIndex &amp;gt; array.Length)&lt;br /&gt;                throw new ArgumentOutOfRangeException(&amp;quot;arrayIndex&amp;quot;);&lt;br /&gt;&lt;br /&gt;            if ((array.Length - arrayIndex) &amp;lt; _size)&lt;br /&gt;                throw new ArgumentException();&lt;br /&gt;&lt;br /&gt;            Array.Copy(_array, 0, array, arrayIndex, _size);&lt;br /&gt;            Array.Reverse(array, arrayIndex, _size);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public int Count&lt;br /&gt;        {&lt;br /&gt;            get { return _size; }&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        public bool IsSynchronized&lt;br /&gt;        {&lt;br /&gt;            get { return false; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public object SyncRoot&lt;br /&gt;        {&lt;br /&gt;            get { return _syncRoot; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        void ICollection.CopyTo(Array array, int index)&lt;br /&gt;        {&lt;br /&gt;            Array.Copy(this._array, 0, array, index, this._size);&lt;br /&gt;            Array.Reverse(array, index, this._size);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        public struct Enumerator : IEnumerator&amp;lt;T&amp;gt;, IDisposable, IEnumerator&lt;br /&gt;        {&lt;br /&gt;            ObservableStack&amp;lt;T&amp;gt; _stack;&lt;br /&gt;            int _index;&lt;br /&gt;            int _version;&lt;br /&gt;            T currentElement;&lt;br /&gt;&lt;br /&gt;            internal Enumerator(ObservableStack&amp;lt;T&amp;gt; stack)&lt;br /&gt;            {&lt;br /&gt;                _stack = stack;&lt;br /&gt;                _version = _stack._version;&lt;br /&gt;                _index = -2;&lt;br /&gt;                currentElement = default(T);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            public T Current&lt;br /&gt;            {&lt;br /&gt;                get&lt;br /&gt;                {&lt;br /&gt;                    if (_index &amp;lt; 0)&lt;br /&gt;                        throw new InvalidOperationException();&lt;br /&gt;&lt;br /&gt;                    return currentElement;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            public void Dispose()&lt;br /&gt;            {&lt;br /&gt;                _index = -1;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            object IEnumerator.Current&lt;br /&gt;            {&lt;br /&gt;                get&lt;br /&gt;                {&lt;br /&gt;                    if (_index &amp;lt; 0)&lt;br /&gt;                        throw new InvalidOperationException();&lt;br /&gt;&lt;br /&gt;                    return currentElement;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            public bool MoveNext()&lt;br /&gt;            {&lt;br /&gt;                bool flag;&lt;br /&gt;&lt;br /&gt;                if (_version != _stack._version)&lt;br /&gt;                    throw new InvalidOperationException(&amp;quot;Version mismatch.&amp;quot;);&lt;br /&gt;&lt;br /&gt;                if (_index == -2)&lt;br /&gt;                {&lt;br /&gt;                    _index = _stack._size - 1;&lt;br /&gt;                    flag = _index &amp;gt;= 0;&lt;br /&gt;&lt;br /&gt;                    if (flag)&lt;br /&gt;                        currentElement = _stack._array[_index];&lt;br /&gt;&lt;br /&gt;                    return flag;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                if (_index == -1)&lt;br /&gt;                    return false;&lt;br /&gt;&lt;br /&gt;                flag = --_index &amp;gt;= 0;&lt;br /&gt;&lt;br /&gt;                if (flag)&lt;br /&gt;                {&lt;br /&gt;                    currentElement = _stack._array[_index];&lt;br /&gt;                    return flag;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                currentElement = default(T);&lt;br /&gt;                return flag;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            public void Reset()&lt;br /&gt;            {&lt;br /&gt;                if (_version != _stack._version)&lt;br /&gt;                    throw new InvalidOperationException(&amp;quot;Version mismatch.&amp;quot;);&lt;br /&gt;&lt;br /&gt;                _index = -2;&lt;br /&gt;                currentElement = default(T);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-3408567981746800326?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CD9nguKSDv5yYj3zaFzwA1YxdBA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CD9nguKSDv5yYj3zaFzwA1YxdBA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CD9nguKSDv5yYj3zaFzwA1YxdBA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CD9nguKSDv5yYj3zaFzwA1YxdBA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/3408567981746800326/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=3408567981746800326" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3408567981746800326?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3408567981746800326?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/12/observablestack.html" title="ObservableStack&amp;lt;T&amp;gt;" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0IEQnw6eyp7ImA9Wx5VEkw.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-195429077527859430</id><published>2010-10-04T14:51:00.003-04:00</published><updated>2010-10-04T15:11:43.213-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-04T15:11:43.213-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Threading" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="multithreading" /><title>HttpContext.Current and Threads with QueueUserWorkItem</title><content type="html">&lt;p&gt;If you’ve got an ASP.NET (including MVC) application that uses ThreadPool.QueueUserWorkItem with a reset event or anything of the like, you can not access HttpContext.Current (or rather, it is null) on those threads. This makes exception logging difficult, especially if you want to log the URL that is currently being requested.&lt;/p&gt;  &lt;p&gt;After a little digging, I discovered that the current HttpContext is actually in thread-local storage, which explains why child threads don’t have access to it. Luckily, you can pass a reference to it in your child thread. Include a reference to HttpContext in the “state” object of your callback method, and then you can store it to HttpContext.Current on that thread. If you notice, HttpContext.Current is not a read-only property – it has a setter as well. Set HttpContext.Current = myStateObj.HttpContextReference where myStateObj is your state object.&lt;/p&gt;  &lt;p&gt;I feel like this post is a bit self-explanatory, but here’s an obligatory example if you don’t follow:&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8364e5d5-945e-4769-a60f-b749736bc14f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4;  toolbar: true;  width: 400px; height: 314px;" style=" width: 400px; height: 314px;overflow: auto;"&gt;private AutoResetEvent s_reset = new AutoResetEvent(false);&lt;br /&gt;&lt;br /&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    var state = new WorkerState() { HttpContextReference = HttpContext.Current };&lt;br /&gt;    ThreadPool.QueueUserWorkItem(new WaitCallback(Worker), state);&lt;br /&gt;&lt;br /&gt;    try&lt;br /&gt;    {&lt;br /&gt;        s_reset.WaitOne();&lt;br /&gt;    }&lt;br /&gt;    finally&lt;br /&gt;    {&lt;br /&gt;        s_reset.Close();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void Worker(object state)&lt;br /&gt;{&lt;br /&gt;    var mystate = state as WorkerState;&lt;br /&gt;&lt;br /&gt;    if (mystate != null &amp;amp;&amp;amp; mystate.HttpContextReference != null)&lt;br /&gt;    {&lt;br /&gt;        HttpContext.Current = mystate.HttpContextReference;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    HttpContext.Current.Response.Write(&amp;quot;Threading!&amp;quot;);&lt;br /&gt;&lt;br /&gt;    s_reset.Set();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private class WorkerState&lt;br /&gt;{&lt;br /&gt;    public HttpContext HttpContextReference { get; set; }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;p&gt;And, of course, it works:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TKoiL0XMQKI/AAAAAAAAAXU/kuQH6RlNBGA/s1600-h/image%5B3%5D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/TKoiMed4SiI/AAAAAAAAAXY/ST-qnGBLz0M/image_thumb%5B1%5D.png?imgmax=800" width="318" height="207" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Hope this helps!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-195429077527859430?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/dPcu8Bqzo6S8QckTyJbfUZLvHcY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dPcu8Bqzo6S8QckTyJbfUZLvHcY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/dPcu8Bqzo6S8QckTyJbfUZLvHcY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/dPcu8Bqzo6S8QckTyJbfUZLvHcY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/195429077527859430/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=195429077527859430" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/195429077527859430?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/195429077527859430?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/10/httpcontextcurrent-and-threads-with.html" title="HttpContext.Current and Threads with QueueUserWorkItem" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_xvXvGivrKF0/TKoiMed4SiI/AAAAAAAAAXY/ST-qnGBLz0M/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;D0AHRng4fyp7ImA9Wx5WEE0.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-4238262179151706595</id><published>2010-09-20T14:00:00.002-04:00</published><updated>2010-09-20T14:02:17.637-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-20T14:02:17.637-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Combining and Abusing Delegates</title><content type="html">&lt;p&gt;I had never before thought much about combining delegates until I came across some code that combined them using lambdas, and it got me thinking about other ways to use them. Consider the following example. Note: crazy code ahead!&lt;/p&gt; &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:03a74474-ec83-4b11-8171-454ac60e08f3" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4;  toolbar: false;  width: 400px; height: 300px;" style=" width: 400px; height: 300px;overflow: auto;"&gt;public class Programmer&lt;br /&gt;{&lt;br /&gt;    Action&amp;lt;string&amp;gt; a;&lt;br /&gt;&lt;br /&gt;    public Programmer(string name)&lt;br /&gt;    {&lt;br /&gt;        this.Name = name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public string Name { get; set; }&lt;br /&gt;&lt;br /&gt;    public bool ShouldDesign&lt;br /&gt;    {&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            if (value)&lt;br /&gt;                a += s =&amp;gt; { Console.WriteLine(Name + &amp;quot; should design &amp;quot; + s); };&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public bool ShouldDevelop&lt;br /&gt;    {&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            if (value)&lt;br /&gt;                a += s =&amp;gt; { Console.WriteLine(Name + &amp;quot; should develop &amp;quot; + s); };&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public bool ShouldDeploy&lt;br /&gt;    {&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            if (value)&lt;br /&gt;                a += s =&amp;gt; { Console.WriteLine(Name + &amp;quot; should deploy &amp;quot; + s); };&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Work(string programName)&lt;br /&gt;    {&lt;br /&gt;        a(programName);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;p&gt;And then used in a console app like this:&lt;/p&gt;&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:ca22a207-ef8a-4e77-bb04-fae9a657f02f" class="wlWriterEditableSmartContent"&gt;&lt;pre class="brush: csharp; gutter: false; first-line: 1; tab-size: 4;  toolbar: false;  width: 400px; height: 238px;" style=" width: 400px; height: 238px;overflow: auto;"&gt;static void Main(string[] args)&lt;br /&gt;{&lt;br /&gt;    var paul = new Programmer(&amp;quot;Paul&amp;quot;);&lt;br /&gt;    paul.ShouldDesign = true;&lt;br /&gt;    paul.ShouldDevelop = true;&lt;br /&gt;    paul.ShouldDeploy = false;&lt;br /&gt;&lt;br /&gt;    paul.Work(&amp;quot;my application&amp;quot;);&lt;br /&gt;&lt;br /&gt;    Console.ReadKey();&lt;br /&gt;}&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;&lt;p&gt;And the output…&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/TJehOfpfC0I/AAAAAAAAAXM/3rP04R6af0w/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/TJehOuAOX0I/AAAAAAAAAXQ/qos3Ybsoj0E/image_thumb%5B1%5D.png?imgmax=800" width="283" height="50" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I do not encourage the kind of code I’ve created here, but maybe this will get you thinking!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-4238262179151706595?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XSz2tJzBEVqCV-ZQQWE0WtS7WGc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XSz2tJzBEVqCV-ZQQWE0WtS7WGc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XSz2tJzBEVqCV-ZQQWE0WtS7WGc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XSz2tJzBEVqCV-ZQQWE0WtS7WGc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/4238262179151706595/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=4238262179151706595" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/4238262179151706595?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/4238262179151706595?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/09/combining-and-abusing-delegates.html" title="Combining and Abusing Delegates" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_xvXvGivrKF0/TJehOuAOX0I/AAAAAAAAAXQ/qos3Ybsoj0E/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0YNRno8fCp7ImA9Wx5XFUw.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-881311949244639492</id><published>2010-09-14T22:53:00.001-04:00</published><updated>2010-09-14T22:53:17.474-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-14T22:53:17.474-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Thoughts on the Microsoft Ecosystem</title><content type="html">&lt;p&gt;I had the great opportunity to touch a Windows Phone 7 device at the Jacksonville Code Camp a few weeks ago, and it sold me – I’ll likely give up my iPhone 4 for a Windows Phone 7 device when they ship this fall. The biggest selling point as a C# developer is that I can develop both data-driven apps in Silverlight and games in XNA for Windows Phone 7 in the language I use every day – C#. So that got me thinking about where else C# and the .NET platform can be used, both at work and at home.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Windows 7 client apps in WPF (with multi-touch for tablets)&lt;/li&gt;    &lt;li&gt;Rich Internet Apps with Silverlight 4 (again with multi-touch)&lt;/li&gt;    &lt;li&gt;Websites with ASP.NET and ASP.NET MVC&lt;/li&gt;    &lt;li&gt;Scaffolding data-driven sites with ASP.NET Dynamic Data&lt;/li&gt;    &lt;li&gt;Windows Phone 7 data-driven apps in Silverlight&lt;/li&gt;    &lt;li&gt;Games for Windows Phone 7 with XNA&lt;/li&gt;    &lt;li&gt;Games for PC with XNA&lt;/li&gt;    &lt;li&gt;Games for Xbox 360 with XNA&lt;/li&gt;    &lt;li&gt;Middleware real-time services with WCF&lt;/li&gt;    &lt;li&gt;Middleware queued services with WCF, WF, and MSMQ&lt;/li&gt;    &lt;li&gt;SQL Server integration with CLR stored procedures&lt;/li&gt;    &lt;li&gt;Windows Media Center apps with the Media Center SDK&lt;/li&gt;    &lt;li&gt;Embedded device apps with WPF (Windows Embedded)&lt;/li&gt;    &lt;li&gt;Small-scale embedded devices with .NET Micro Framework (including Netduino)&lt;/li&gt;    &lt;li&gt;Windows Home Server add-ins with the WHS SDK&lt;/li&gt;    &lt;li&gt;Cloud apps with the Windows Azure SDK&lt;/li&gt;    &lt;li&gt;SharePoint parts and sites&lt;/li&gt;    &lt;li&gt;Office add-ins for Outlook, Excel, Word, and others&lt;/li&gt;    &lt;li&gt;Surface development with the Surface SDK (which will be in our homes within a few years)&lt;/li&gt;    &lt;li&gt;… and probably a dozen other things I’m forgetting.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;That’s a huge list, and I’ve heard complaints from people that the ecosystem has gotten too big, and therefore too much to keep track of and learn. I don’t look at it that way – I view all of these varied and important areas as all using the same foundation, C# and the .NET framework. If you know C# and the framework, you can jump from one to the other with a minimal learning curve. A WPF developer can jump to Silverlight and then to Surface and then to Windows Media Center and then to Windows Phone 7 with Silverlight without much to learn. An ASP.NET developer can jump to ASP.NET MVC and to Windows Azure and to SharePoint, again with minimal learning. Compared to jumping to another framework or another language, jumping between any of these technologies is relatively painless.&lt;/p&gt;  &lt;p&gt;It’s a great time to be a .NET developer, and the potential with all of these technologies excites me!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-881311949244639492?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uuzIryN7db1iMInwyXj35GwakPo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uuzIryN7db1iMInwyXj35GwakPo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uuzIryN7db1iMInwyXj35GwakPo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uuzIryN7db1iMInwyXj35GwakPo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/881311949244639492/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=881311949244639492" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/881311949244639492?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/881311949244639492?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/09/thoughts-on-microsoft-ecosystem.html" title="Thoughts on the Microsoft Ecosystem" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0AGQHk5eCp7ImA9Wx5RE0k.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-5995559387354432451</id><published>2010-08-20T19:08:00.001-04:00</published><updated>2010-08-20T19:08:41.720-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-20T19:08:41.720-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="VS2010" /><category scheme="http://www.blogger.com/atom/ns#" term="WF" /><title>My First Workflow Foundation (WF) 4 App</title><content type="html">&lt;p&gt;I came across a book in our company’s “library” today – Microsoft Windows Workflow Foundation, Step by Step – and I started thinking about whether or not I should try to learn WF. Frankly, I haven’t been interested so far. Being a front-end developer, I haven’t really developed many service-level applications or processes, and of the ones I’ve touched, it seems like remoting, WCF, and/or MSMQ works rather well for those tasks. However, I came across NServiceBus this past week and it got me thinking more in the mindset of a service designer, and WF piqued my interest. A good developer tries to be well-rounded and knowledgeable about other technologies, even if he or she doesn’t use them on a daily basis.&lt;/p&gt;  &lt;p&gt;I started flipping through the first chapter of this book. I quickly realized that it’s a 3 year old book (a lifetime in software technologies) and is about .NET 3.0 – the red-headed stepchild release of .NET. WF, of course, has seen 2 revisions since, with .NET 3.5 and again with 4.0. Nonetheless, I enjoyed the first chapter, and I started to see where WF could be useful. (Despite, that is, a question I posted on &lt;a href="http://twitter.com/paulirwin"&gt;twitter&lt;/a&gt; asking if anyone has used WF, to which I got zero responses.)&lt;/p&gt;  &lt;p&gt;I came home, fired up my beast of a work laptop (Core i7 4core/8thread, 8GB RAM), and launched Visual Studio 2010. File – New Project. Immediately I noticed a difference from the first chapter of this book. In the .NET 3 version, you have to choose between a Sequential or State Machine workflow type and then between a console app or library, or an “activity library”, or an empty workflow project. In VS2010, you only have 2 non-library Workflow project types – WCF Workflow Service, and Workflow Console App. I chose the Workflow Console App because it more closely matched the example. Then the similarities came to a screeching halt.&lt;/p&gt;  &lt;p&gt;I hadn’t kept up with WF, otherwise I should have known this. WF in 4.0 uses XAML to describe workflows, and the only “code” in the workflow are “expressions” in… wait for it… VB. Yes, even though I created a C# Workflow Console App, the expressions are in Visual Basic. Furthermore, the example in the book is a .cs file (not .xaml), and has an accompanying .Designer.cs file as a “code-behind”. Better still, when you create “Code” activities in the older WF, they are methods in a C# file. The only equivalent to the “Code” activity I found in WF 4 is the “InvokeMethod” activity, which can only call a method on a type &lt;em&gt;not&lt;/em&gt; defined in the workflow.&lt;/p&gt;  &lt;p&gt;Still, I was able to accomplish a fairly basic If/Else workflow in WF4. Here’s what it looks like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/TG8K8CLl9HI/AAAAAAAAAWk/hvCVBNcM7kI/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/TG8K8Vez9bI/AAAAAAAAAWo/2hgz2tTV3Js/image_thumb%5B1%5D.png?imgmax=800" width="488" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Fairly trivial. If a “PostalCodeIsValid”, then I write a line to the console saying it’s valid, and if not, I write a line saying it’s not. Notice the VB ampersands for string concatenation in the “Text” fields.&lt;/p&gt;  &lt;p&gt;Look at the Condition field. I’m executing a method on a “Workflow1Helper” static class I created for simplicity. That method simply returns “PostalCode.Length == 5” which is not a true postal code validation routine, but could be replaced with one. Luckily, the Workflow1Helper class is written in C#.&lt;/p&gt;  &lt;p&gt;It seems like this is the pattern for WF4 workflows – define your workflow in XAML, and farm out your code to other types. Makes since, especially from a separation of concerns aspect, but it’s hardly similar to WF in .NET 3.0.&lt;/p&gt;  &lt;p&gt;So where does that PostalCode field come from? You must define it as an “Argument”. If you look at the bottom of the workflow designer, you’ll see this pane:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TG8K8uCs0rI/AAAAAAAAAWs/ARPYC0H13Ek/s1600-h/image%5B6%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TG8K9KojSUI/AAAAAAAAAWw/pR80qS53T4c/image_thumb%5B2%5D.png?imgmax=800" width="214" height="77" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The Arguments tab brings up this pane:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/TG8K9Wgw4tI/AAAAAAAAAW0/HQffU-M1ASk/s1600-h/image%5B10%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/TG8K9vVEX2I/AAAAAAAAAW4/IPy3U7qm8cE/image_thumb%5B4%5D.png?imgmax=800" width="504" height="127" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;That’s where I created the PostalCode argument. You can define any type and number of arguments you want, think of them as “parameters” to your workflow when you invoke it (more on invocation later). Also note you can assign a Default Value, i.e. “New MyType()” (alas, &lt;em&gt;sigh&lt;/em&gt;, again in VB.)&lt;/p&gt;  &lt;p&gt;Lastly, the invocation. There’s a Program.cs file that gets created as part of the project, and it’s a standard console app entry point class. I just had to modify the invocation part to pass the PostalCode argument:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TG8K94oPb9I/AAAAAAAAAW8/6qHPLBxjnis/s1600-h/image%5B14%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/TG8K-Gy1uBI/AAAAAAAAAXA/frjx2KoR1ec/image_thumb%5B6%5D.png?imgmax=800" width="542" height="112" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(I apologize for the code-screenshot, I am lazy and haven’t installed the PreCode plug-in yet.)&lt;/p&gt;  &lt;p&gt;Obviously, hitting F5 will run the app, and we get a message saying it’s valid. Yay.&lt;/p&gt;  &lt;p&gt;Now time for the dramatic conclusion. WF4 seems much more polished than WF in .NET 3 appears in the book. I love that it’s XAML (although you really don’t want to go in and modify it, it’s pretty ugly), and I love that the code is separated from the workflow logic. It’s all very professional – easy to understand, self-documenting processes, and very easy to grasp. I also created my second WF app, this time as a WCF service, and I think that’s a much more useful paradigm than a console app, especially if it’s possible to use with a MSMQ binding (which I haven’t tried). &lt;/p&gt;  &lt;p&gt;For the negatives, I dislike the fact that a C# WF app needs to use VB expressions, because I dislike having to switch gears. I don’t mind coding in VB if I have to, but would it have killed them to allow C# expressions?&lt;/p&gt;  &lt;p&gt;I want to read up more on WF, as well as it’s migration from 3 –&amp;gt; 3.5 –&amp;gt; 4, as well as play around more with the WCF version of it before writing another blog post on the subject. &lt;/p&gt;  &lt;p&gt;Bottom line, fire up Visual Studio 2010 and create your first WF app and go to town. Come up with some cool real-world ways to use it, and let me know, will you?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-5995559387354432451?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9CfMua-AjLdaL3QwUC1pzijBF0M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9CfMua-AjLdaL3QwUC1pzijBF0M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9CfMua-AjLdaL3QwUC1pzijBF0M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9CfMua-AjLdaL3QwUC1pzijBF0M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/5995559387354432451/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=5995559387354432451" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/5995559387354432451?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/5995559387354432451?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/08/my-first-workflow-foundation-wf-4-app.html" title="My First Workflow Foundation (WF) 4 App" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_xvXvGivrKF0/TG8K8Vez9bI/AAAAAAAAAWo/2hgz2tTV3Js/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkUMRn48eSp7ImA9Wx5TGEk.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-3742808247853310266</id><published>2010-08-03T08:50:00.003-04:00</published><updated>2010-08-03T08:58:07.071-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-03T08:58:07.071-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jaxcc" /><title>Jax Code Camp - August 28th, 2010</title><content type="html">Last year about this time I was just in the process of moving to Jacksonville, but I made sure that despite living out of boxes, I made it to the Jax Code Camp 2009. It was a great event, tons of people (somewhere north of 600?), and had a great after party where you get valuable time socializing with the community.&lt;br /&gt;&lt;br /&gt;This year, it's happening again, and I'm a speaker. It's on Saturday, August 28th, 2010 at the UNF campus. You can get more details at &lt;a href="http://www.jaxcodecamp.com"&gt;http://www.jaxcodecamp.com&lt;/a&gt;. Registration is free, and there's many sessions and tracks available, including one all-day session about Windows Phone 7 that you can pop in and out of.&lt;br /&gt;&lt;br /&gt;My talk is titled "Dynamic Code with IL and Expressions" and from the IL side I'll be covering how to use DynamicMethod to create functions and methods at runtime with IL emit, as well as how to use AssemblyBuilder to create entire types and assemblies at runtime (such as creating derived "proxy" classes for aspect-oriented programming). From the Expression side, I'll show how to parse Expressions for simple key selectors to advanced LINQ providers, and how to create methods (much like you would in IL) with Expressions to do a number of common tasks.&lt;br /&gt;&lt;br /&gt;Hope to see you there! Again, it's a free, all-day conference-style event with breakfast, lunch, and an after-party. You won't want to miss it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-3742808247853310266?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RKaiu6gEihQYMBjKBoNao3PDy2k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RKaiu6gEihQYMBjKBoNao3PDy2k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RKaiu6gEihQYMBjKBoNao3PDy2k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RKaiu6gEihQYMBjKBoNao3PDy2k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/3742808247853310266/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=3742808247853310266" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3742808247853310266?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3742808247853310266?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/08/jax-code-camp-august-28th-2010.html" title="Jax Code Camp - August 28th, 2010" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D08MQno5cSp7ImA9WxFUGU8.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-8981168736452130661</id><published>2010-06-30T15:23:00.002-04:00</published><updated>2010-06-30T15:24:43.429-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-30T15:24:43.429-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ienumerable" /><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><category scheme="http://www.blogger.com/atom/ns#" term="extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>A better, more type-safe, alternative to Cast&lt;T&gt;()</title><content type="html">&lt;p&gt;I ran into a limitation in the Cast extension method included with LINQ (Enumerable.Cast&amp;lt;TResult&amp;gt;(this IEnumerable source)), specifically that it does not allow for explicit/implicit conversion operators. The reason for this is that it is an extension method on IEnumerable, not IEnumerable&amp;lt;T&amp;gt;. Therefore the “Current” property (see previous post on IEnumerable&amp;lt;T&amp;gt;) is of type Object, and it can’t perform the cast from type A to Object to type B if there’s a conversion operator on either type.&lt;/p&gt;  &lt;p&gt;I wrote a quick extension method to handle this:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;public static IEnumerable&amp;lt;TDest&amp;gt; CastAll&amp;lt;TItem, TDest&amp;gt;(this IEnumerable&amp;lt;TItem&amp;gt; items)&lt;br /&gt;{&lt;br /&gt;    var p = Expression.Parameter(typeof(TItem), &amp;quot;i&amp;quot;);&lt;br /&gt;    var c = Expression.Convert(p, typeof(TDest));&lt;br /&gt;    var ex = Expression.Lambda&amp;lt;Func&amp;lt;TItem, TDest&amp;gt;&amp;gt;(c, p).Compile();&lt;br /&gt;&lt;br /&gt;    foreach (var item in items)&lt;br /&gt;    {&lt;br /&gt;        yield return ex(item);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Basically it builds an Expression that takes TItem, performs a type-safe Convert expression to TDest, and compiles that expression to a lambda of type Func&amp;lt;TItem, TDest&amp;gt; once per call (this could be cached outside of the method), and calls this new function on each item. Now it does a direct cast from TItem to TDest, instead of the type-unsafe A to Object to B casting that Cast&amp;lt;T&amp;gt; does.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Hope this helps!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-8981168736452130661?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rAl5tJphfTmWApVAODwCuP-M_1U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rAl5tJphfTmWApVAODwCuP-M_1U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rAl5tJphfTmWApVAODwCuP-M_1U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rAl5tJphfTmWApVAODwCuP-M_1U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/8981168736452130661/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=8981168736452130661" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8981168736452130661?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8981168736452130661?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/06/better-more-type-safe-alternative-to.html" title="A better, more type-safe, alternative to Cast&amp;lt;T&amp;gt;()" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;DE8NQ3wzfCp7ImA9WxFVEUo.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-1696343094391308494</id><published>2010-06-10T09:33:00.001-04:00</published><updated>2010-06-10T09:34:52.284-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-10T09:34:52.284-04:00</app:edited><title>My Apologies</title><content type="html">I accidentally recently marked many valid comments as rejected when going through them (which was long overdue!). I apologize, there were some good posts there that are now lost. I was attempting to reject just one spam one but accidentally had others checked and Blogger decided I wanted to reject all of them.&lt;br /&gt;&lt;br /&gt;Meanwhile, I recently discovered that one of my previous posts on extension methods was incorrect. I'll follow up soon (hopefully) with a corrected version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-1696343094391308494?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SFWAbrLxG_6FLAjQoK9CZpNpgGc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SFWAbrLxG_6FLAjQoK9CZpNpgGc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SFWAbrLxG_6FLAjQoK9CZpNpgGc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SFWAbrLxG_6FLAjQoK9CZpNpgGc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/1696343094391308494/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=1696343094391308494" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/1696343094391308494?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/1696343094391308494?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/06/my-apologies.html" title="My Apologies" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEYFSXY-eyp7ImA9WxFVEks.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-8572763756655870622</id><published>2010-06-01T16:10:00.006-04:00</published><updated>2010-06-11T09:15:18.853-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-11T09:15:18.853-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ienumerable" /><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><category scheme="http://www.blogger.com/atom/ns#" term="extension methods" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Understanding C#’s “yield” Keyword and IEnumerable&lt;T&gt;</title><content type="html">One of the interview questions I usually give candidates for .NET developer positions is around IEnumerable&amp;lt;T&amp;gt;. What is it? What pattern does it represent under the hood? How would you use it? You might be surprised to see how many candidates have no idea what it even is, yet they probably use it everyday, or at least it’s older brother, IEnumerable.&lt;br /&gt;&lt;br /&gt;IEnumerable and IEnumerable&amp;lt;T&amp;gt; represent a sequence of items that can be iterated over (forward only), and may be lazy evaluated upon iteration. Note that I carefully didn’t use the term “collection”, rather “sequence”, because collection implies that the items are known ahead of time, before evaluation. With IEnumerable and IEnumerable&amp;lt;T&amp;gt;, you can generate objects on the fly as you iterate over the sequence if you wish.&lt;br /&gt;&lt;br /&gt;Before we get to IEnumerable&amp;lt;T&amp;gt;, let’s look at IEnumerable. Bring back your .NET 1.1 hats, ladies and gentlemen. IEnumerable, as the “I” in the name suggests, is an interface only. It does not provide any functionality. IEnumerable only defines one method, called GetEnumerator(), that returns an IEnumerator. The purpose of separating IEnumerable and IEnumerator, I believe, is to logically separate the functions of a sequence of items as a whole, and performing the actual iteration over them.&lt;br /&gt;&lt;br /&gt;Let’s create a class that implements IEnumerable, called OldEnumerable (since this is before generics in .NET 2.0).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class OldEnumerable : IEnumerable&lt;br /&gt;{&lt;br /&gt;    public IEnumerator GetEnumerator()&lt;br /&gt;    {&lt;br /&gt;        return new OldEnumerator();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Very simple, right? All we’re doing is returning an instance of OldEnumerator. Do note that an actual class that implements IEnumerable would probably be doing a lot more than this, such as providing utility functions or such. Also, a real-world implementation would probably pass some information about the sequence’s state or identity to the constructor of OldEnumerator, which is not only valid but encouraged, since interfaces can not define the required signatures of any constructors.&lt;br /&gt;&lt;br /&gt;Now let’s look at OldEnumerator, before we look at a sample of how to use it.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class OldEnumerator : IEnumerator&lt;br /&gt;{&lt;br /&gt;    int x = 0;&lt;br /&gt;&lt;br /&gt;    public object Current&lt;br /&gt;    {&lt;br /&gt;        get { return x; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public bool MoveNext()&lt;br /&gt;    {&lt;br /&gt;        return x++ &amp;lt; 100;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Reset()&lt;br /&gt;    {&lt;br /&gt;        x = 0;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This class does one thing and one thing well – return numbers from 1 to 100. Notice that it implements the IEnumera&lt;strong&gt;tor&lt;/strong&gt; interface, not IEnumera&lt;strong&gt;ble&lt;/strong&gt;. This interface dictates the property and two methods you see above – namely the read-only property Current (note the return type of System.Object), MoveNext() which returns boolean, and Reset(). The names should be pretty self explanatory – Current returns the current item, MoveNext() tries to move to the next item (and returns false if it can not), and Reset(), which resets the enumerator to it’s (hopefully) original state.&lt;br /&gt;&lt;br /&gt;In this example, we have a private variable x, which is simply returned by Current whenever it is requested. Note that a real-world example would probably throw an exception if MoveNext() had not yet been called. (And this is an important note: MoveNext() must be called to access the first item before Current can be called, according to the way that IEnumerable is used throughout the framework.)&lt;br /&gt;&lt;br /&gt;Our MoveNext() method returns whether the value of x is less than 100, then increments x by 1. This allows 100 to be an inclusive maximum value of this sequence. By initializing x to 0, since MoveNext() should be called before any calls to Current, this ensures that the sequence will start at 1. Finally, the Reset() method sets x to 0, and upon the next MoveNext() call, x will start the sequence over again at 1.&lt;br /&gt;&lt;br /&gt;So let’s look at an example of how to use our new OldEnumerable and OldEnumerator classes. (This is in the Main() method of a console application.)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;var old = new OldEnumerable();&lt;br /&gt;&lt;br /&gt;var oldenum = old.GetEnumerator();&lt;br /&gt;&lt;br /&gt;while (oldenum.MoveNext())&lt;br /&gt;{&lt;br /&gt;    object i = oldenum.Current;&lt;br /&gt;&lt;br /&gt;    Console.WriteLine(i);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Console.ReadKey();&lt;/pre&gt;&lt;br /&gt;As you can see, we first create our IEnumerable class, then call GetEnumerator to get our IEnumerator class. We don’t actually know that we’re working with GetEnumerator here, we’re merely working by contract with IEnumerator. Next, we have a while loop with a precondition of oldenum.MoveNext(), which returns whether or not we can access the next element in the sequence. If we can, we get the Current element (again of type Object), and implicitly call its ToString() method in the call to Console.WriteLine(). We now get the following output:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/TAVpI5RE3rI/AAAAAAAAAVU/RrmAsQdJsZ4/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpJuuvDzI/AAAAAAAAAVY/1PTtyv346wo/image_thumb%5B2%5D.png?imgmax=800" border="0" height="285" width="532" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(I’m assuming you can trust me when I say it starts at 1. In retrospect, going 1 to 10 would have been a better example.)&lt;br /&gt;&lt;br /&gt;When you look at IEnumerable/IEnumerator this way, you quickly realize that the values of x were not pre-calculated. Instead, they were lazy evaluated and calculated on the fly. This is why I chose to use the term “sequence” instead of “collection” earlier.&lt;br /&gt;&lt;br /&gt;Obviously, calling GetEnumerator and storing it’s output into a new variable, and calling MoveNext() and Current from a “while” loop is not the cleanest way of looping over items. We’d much rather do this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;var old = new OldEnumerable();&lt;br /&gt;&lt;br /&gt;foreach (var i in old)&lt;br /&gt;    Console.WriteLine(i);&lt;br /&gt;&lt;br /&gt;Console.ReadKey();&lt;/pre&gt;&lt;br /&gt;Much better. And, best of all, it still works as expected. Why? There’s a compiler trick going on here. To find what it is, we first step through the code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/TAVpKOQiy7I/AAAAAAAAAVc/8jlB7WyrORo/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpKdmIpkI/AAAAAAAAAVg/gEtjV3H0EbA/image_thumb%5B3%5D.png?imgmax=800" border="0" height="117" width="232" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After highlighting the foreach keyword and hitting F10 to continue stepping, it first highlights the “old” in the statement as seen above. Next step it highlights “in”:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TAVpKqbWIaI/AAAAAAAAAVk/1y2VGizXh0k/s1600-h/image%5B10%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/TAVpLH-jc1I/AAAAAAAAAVo/EHvxM42K0eU/image_thumb%5B4%5D.png?imgmax=800" border="0" height="119" width="231" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And then on the next step, it highlights “var i”:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpLfUU9qI/AAAAAAAAAVs/0f04VfybclY/s1600-h/image%5B13%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpLs3f1cI/AAAAAAAAAVw/gSm8PhTcsJU/image_thumb%5B5%5D.png?imgmax=800" border="0" height="114" width="228" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What’s going on here? Why is it moving backwards? Actually, it’s performing GetEnumerator(), MoveNext(), and Current in those three steps, in that order. When “old” is highlighted, it calls GetEnumerator() and stores the enumerator in a hidden variable. When “in” is highlighted, it calls MoveNext(), which upon the first iteration is very convenient because it’s called before Current is referenced. Then, when “var i” is highlighted, it calls Current’s getter method and stores the output in a variable (here inferred to be type Object) called “i”.&lt;br /&gt;&lt;br /&gt;Thanks to Visual Studio 2010’s new Intellitrace feature, we can see this in action:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TAVpMGBoNBI/AAAAAAAAAV0/8lStfjp-9U8/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpMUwAjkI/AAAAAAAAAV4/JKXUK6qUOs8/image_thumb%5B7%5D.png?imgmax=800" border="0" height="276" width="371" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The blue arrows indicate code that has been automatically stepped over, and you can see at each stop point (indicated by red Stop-button icons) that the functions mentioned above are called. Furthermore, when we go another iteration through, we see the following:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/TAVpM9FZ2SI/AAAAAAAAAV8/pAuRaYDH2uk/s1600-h/image%5B22%5D.png"&gt;&lt;img style="border-width: 0px; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/TAVpNFfHbMI/AAAAAAAAAWA/DTZNo2ndALI/image_thumb%5B10%5D.png?imgmax=800" border="0" height="260" width="336" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We see the first call to Console.WriteLine() in the body of our foreach loop, and then MoveNext() is called again followed by Current. This will continue ad nauseum until MoveNext() returns false and giving us an escape from our iteration. If MoveNext() never returns false, the iteration could continue infinitely, or until an exception is thrown.&lt;br /&gt;&lt;br /&gt;Also of note is on our second iteration, “old” is not highlighted. This is because we no longer need a new enumerator, since we already have one. So first “in” is highlighted (MoveNext) followed by “var i” (setting the value of Current to “i”).&lt;br /&gt;&lt;br /&gt;At the beginning of this post, I mentioned a question I might ask to a candidate: what pattern does this represent under the hood? While it’s not the most straight-forward question (or the most straight-forward answer), it’s an interesting question to ask because it gets the candidate to think. The answer is a “state machine” pattern, where the object operates based on its state, which may be constantly changing, but the state is persisted in the object for a given period of time (such as the object’s lifespan). The “Current” value of x is our state (which could be the current index of an array, for example), and MoveNext() alters our state.&lt;br /&gt;&lt;br /&gt;Now let’s look at the generic version of IEnumerable, IEnumerable&amp;lt;T&amp;gt;. It also has a generic enumerator counterpart, IEnumerator&amp;lt;T&amp;gt;. Interestingly enough, the namespaces that contain the generic versions are imported by default with a new project in Visual Studio 2010 / .NET 4, while the IEnumerable/IEnumerator non-generic versions are in a namespace that is not imported by default, System.Collections. I take this to mean that Microsoft is encouraging the adoption of the generic, type-safe versions of them instead of the non-generic versions. In our example, we get for free the added benefit of type inference as well as we no longer need to box the Int32 variable when we return it in the Current getter, probably resulting in better performance due to less IL being generated.&lt;br /&gt;&lt;br /&gt;Like IEnumerable, we have GetEnumerator() in IEnumerable&amp;lt;T&amp;gt;. However, it now has an overload, one which returns IEnumerator&amp;lt;T&amp;gt;, the other which returns IEnumerator. The reason for this is simpler than it may appear on the surface -- IEnumerable&amp;lt;T&amp;gt; inherits from IEnumerable for compatibility reasons. You can safely cast an IEnumerable&amp;lt;T&amp;gt; type to IEnumerable for use with legacy code. However, with value types such as our example, you’ll end up adding boxing as well.&lt;br /&gt;&lt;br /&gt;Here’s our IEnumerable&amp;lt;T&amp;gt; implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class NewEnumerable : IEnumerable&amp;lt;int&amp;gt;&lt;br /&gt;{&lt;br /&gt;    public IEnumerator&amp;lt;int&amp;gt; GetEnumerator()&lt;br /&gt;    {&lt;br /&gt;        return new NewEnumerator();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    IEnumerator IEnumerable.GetEnumerator()&lt;br /&gt;    {&lt;br /&gt;        return new NewEnumerator();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;As you can see, we have the new, generic GetEnumerator as well as the old, non-generic one. In both cases we’re returning a new instance of the NewEnumerator() class, since it inherits from IEnumerator&amp;lt;T&amp;gt; as well as IEnumerator, making it a safe implicit cast for both. Here’s our IEnumerator&amp;lt;T&amp;gt; implementation:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public class NewEnumerator : IEnumerator&amp;lt;int&amp;gt;&lt;br /&gt;{&lt;br /&gt;    int x = 0;&lt;br /&gt;&lt;br /&gt;    public int Current&lt;br /&gt;    {&lt;br /&gt;        get { return x; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Dispose()&lt;br /&gt;    {&lt;br /&gt;        // do nothing&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    object IEnumerator.Current&lt;br /&gt;    {&lt;br /&gt;        get { return x; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public bool MoveNext()&lt;br /&gt;    {&lt;br /&gt;        return x++ &amp;lt; 100;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void Reset()&lt;br /&gt;    {&lt;br /&gt;        x = 0;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Note that IEnumerator&amp;lt;T&amp;gt; not only inherits from IEnumerator but also IDisposable as well, meaning you can use any IEnumerator&amp;lt;T&amp;gt; inside a “using” block if you wish. Hence, we now have a Dispose method along for the ride. In our implementation, we don’t have any unmanaged resources we need to dispose of, so we do nothing.&lt;br /&gt;&lt;br /&gt;We also now have two Current properties – one returns T (in this case, int), the other returns object. When working with the generic version, we’ll be using the T version of Current, and when working this enumerator as IEnumerator, we’ll be using the object version of Current. Since IEnumerator&amp;lt;T&amp;gt; only defines Current, we inherit MoveNext() and Reset() from IEnumerator, and so there’s no change there. Also, here you can see that since Current is now generic and returns int, there is no longer a need to box “x” to an object to return it.&lt;br /&gt;&lt;br /&gt;We can now use the NewEnumerator class in exactly the same way as OldEnumerator, but now we don’t need to cast the value to use it as an int. (If we wanted to – we didn’t need to in the previous example as we were only implicitly using ToString() on System.Object.)&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;var newenum = new NewEnumerable();&lt;br /&gt;&lt;br /&gt;foreach (int i in newenum)&lt;br /&gt;    Console.WriteLine(i);&lt;br /&gt;&lt;br /&gt;Console.ReadKey();&lt;/pre&gt;&lt;br /&gt;So that’s all well and good. Now, how do we use the “yield” keyword, and why did I tie it in with a post on IEnumerable&amp;lt;T&amp;gt;?&lt;br /&gt;&lt;br /&gt;Because &lt;em&gt;it builds for you an automatic IEnumerator&amp;lt;T&amp;gt;.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;That’s pretty much all it does. That – and it maintains the state of the code around it until the next iteration. This may not be the best explanation of the “yield” keyword, but I think it fits.&lt;br /&gt;&lt;br /&gt;Here’s a handy extension method to make your code feel more fun and expressive (or confusing and hard-to-maintain, depending on if you’re an optimist or a pessimist).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public static IEnumerable&amp;lt;int&amp;gt; To(this int value, int inclusiveMax)&lt;br /&gt;{&lt;br /&gt;    for (int i = value; i &amp;lt;= inclusiveMax; i++)&lt;br /&gt;        yield return i;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;This extension method, when placed in a static class in your project will allow you to this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;var ten = 1.To(10);&lt;br /&gt;&lt;br /&gt;foreach (var i in ten)&lt;br /&gt;    Console.WriteLine(i);&lt;/pre&gt;&lt;br /&gt;Since 1 is an int, it gets the extension method To() which returns an IEnumerable&amp;lt;int&amp;gt;. Notice that we have not created a class that inherits from IEnumerable&amp;lt;int&amp;gt;, nor a class that inherits from IEnumerator&amp;lt;int&amp;gt;. The C# compiler does this for us automatically with an anonymous, compiler-generated type. We can pull it up in &lt;a href="http://www.red-gate.com/products/reflector/" target="_blank"&gt;Reflector&lt;/a&gt; and see this type:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/TAVpNRJBy8I/AAAAAAAAAWE/WHztmnM0uyM/s1600-h/image%5B26%5D.png"&gt;&lt;img style="border: 0px none; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpNo1LibI/AAAAAAAAAWI/qoLse2xIGP4/image_thumb%5B12%5D.png?imgmax=800" border="0" height="478" width="543" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that the method starts with &amp;lt;To&amp;gt; – that’s the name of the method that uses this enumerator. Also notice the d__0 identifier – that’s how the .NET runtime knows how to access this compiler-generated type. And finally, notice that it inherits from both IEnumerable&amp;lt;T&amp;gt; and IEnumerator&amp;lt;T&amp;gt;, making it both an enumerable and enumerator at the same time. Our previous examples could have done this, but I separated them out for clarity. If you wanted to do this in the previous examples, just have GetEnumerator() return “this”.&lt;br /&gt;&lt;br /&gt;There’s a bunch of thread-safe code going on underneath those method signatures, so try it on your own to see what’s happening – I’ll spare the details here.&lt;br /&gt;&lt;br /&gt;Nonetheless, the code does what you would expect – it prints 1 through 10 and stops. As you can see, the yield keyword can save you a ton of code. Here’s another extension method to multiply each element so you can better see the benefits of yield:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;public static IEnumerable&amp;lt;int&amp;gt; Multiply(this IEnumerable&amp;lt;int&amp;gt; value, int multiplier)&lt;br /&gt;{&lt;br /&gt;    foreach (int v in value)&lt;br /&gt;        yield return v * multiplier;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Now we can use the two together like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;var dbl = 1.To(10).Multiply(2);&lt;br /&gt;&lt;br /&gt;foreach (var i in dbl)&lt;br /&gt;    Console.WriteLine(i);&lt;/pre&gt;&lt;br /&gt;I hope this helps your understanding of IEnumerable, IEnumerable&amp;lt;T&amp;gt;, IEnumerator, IEnumerator&amp;lt;T&amp;gt;, and the “yield” keyword.&lt;br /&gt;&lt;br /&gt;Aside: Sadly the “yield” keyword has no equivalent in VB. It’s a feature that’s been sorely missing, and is still missing in .NET 4.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; I realized that in the IDisposable.Dispose() method in the above examples, it should be calling Reset(). The reason for this is that many times IEnumerator&amp;lt;T&amp;gt; is used in a "using" block such that once it is disposed, it should be reset.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-8572763756655870622?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yhUBVXmlITip2MLFxM9ZaGGTjlc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yhUBVXmlITip2MLFxM9ZaGGTjlc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yhUBVXmlITip2MLFxM9ZaGGTjlc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yhUBVXmlITip2MLFxM9ZaGGTjlc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/8572763756655870622/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=8572763756655870622" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8572763756655870622?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8572763756655870622?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2010/06/understanding-cs-yield-keyword-and.html" title="Understanding C#’s “yield” Keyword and IEnumerable&amp;lt;T&amp;gt;" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_xvXvGivrKF0/TAVpJuuvDzI/AAAAAAAAAVY/1PTtyv346wo/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkANQnw6eyp7ImA9WxNVEUs.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-2337315334862989511</id><published>2009-10-21T18:36:00.002-04:00</published><updated>2009-10-21T18:39:53.213-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-21T18:39:53.213-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="VS2010" /><title>VS2010: A First Look at Beta 2 for ASP.NET – Part 1</title><content type="html">&lt;p&gt;If you haven’t yet downloaded Visual Studio 2010 Beta 2, &lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;what are you waiting for?&lt;/a&gt; Until then, here’s a first look at what’s new for ASP.NET developers with .NET 4 and Visual Studio 2010.&lt;/p&gt;  &lt;h2&gt;Visual Changes&lt;/h2&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/St-MwRbi2wI/AAAAAAAAAT4/inI9GhnJFaU/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/St-MxOT2DII/AAAAAAAAAUA/6o6evUWZKTE/image_thumb%5B2%5D.png?imgmax=800" border="0" height="393" width="538" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;First off, there’s a new splash screen and icon! I know, I know, this really isn’t important for day-to-day use. But I feel it reflects Microsoft’s renewed commitment to great user experience. Personally, I absolutely love it. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/St-MxYhPcCI/AAAAAAAAAUE/ixsNB496EHM/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/St-Mxs4SSAI/AAAAAAAAAUI/8JhkWKrbqjI/image_thumb%5B3%5D.png?imgmax=800" border="0" height="43" width="71" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is the new icon that shows up in the taskbar.&lt;/p&gt;  &lt;p&gt; &lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/St-MyCeqqaI/AAAAAAAAAUM/mc0p1g1EWm0/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/St-MyUWxk8I/AAAAAAAAAUQ/obgP4YbNj4M/image_thumb%5B5%5D.png?imgmax=800" border="0" height="452" width="538" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Also there’s a new theme for the overall UI. A bit darker, and 100% more awesome. Even the menus are in WPF, so it feels more “2010” and less “2003”.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;New ASP.NET Default Template&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/St-MynQlTzI/AAAAAAAAAUU/JBDI0Dbm1LQ/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/St-Myk_9NMI/AAAAAAAAAUY/rmM8wZkWtCE/image_thumb%5B8%5D.png?imgmax=800" border="0" height="317" width="536" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;When you do File –&amp;gt; New Project and choose the ASP.NET Web Application project template, you now get a much more robust project template by default for new web forms projects, complete with authentication, much like the default ASP.NET MVC project template.&lt;/p&gt;  &lt;h2&gt;Snippets for ASPX Markup&lt;/h2&gt;  &lt;p&gt; &lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/St-My-_BOFI/AAAAAAAAAUc/rNXT4sBgi9w/s1600-h/image%5B26%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/St-MzOZhvLI/AAAAAAAAAUg/3YqzDJxm9xE/image_thumb%5B12%5D.png?imgmax=800" border="0" height="101" width="306" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The awesome snippets that make coding in C# and VB more fun have made their way to ASPX markup. Start typing “&amp;lt;button” and press tab twice to get a button snippet like this. One annoying issue I’ve noticed is that trying to type a normal &amp;lt;a&amp;gt; tag is painful, because it tries to put in an &amp;lt;accessdatasource&amp;gt; snippet instead. Hopefully this will be resolved by the next Beta/RC.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Client ID Mode&lt;/h2&gt;  &lt;p&gt;There is a new ClientIDMode attribute that can be applied to most server controls that changes the output ID to make it more JavaScript and CSS friendly. Given the following ASPX code:&lt;/p&gt;  &lt;pre class="brush: xml;"&gt;&amp;lt;asp:Panel ID="pnlContent" runat="server" ClientIDMode="Static"&amp;gt;&lt;br /&gt;  This is some content&lt;br /&gt;&amp;lt;/asp:Panel&amp;gt;&lt;/pre&gt;The following HTML is outputted:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;div id="pnlContent"&amp;gt;&lt;br /&gt;  This is some content  &lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;As compared to the following HTML output without ClientIDMode=”Static”:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;div id="MainContent_pnlContent"&amp;gt;&lt;br /&gt;  This is some content&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;/pre&gt;Which, as you know, if that pnlContent panel was nested 5 layers deep in controls, you would see each of those layers’ IDs present in its ID. This makes the IDs of the elements predictable for use in JavaScript and CSS.&lt;br /&gt;&lt;h2&gt;HTML Encoding Block Syntax&lt;/h2&gt;Especially when dealing with ASP.NET MVC, but also with WebForms, you end up needing to HTML encode output when using the ASP-style blocks. With the following code-behind:&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  FooterContent = "Hello &amp;lt;World&amp;gt; !";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public string FooterContent { get; set; }&lt;/pre&gt;And the following ASPX page:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;%= FooterContent %&amp;gt;&lt;/pre&gt;We get the following output:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/St-MzH89hVI/AAAAAAAAAUk/ydBiUemiXSk/s1600-h/image%5B29%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/St-MzVa8ZkI/AAAAAAAAAUo/JmoKnXzvYXY/image_thumb%5B13%5D.png?imgmax=800" border="0" height="91" width="187" /&gt;&lt;/a&gt; &lt;/p&gt;But if we wanted to HTML encode that output, we previously would need to do this:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;%= Server.HtmlEncode(FooterContent) %&amp;gt;&lt;/pre&gt;Now, we can use a new block syntax to do the same, without the function call:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;&amp;lt;%: FooterContent %&amp;gt;&lt;/pre&gt;And now we get properly escaped HTML output:&lt;br /&gt;&lt;pre class="brush: xml;"&gt;Hello &amp;amp;lt;World&amp;amp;gt; !&lt;/pre&gt;&lt;span style="font-family:Georgia;"&gt;Which shows up properly in our browser as we would expect:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/St-Mzl3zg5I/AAAAAAAAAUs/13OA0Xo55Qc/s1600-h/image%5B32%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/St-M0NYl24I/AAAAAAAAAUw/yVkHaIityxU/image_thumb%5B14%5D.png?imgmax=800" border="0" height="85" width="161" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-2337315334862989511?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f-7pj7YXkoHDJtiIRGdcTnVcw_c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f-7pj7YXkoHDJtiIRGdcTnVcw_c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f-7pj7YXkoHDJtiIRGdcTnVcw_c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f-7pj7YXkoHDJtiIRGdcTnVcw_c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/2337315334862989511/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=2337315334862989511" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/2337315334862989511?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/2337315334862989511?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/10/vs2010-first-look-at-beta-2-for-aspnet.html" title="VS2010: A First Look at Beta 2 for ASP.NET – Part 1" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_xvXvGivrKF0/St-MxOT2DII/AAAAAAAAAUA/6o6evUWZKTE/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0INQnY7eip7ImA9WxNXFE0.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-6295539124135623707</id><published>2009-09-30T18:30:00.002-04:00</published><updated>2009-10-01T08:53:13.802-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T08:53:13.802-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dependency injection" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="ninject" /><title>Creating Your Own IoC Container: Part 2</title><content type="html">&lt;p&gt;In the &lt;a href="http://adventuresdotnet.blogspot.com/2009/09/creating-your-own-ioc-container.html"&gt;first part&lt;/a&gt; of this post series (which, honestly, I didn’t intend to need a Part 2), I discussed how you can easily create your own container for basic inversion of control (IoC) needs. However, many people may need to use Dependency Injection (DI) as well, so I’ve modified the project to support DI.&lt;/p&gt;  &lt;p&gt;Also, a colleague pointed out that there’s another reason why you may want to do this – to simply see how it all works. Sure, you can plop Ninject into a project and start using DI/IoC, but creating your own makes you realize what’s really involved and going on behind-the-scenes.&lt;/p&gt;  &lt;p&gt;Here I’ve modified the previous example to support DI, and it took less than an hour. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; I have only briefly tested this code, and have not created unit tests. Before using in production, I’d recommend testing it thoroughly. You’ll also need to get the previous post working on your end before integrating these features. I also noticed a bug after publishing this post reading through the code that if you request an IFoo, and Foo : IFoo has a constructor that is asking for an IFoo parameter, you'll end up in an endless loop and probably stack overflow. Ideally this should detect a circular Resolve() call, and throw an exception.&lt;br /&gt;&lt;/p&gt;  &lt;h2&gt;The IServiceResolver Interface&lt;/h2&gt;  &lt;p&gt;This bit is not required, however I realized as I was writing the DependencyInjector class below that I was tightly coupling it with ServiceResolver from the previous post. Since this is very much an anti-pattern, I decided to make ServiceResolver implement an interface, so that you can use your own IServiceResolver implementation with this DependencyInjector class. Here’s the interface:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace Core&lt;br /&gt;{&lt;br /&gt;   public interface IServiceResolver&lt;br /&gt;   {&lt;br /&gt;       void Register&amp;lt;TFrom, TTo&amp;gt;();&lt;br /&gt;       T Resolve&amp;lt;T&amp;gt;();&lt;br /&gt;       object Resolve(Type fromType);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Notice that I’ve added a non-generic version of this class. This was done for compatibility, and now the ServiceResolver class looks like the following. The major changes are it now implements the IServiceResolver interface, and there is the new non-generic method which is called by the generic method. Also, it does not throw an exception if there has not been a registration for the given type. Instead, it creates a new object and looks for any injections. This is to remove the need to bind items to themselves. Note that there is still a tight coupling in the default constructor to DependencyInjector. You may wish to remove this. &lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace Core&lt;br /&gt;{&lt;br /&gt;   /// &amp;lt;summary&amp;gt;&lt;br /&gt;   /// Resolves abstract types or interfaces to concrete implementations. Use &amp;lt;see cref="ServiceLocator" /&amp;gt; for static/shared access.&lt;br /&gt;   /// &amp;lt;/summary&amp;gt;&lt;br /&gt;   public class ServiceResolver : IServiceResolver&lt;br /&gt;   {&lt;br /&gt;       private Dictionary&amp;lt;Type, object&amp;gt; _store;&lt;br /&gt;       private Dictionary&amp;lt;Type, Type&amp;gt; _bindings;&lt;br /&gt;      &lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Default constructor; instantiates a new ServiceResolver object.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       public ServiceResolver()&lt;br /&gt;       {&lt;br /&gt;           this.DependencyInjector = new DependencyInjector(this);&lt;br /&gt;           _store = new Dictionary&amp;lt;Type, object&amp;gt;();&lt;br /&gt;           _bindings = new Dictionary&amp;lt;Type, Type&amp;gt;();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Creates a new ServiceResolver with a given IDependencyInjector.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="injector"&amp;gt;The IDependencyInjector to use for dependency injection.&amp;lt;/param&amp;gt;&lt;br /&gt;       public ServiceResolver(IDependencyInjector injector)&lt;br /&gt;       {&lt;br /&gt;           this.DependencyInjector = injector;&lt;br /&gt;           _store = new Dictionary&amp;lt;Type, object&amp;gt;();&lt;br /&gt;           _bindings = new Dictionary&amp;lt;Type, Type&amp;gt;();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an implementation object of a registered abstract type or interface.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;typeparam name="T"&amp;gt;The registered abstract type or interface to look up.&amp;lt;/typeparam&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns an object of the given type.&amp;lt;/returns&amp;gt;&lt;br /&gt;       public T Resolve&amp;lt;T&amp;gt;()&lt;br /&gt;       {&lt;br /&gt;           return (T)Resolve(typeof(T));&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an implementation object of a registered abstract type or interface.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="fromType"&amp;gt;The registered abstract type or interface to look up.&amp;lt;/param&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns an object of the given type.&amp;lt;/returns&amp;gt;&lt;br /&gt;       public object Resolve(Type fromType)&lt;br /&gt;       {&lt;br /&gt;           // check for registration&lt;br /&gt;           if (!_bindings.ContainsKey(fromType))&lt;br /&gt;               return DependencyInjector.GetInjectedInstance(fromType);&lt;br /&gt;              &lt;br /&gt;           // get destination type&lt;br /&gt;           Type dest = _bindings[fromType];&lt;br /&gt;&lt;br /&gt;           // check for already requested object&lt;br /&gt;           if (_store.ContainsKey(dest))&lt;br /&gt;               return _store[dest];&lt;br /&gt;&lt;br /&gt;           // create a new instance of this type&lt;br /&gt;           object obj = DependencyInjector.GetInjectedInstance(dest);&lt;br /&gt;&lt;br /&gt;           // add to store for future use&lt;br /&gt;           _store.Add(dest, obj);&lt;br /&gt;&lt;br /&gt;           return obj;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Registers a type with its corresponding implementation type.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;typeparam name="TFrom"&amp;gt;The abstract type or interface to use as a key.&amp;lt;/typeparam&amp;gt;&lt;br /&gt;       /// &amp;lt;typeparam name="TTo"&amp;gt;The implementation type to use as a value.&amp;lt;/typeparam&amp;gt;&lt;br /&gt;       public void Register&amp;lt;TFrom, TTo&amp;gt;()&lt;br /&gt;       {&lt;br /&gt;           _bindings.Add(typeof(TFrom), typeof(TTo));&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets or sets a dependency injector to use for types that need injection.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       public IDependencyInjector DependencyInjector { get; set; }&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The InjectAttribute class&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In order to tell our DependencyInjector class that we want to inject something, we need to decorate either a constructor or some properties (or both) with an [Inject] attribute. If you’ve never created your own attributes, all you have to do is create a new class with a name that ends in Attribute (the “Attribute” bit is cut off on use) and make it inherit from Attribute. Here’s our empty InjectAttribute class:&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;&lt;br /&gt;namespace Core&lt;br /&gt;{&lt;br /&gt;   [AttributeUsage(AttributeTargets.Property | AttributeTargets.Constructor)]&lt;br /&gt;   public class InjectAttribute : Attribute&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;the IDependencyInjector Interface&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Since we want to make our DependencyInjector loosely coupled with any use of it, we want to make it implement an interface.&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace Core&lt;br /&gt;{&lt;br /&gt;   public interface IDependencyInjector&lt;br /&gt;   {&lt;br /&gt;       T GetInjectedInstance&amp;lt;T&amp;gt;() where T : class;&lt;br /&gt;       object GetInjectedInstance(Type fromType);&lt;br /&gt;       IServiceResolver ServiceResolver { get; set; }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;The DependencyInjector Class&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Now that we have all of the plumbing out of the way, we can show off our new DependencyInjector class.&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Reflection;&lt;br /&gt;&lt;br /&gt;namespace Core&lt;br /&gt;{&lt;br /&gt;   /// &amp;lt;summary&amp;gt;&lt;br /&gt;   /// A class for getting instances of objects that need dependencies injected to function.&lt;br /&gt;   /// &amp;lt;/summary&amp;gt;&lt;br /&gt;   public class DependencyInjector : IDependencyInjector&lt;br /&gt;   {&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Creates a new DependencyInjector with a default IServiceResolver for resolving types.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       public DependencyInjector() : this(new ServiceResolver())&lt;br /&gt;       { }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Creates a new DependencyInjector with a given IServiceResolver for resolving types.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="resolver"&amp;gt;The IServiceResolver to use for resolving types to implementations.&amp;lt;/param&amp;gt;&lt;br /&gt;       public DependencyInjector(IServiceResolver resolver)&lt;br /&gt;       {&lt;br /&gt;           this.ServiceResolver = resolver;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets or sets an IServiceResolver to use for resolving types to implementations.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       public IServiceResolver ServiceResolver { get; set; }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an injected instance of a given type.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;typeparam name="T"&amp;gt;The type to instantiate and inject.&amp;lt;/typeparam&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns a new instance of the given type.&amp;lt;/returns&amp;gt;&lt;br /&gt;       public virtual T GetInjectedInstance&amp;lt;T&amp;gt;() where T : class&lt;br /&gt;       {&lt;br /&gt;           return (T)GetInjectedInstance(typeof(T));&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an injected instance of a given type.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="fromType"&amp;gt;The type to instantiate and inject.&amp;lt;/param&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns a new instance of the given type.&amp;lt;/returns&amp;gt;&lt;br /&gt;       public virtual object GetInjectedInstance(Type fromType)&lt;br /&gt;       {&lt;br /&gt;           object obj = null;&lt;br /&gt;&lt;br /&gt;           foreach (var constructor in fromType.GetConstructors())&lt;br /&gt;           {&lt;br /&gt;               // look for inject attribute&lt;br /&gt;               var attr = GetConstructorInjectAttribute(constructor);&lt;br /&gt;&lt;br /&gt;               if (attr != null)&lt;br /&gt;               {&lt;br /&gt;                   // get parameters to inject&lt;br /&gt;                   var parmValues = GetResolvedParameterValues(constructor);&lt;br /&gt;&lt;br /&gt;                   if (parmValues.Count &amp;gt; 0)&lt;br /&gt;                       obj = Activator.CreateInstance(fromType, parmValues.ToArray());&lt;br /&gt;&lt;br /&gt;                   break;&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           // handle case where no constructor injections&lt;br /&gt;           if (obj == null)&lt;br /&gt;               obj = Activator.CreateInstance(fromType);&lt;br /&gt;&lt;br /&gt;           foreach (var prop in fromType.GetProperties())&lt;br /&gt;           {&lt;br /&gt;               // look for inject attribute&lt;br /&gt;               var attr = GetPropertyInjectAttribute(prop);&lt;br /&gt;&lt;br /&gt;               if (attr != null)&lt;br /&gt;                   prop.SetValue(obj, ServiceResolver.Resolve(prop.PropertyType), new object[] { });&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           return obj;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an InjectAttribute (if any) for the given constructor.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="constructor"&amp;gt;The constructor to inspect for an InjectAttribute.&amp;lt;/param&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns an InjectAttribute if exists, or null if not.&amp;lt;/returns&amp;gt;&lt;br /&gt;       protected virtual InjectAttribute GetConstructorInjectAttribute(ConstructorInfo constructor)&lt;br /&gt;       {&lt;br /&gt;           var attrs = constructor.GetCustomAttributes(typeof(InjectAttribute), true);&lt;br /&gt;           return attrs.OfType&amp;lt;InjectAttribute&amp;gt;().FirstOrDefault();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets an InjectAttribute (if any) for the given property.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="prop"&amp;gt;The property to inspect for an InjectAttribute.&amp;lt;/param&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns an InjectAttribute if exists, or null if not.&amp;lt;/returns&amp;gt;&lt;br /&gt;       protected virtual InjectAttribute GetPropertyInjectAttribute(PropertyInfo prop)&lt;br /&gt;       {&lt;br /&gt;           var attrs = prop.GetCustomAttributes(typeof(InjectAttribute), true);&lt;br /&gt;           return attrs.OfType&amp;lt;InjectAttribute&amp;gt;().FirstOrDefault();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       /// &amp;lt;summary&amp;gt;&lt;br /&gt;       /// Gets a list of parameter values for the given constructor, resolved by the ServiceResolver.&lt;br /&gt;       /// &amp;lt;/summary&amp;gt;&lt;br /&gt;       /// &amp;lt;param name="constructor"&amp;gt;The constructor to resolve parameters for.&amp;lt;/param&amp;gt;&lt;br /&gt;       /// &amp;lt;returns&amp;gt;Returns a new list of parameter values.&amp;lt;/returns&amp;gt;&lt;br /&gt;       protected virtual List&amp;lt;object&amp;gt; GetResolvedParameterValues(ConstructorInfo constructor)&lt;br /&gt;       {&lt;br /&gt;           var parms = constructor.GetParameters();&lt;br /&gt;           List&amp;lt;object&amp;gt; parmValues = new List&amp;lt;object&amp;gt;();&lt;br /&gt;&lt;br /&gt;           foreach (var parm in parms)&lt;br /&gt;           {&lt;br /&gt;               if (parm.ParameterType.IsInterface || parm.ParameterType.IsAbstract)&lt;br /&gt;               {&lt;br /&gt;                   Type parmType = parm.ParameterType;&lt;br /&gt;                   object parmValue = ServiceResolver.Resolve(parmType);&lt;br /&gt;                   parmValues.Add(parmValue);&lt;br /&gt;               }&lt;br /&gt;               else&lt;br /&gt;                   throw new InvalidOperationException("Unable to inject a parameter that is not an interface or abstract type.");&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           return parmValues;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I’m not going to cover line-by-line what this class does, but basically it looks for any InjectAttributes decorating a constructor or properties, and if it finds them, it resolves instances automatically using the ServiceLocator (another tight coupling) and fills them in.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Usage&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Back in our ASP.NET MVC test app, we have created a new interface to use for testing, ILogger. It has one implementation (but could have many), and this one is WebLogger which writes out the log message to the current HttpResponse.&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;&lt;br /&gt;namespace CustomIoCMvc.Models&lt;br /&gt;{&lt;br /&gt;   public interface ILogger&lt;br /&gt;   {&lt;br /&gt;       void Log(string message);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And here’s our WebLogger:&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Web;&lt;br /&gt;&lt;br /&gt;namespace CustomIoCMvc.Models&lt;br /&gt;{&lt;br /&gt;   public class WebLogger : ILogger&lt;br /&gt;   {&lt;br /&gt;       public void Log(string message)&lt;br /&gt;       {&lt;br /&gt;           HttpContext.Current.Response.Write(message);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;We, of course, need to wire up this implementation in our Global.asax.cs:&lt;/span&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;protected void Application_Start()&lt;br /&gt;{&lt;br /&gt;   RegisterRoutes(RouteTable.Routes);&lt;br /&gt;  &lt;br /&gt;   // register types&lt;br /&gt;   ServiceLocator.Register&amp;lt;ICustomerRepository, CustomerRepository&amp;gt;();&lt;br /&gt;   ServiceLocator.Register&amp;lt;ILogger, WebLogger&amp;gt;();&lt;br /&gt;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Our CustomerRepository is going to now use an ILogger for all of its calls. Here it is with a Constructor injection:&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Configuration;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Web;&lt;br /&gt;using System.Web.Security;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;using System.Web.UI.HtmlControls;&lt;br /&gt;using System.Web.UI.WebControls;&lt;br /&gt;using System.Web.UI.WebControls.WebParts;&lt;br /&gt;using System.Xml.Linq;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using Core;&lt;br /&gt;&lt;br /&gt;namespace CustomIoCMvc.Models&lt;br /&gt;{&lt;br /&gt;   public class CustomerRepository : ICustomerRepository&lt;br /&gt;   {&lt;br /&gt;       [Inject]&lt;br /&gt;       public CustomerRepository(ILogger logger)&lt;br /&gt;       {&lt;br /&gt;           this.Logger = logger;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       public Customer Find(int id)&lt;br /&gt;       {&lt;br /&gt;           Logger.Log("Find called with param value " + id.ToString());&lt;br /&gt;           return FindAll().Where(c =&amp;gt; c.Id == id).FirstOrDefault();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       public List&amp;lt;Customer&amp;gt; FindAll()&lt;br /&gt;       {&lt;br /&gt;           Logger.Log("FindAll called.");&lt;br /&gt;           var data = new List&amp;lt;Customer&amp;gt;();&lt;br /&gt;           data.Add(new Customer() { Id = 1, Name = "Joe" });&lt;br /&gt;           data.Add(new Customer() { Id = 2, Name = "Steve" });&lt;br /&gt;           data.Add(new Customer() { Id = 3, Name = "Karen" });&lt;br /&gt;           return data;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       public ILogger Logger { get; set; }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;And here’s our CustomerRepository with Property injection:&lt;/p&gt;&lt;br /&gt;&lt;pre class="brush: csharp;"&gt;using System;&lt;br /&gt;using System.Data;&lt;br /&gt;using System.Configuration;&lt;br /&gt;using System.Linq;&lt;br /&gt;using System.Web;&lt;br /&gt;using System.Web.Security;&lt;br /&gt;using System.Web.UI;&lt;br /&gt;using System.Web.UI.HtmlControls;&lt;br /&gt;using System.Web.UI.WebControls;&lt;br /&gt;using System.Web.UI.WebControls.WebParts;&lt;br /&gt;using System.Xml.Linq;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using Core;&lt;br /&gt;&lt;br /&gt;namespace CustomIoCMvc.Models&lt;br /&gt;{&lt;br /&gt;   public class CustomerRepository : ICustomerRepository&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;       public Customer Find(int id)&lt;br /&gt;       {&lt;br /&gt;           Logger.Log("Find called with param value " + id.ToString());&lt;br /&gt;           return FindAll().Where(c =&amp;gt; c.Id == id).FirstOrDefault();&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       public List&amp;lt;Customer&amp;gt; FindAll()&lt;br /&gt;       {&lt;br /&gt;           Logger.Log("FindAll called.");&lt;br /&gt;           var data = new List&amp;lt;Customer&amp;gt;();&lt;br /&gt;           data.Add(new Customer() { Id = 1, Name = "Joe" });&lt;br /&gt;           data.Add(new Customer() { Id = 2, Name = "Steve" });&lt;br /&gt;           data.Add(new Customer() { Id = 3, Name = "Karen" });&lt;br /&gt;           return data;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       [Inject]&lt;br /&gt;       public ILogger Logger { get; set; }&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Both have been tested with the same result. But first, a little background about what’s going on here.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Our CustomersController is requesting from the service locator an instance of ICustomerRepository. It finds that we’ve bound ICustomerRepository to CustomerRepository, and goes to instantiate that class. What we’ve modified our code to do is to look, before we instantiate, if there’s a constructor with an [Inject] attribute. If there is, we fill in the constructor parameters with the needed types. If not, we go ahead and create the object with the default constructor.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Next, after we’ve instantiated the object, it looks for any properties with an [Inject] attribute, and does the same. Finally, it returns the object.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Therefore, in this case, our DependencyInjector is getting a request for a new CustomerRepository, it looks for a constructor with [Inject], sees one (in the first example) and resolves ILogger to the bound WebLogger type, gets an instance of WebLogger, and fills it in to the constructor. In the second example, it uses a default constructor but finds the [Inject] decorated Logger property, resolves ILogger to WebLogger, and sets it.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;So here’s our output. You can’t really see it (because it’s a cheap quick hack), but theres a “FindAll called.” string at the top of the page:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SsPcF5Y7ugI/AAAAAAAAATw/l_ExVJeGFyY/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SsPcGLYlEJI/AAAAAAAAAT0/l0bw6Q_H77I/image_thumb%5B1%5D.png?imgmax=800" border="0" height="282" width="340" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Let me know in the comments if you have any issues or constructive criticism of this code. Hope this helps!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-6295539124135623707?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/aJlcmuTvaaxISVtDuWwL3tVziKY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aJlcmuTvaaxISVtDuWwL3tVziKY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/aJlcmuTvaaxISVtDuWwL3tVziKY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/aJlcmuTvaaxISVtDuWwL3tVziKY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/6295539124135623707/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=6295539124135623707" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/6295539124135623707?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/6295539124135623707?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/09/creating-your-own-ioc-container-part-2.html" title="Creating Your Own IoC Container: Part 2" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_xvXvGivrKF0/SsPcGLYlEJI/AAAAAAAAAT0/l0bw6Q_H77I/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUQNQ307cSp7ImA9WxNQF0g.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-2681770129599488502</id><published>2009-09-23T21:55:00.002-04:00</published><updated>2009-09-23T21:56:32.309-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-23T21:56:32.309-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dependency injection" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><title>Creating Your Own IoC Container</title><content type="html">&lt;p&gt;A few posts ago I covered how to take your &lt;a href="http://adventuresdotnet.blogspot.com/2009/08/first-steps-into-dependency-injection.html"&gt;first steps into Dependency Injection with Ninject&lt;/a&gt;. Continuing on the DI/IoC theme, let’s now look at how you can create your own Inversion of Control (IoC) container.&lt;/p&gt;  &lt;p&gt;Suppose that your organization has very strict limits on what outside software you can use due to licensing, but you still want to do IoC. Or, perhaps you don’t need your IoC container to do very much other than the basics and you don’t want the weight of another full-featured DLL. This is what we will be creating today, with 2 classes: a &lt;strong&gt;ServiceResolver&lt;/strong&gt; and a &lt;strong&gt;ServiceLocator&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;(Aside: For those that feel I’m using the term “Service Locator” inappropriately, please forgive me. For this example that’s the name I came up with.)&lt;/p&gt;  &lt;p&gt;A basic IoC container needs to do the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Register abstract types or interfaces to concrete implementation types &lt;/li&gt;    &lt;li&gt;Resolve abstract types or interfaces to implementation objects &lt;/li&gt;    &lt;li&gt;Keep track of the registered types &lt;/li&gt;    &lt;li&gt;Keep already-resolved objects available for re-use &lt;/li&gt;    &lt;li&gt;Create instances of the implementation types behind-the-scenes &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Our two classes will accomplish that, but only one has most of the logic – the &lt;strong&gt;ServiceResolver&lt;/strong&gt;. The reason for the ServiceLocator class is to provide static methods around the ServiceResolver, and maintain a static instance of the resolver. Since static methods are difficult to test, this allows you to test the functionality of the ServiceResolver class, and trust that the basic wrapper functionality of the ServiceLocator just works.&lt;/p&gt;  &lt;h2&gt;The Light At The End&lt;/h2&gt;  &lt;p&gt;Sometimes it’s fun to see what we’re aiming to do, instead of starting from the beginning, right? Basically we’re going to have a simple ASP.NET MVC site that is going to have a Customers controller. The Index action will ask the service locator for an implementation of ICustomerRepository so that it is loosely coupled. In our Global.asax class, we will register the binding of ICustomerRepository to CustomerRepository. The reason for this is we are pretending that CustomerRepository hits the database, so that for our unit tests we could create a mock repository that does not.&lt;/p&gt;  &lt;p&gt;Our Global.asax.cs file looks like this:&lt;/p&gt;  &lt;div style="padding: 5px; width: 549px; display: block; float: none; margin-left: auto; margin-right: auto;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f3e814e1-f196-430e-8b28-807bd34932bd" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 300px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Application_Start()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             RegisterRoutes(&lt;span style="color: rgb(43, 145, 175);"&gt;RouteTable&lt;/span&gt;.Routes);&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// register types&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceLocator&lt;/span&gt;.Register&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ICustomerRepository&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;CustomerRepository&lt;/span&gt;&amp;gt;();&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p&gt;Note that in a real-world app, you may wish to register types on each page request, not on application start.&lt;/p&gt;  &lt;p&gt;And our Index action looks like this:&lt;/p&gt;  &lt;div style="padding: 5px; width: 549px; display: block; float: none; margin-left: auto; margin-right: auto;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0596177b-ea61-4a2d-8cc4-d1aa1a92162a" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 300px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ActionResult&lt;/span&gt; Index()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; repo = &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceLocator&lt;/span&gt;.Resolve&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;ICustomerRepository&lt;/span&gt;&amp;gt;();&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             ViewData[&lt;span style="color: rgb(163, 21, 21);"&gt;"customers"&lt;/span&gt;] = repo.FindAll();&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; View();&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;h2&gt;The ServiceResolver Class&lt;/h2&gt;  &lt;p&gt;Let’s look at the ServiceResolver class that does all the heavy lifting (although there really isn’t much).&lt;/p&gt;  &lt;p&gt;   &lt;/p&gt;&lt;div style="padding: 5px; width: 549px; display: block; float: none; margin-left: auto; margin-right: auto;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7f137dd7-854b-4cee-b3a3-07370b6d1a7a" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 500px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/li&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Linq;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Text;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;namespace&lt;/span&gt; Core&lt;/li&gt;&lt;li&gt; {&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Resolves abstract types or interfaces to concrete implementations. Use &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;see cref="ServiceLocator" /&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; for static/shared access.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceResolver&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     {&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt; _store;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;&amp;gt; _bindings;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Default constructor; instantiates a new ServiceResolver object.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ServiceResolver()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             _store = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&amp;gt;();&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             _bindings = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;, &lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt;&amp;gt;();&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets an implementation object of a registered abstract type or interface.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="T"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The registered abstract type or interface to look up.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;Returns an object of the given type.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; T Resolve&amp;lt;T&amp;gt;()&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// check for registration&lt;/span&gt;&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!_bindings.ContainsKey(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(T)))&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;                 &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;InvalidOperationException&lt;/span&gt;(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;.Format(&lt;span style="color: rgb(163, 21, 21);"&gt;"Requested type {0} has not been registered."&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(T).ToString()));&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// get destination type&lt;/span&gt;&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(43, 145, 175);"&gt;Type&lt;/span&gt; dest = _bindings[&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(T)];&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// check for already requested object&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (_store.ContainsKey(dest))&lt;/li&gt;&lt;li&gt;                 &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; (T)_store[dest];&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// create a new instance of this type&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             T obj = (T)&lt;span style="color: rgb(43, 145, 175);"&gt;Activator&lt;/span&gt;.CreateInstance(dest);&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 128, 0);"&gt;// add to store for future use&lt;/span&gt;&lt;/li&gt;&lt;li&gt;             _store.Add(dest, obj);&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; obj;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Registers a type with its corresponding implementation type.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="TFrom"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The abstract type or interface to use as a key.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="TTo"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The implementation type to use as a value.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Register&amp;lt;TFrom, TTo&amp;gt;()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             _bindings.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(TFrom), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(TTo));&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     }&lt;/li&gt;&lt;li&gt; }&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt;  &lt;p&gt;First, notice the _store and _bindings members. Those are our ways of keeping track of registered types (_bindings) and reusable already-resolved objects (_store). &lt;/p&gt;  &lt;p&gt;The Register&amp;lt;TFrom, TTo&amp;gt;() method adds to the _bindings dictionary the “from” and “to” types to use later, whenever Resolve&amp;lt;T&amp;gt;() is called. Since we’re just storing types in the dictionary, there is little overhead and it’s okay to register all our types in advance.&lt;/p&gt;  &lt;p&gt;Finally, the Resolve&amp;lt;T&amp;gt;() method looks for a pre-registered type binding, and throws an error if it doesn’t find one. Then, it looks to see if an object has already been created for this type. If so, it returns it. If not, it creates an instance of the type and adds it to the _store dictionary before returning it.&lt;/p&gt;  &lt;p&gt;You can certainly use the ServiceResolver class by itself for IoC, but I prefer using static methods for conciseness. That’s why we need a static wrapper class, called ServiceLocator.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;The ServiceLocator Class&lt;/h2&gt;  &lt;p&gt;Here’s our ServiceLocator static wrapper class.&lt;/p&gt;  &lt;div style="padding: 5px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:53dc0c17-2ae3-4b2c-88ff-9368add6fcd9" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 300px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/li&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Linq;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Text;&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;namespace&lt;/span&gt; Core&lt;/li&gt;&lt;li&gt; {&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; A service locator to resolve abstract types or interfaces to concrete implementations.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceLocator&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     {&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceResolver&lt;/span&gt; _instance = &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; _lock = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;();&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets a shared instance of the ServiceResolver.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;Returns the shared instance of a ServiceResolver, or a new one if it has not yet been accessed.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceResolver&lt;/span&gt; GetInstance()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;lock&lt;/span&gt; (_lock)&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             {&lt;/li&gt;&lt;li&gt;                 &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (_instance == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;                     _instance = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;ServiceResolver&lt;/span&gt;();&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;                 &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; _instance;&lt;/li&gt;&lt;li&gt;             }&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Binds an abstract type to a concrete implementation.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="TFrom"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The abstract type or interface to use as a key.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="TTo"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The implementation type to use as a value.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Register&amp;lt;TFrom, TTo&amp;gt;()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             GetInstance().Register&amp;lt;TFrom, TTo&amp;gt;();&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; Gets an implementation of the given type.&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;typeparam name="T"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;The abstract type or interface to look up.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;returns&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;Returns an implementation of the given type.&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; T Resolve&amp;lt;T&amp;gt;()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; GetInstance().Resolve&amp;lt;T&amp;gt;();&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     }&lt;/li&gt;&lt;li&gt; }&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p&gt;Notice that we’ve got one static instance of the service resolver, and a GetInstance() method that instantiates it if it doesn’t exist. Also notice our Resolve and Register methods that have the same signature (albeit static) as our ServiceResolver class.&lt;/p&gt;  &lt;p&gt;This enables us to simply call ServiceLocator.Resolve&amp;lt;T&amp;gt;() without needing to find an instantiated resolver or create one.&lt;/p&gt;  &lt;p&gt;Just to show you that this was tested, here’s our view:&lt;/p&gt;  &lt;div style="padding: 5px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:79c2b56a-a624-4595-97e7-0f65ec34b36d" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 300px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;asp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Content&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="Content2"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ContentPlaceHolderID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="MainContent"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;h2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;Customers&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;h2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ul&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt; c &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; (&lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt;)ViewData[&lt;span style="color: rgb(163, 21, 21);"&gt;"customers"&lt;/span&gt;])&lt;/li&gt;&lt;li&gt;        { &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;=&lt;/span&gt; c.Name &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;li&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;     &lt;/li&gt;&lt;li&gt;     &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background: rgb(255, 238, 98) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;ul&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;     &lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;asp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;:&lt;/span&gt;&lt;span style="color: rgb(163, 21, 21);"&gt;Content&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p&gt;Here’s our CustomerRepository:&lt;/p&gt;  &lt;div style="padding: 5px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c99d0f7e-8f3d-4eae-8a44-dd893ceb534c" class="wlWriterEditableSmartContent"&gt;&lt;br /&gt;&lt;div   style="border: 1px solid rgb(0, 0, 128);font-family:'Courier New',Courier,Monospace;font-size:10pt;"&gt;&lt;br /&gt;&lt;div style="padding: 2px 5px; background: rgb(255, 255, 255) none repeat scroll 0% 0%; overflow: auto; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; max-height: 300px;"&gt;&lt;br /&gt;&lt;ol style="margin: 0pt; background: rgb(255, 255, 255) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;li&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;namespace&lt;/span&gt; CustomIoCMvc.Models&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt; {&lt;/li&gt;&lt;li&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;CustomerRepository&lt;/span&gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;ICustomerRepository&lt;/span&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     {&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt; Find(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; id)&lt;/li&gt;&lt;li&gt;         {&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; FindAll().Where(c =&amp;gt; c.Id == id).FirstOrDefault();&lt;/li&gt;&lt;li&gt;         }&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt; FindAll()&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         {&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; data = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;&amp;gt;();&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             data.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;() { Id = 1, Name = &lt;span style="color: rgb(163, 21, 21);"&gt;"Joe"&lt;/span&gt; });&lt;/li&gt;&lt;li&gt;             data.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;() { Id = 2, Name = &lt;span style="color: rgb(163, 21, 21);"&gt;"Steve"&lt;/span&gt; });&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;             data.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;Customer&lt;/span&gt;() { Id = 3, Name = &lt;span style="color: rgb(163, 21, 21);"&gt;"Karen"&lt;/span&gt; });&lt;/li&gt;&lt;li&gt;             &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; data;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;         }&lt;/li&gt;&lt;li&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="background: rgb(243, 243, 243) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;     }&lt;/li&gt;&lt;li&gt; }&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;p&gt;And here’s the output:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SrrRiC_iTiI/AAAAAAAAATo/lyY8ygHa8j4/s1600-h/image%5B2%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SrrRjwdgDFI/AAAAAAAAATs/39mPWdIaVmQ/image_thumb.png?imgmax=800" border="0" height="217" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Hope this helps! Please leave constructive comments below. Also note that I'm still playing around with formatting code, please forgive me if it doesn't render correctly!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-2681770129599488502?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/f4A7IOzzIYXuTNvf_0e2in88Y8U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f4A7IOzzIYXuTNvf_0e2in88Y8U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/f4A7IOzzIYXuTNvf_0e2in88Y8U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/f4A7IOzzIYXuTNvf_0e2in88Y8U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/2681770129599488502/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=2681770129599488502" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/2681770129599488502?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/2681770129599488502?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/09/creating-your-own-ioc-container.html" title="Creating Your Own IoC Container" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_xvXvGivrKF0/SrrRjwdgDFI/AAAAAAAAATs/39mPWdIaVmQ/s72-c/image_thumb.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DUMMRX49fip7ImA9WxNQFk4.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-8092806437523572168</id><published>2009-09-22T08:45:00.003-04:00</published><updated>2009-09-22T12:38:04.066-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T12:38:04.066-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pair programming" /><title>Pair Programming in the News</title><content type="html">&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SrjHADdDIhI/AAAAAAAAATg/K61J57IiXyU/s1600-h/20pre600.1%5B3%5D.jpg"&gt;&lt;img style="border: 0px none ; display: inline; margin-left: 0px; margin-right: 0px;" title="20pre600.1" alt="20pre600.1" src="http://lh3.ggpht.com/_xvXvGivrKF0/SrjHAaNVcYI/AAAAAAAAATk/CCO4kouu8Tk/20pre600.1_thumb%5B1%5D.jpg?imgmax=800" align="right" border="0" height="136" width="244" /&gt;&lt;/a&gt;I’ve been a huge fan of pair programming for a while now.  It really is more productive, and it effectively is a real-time code review as you write it. I’ve had the chance to do some pair programming here at the new gig, and it’s worked out really well. A new favorite quote of mine when paraphrased goes something like “You don’t learn from people that agree with you” and with pair programming that is definitely the case. You learn from the mistakes you make when your partner disagrees with what you just wrote.&lt;/p&gt;  &lt;p&gt;So I was very excited to find &lt;a href="http://www.nytimes.com/2009/09/20/jobs/20pre.html?src=tptw" target="_blank"&gt;an article about pair programming in the New York Times&lt;/a&gt;. Check it out and let me know in the comments what your thoughts are.&lt;/p&gt;  &lt;p&gt;I’ve got a few new discoveries with ASP.NET MVC and Dependency Injection that I’m gearing up some posts about, and as you may have noticed, I’m still trying to figure out the best way to get code into this blog as a formatted, copy-and-paste-able format.    &lt;/p&gt;&lt;p&gt;&lt;/p&gt;    &lt;p&gt;I’m looking forward to the next meetings (and my first) of &lt;a href="http://www.jaxdug.com/" target="_blank"&gt;JaxDUG&lt;/a&gt; (Jacksonville .NET User Group),  &lt;a href="http://jaxarcsig.spaces.live.com/default.aspx?sa=811254021" target="_blank"&gt;ArcSIG&lt;/a&gt; (for Architects), and the &lt;a href="http://jacksonville.sqlpass.org/" target="_blank"&gt;Jacksonvile SQL Server Users Group&lt;/a&gt;. I’m a big fan of community, and if you’ve never been to a local .NET user group, I strongly encourage you to give it a try.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt; It appears that at least one person is &lt;a href="http://blog.obiefernandez.com/content/2009/09/10-reasons-pair-programming-is-not-for-the-masses.html"&gt;asserting a more pessimistic view&lt;/a&gt; of this article. I really am not a proponent of that kind of negative, borderline arrogant language, as I try to make this blog positive and forward-thinking for beginners as well as experts -- but it's an interesting read nonetheless.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-8092806437523572168?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iY05tM_jUDHiXE1lfiVz7Cgoh1M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iY05tM_jUDHiXE1lfiVz7Cgoh1M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iY05tM_jUDHiXE1lfiVz7Cgoh1M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iY05tM_jUDHiXE1lfiVz7Cgoh1M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/8092806437523572168/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=8092806437523572168" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8092806437523572168?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8092806437523572168?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/09/pair-programming-in-news.html" title="Pair Programming in the News" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_xvXvGivrKF0/SrjHAaNVcYI/AAAAAAAAATk/CCO4kouu8Tk/s72-c/20pre600.1_thumb%5B1%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkIHSX88cSp7ImA9WxNTF00.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-515813715962676330</id><published>2009-08-19T10:23:00.001-04:00</published><updated>2009-08-19T12:48:58.179-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-19T12:48:58.179-04:00</app:edited><title>ASP.NET: WebForms Validation with Data Annotations</title><content type="html">&lt;p&gt;Last night at my last regular trip to the &lt;a href="http://www.lakelandug.net" target="_blank"&gt;Lakeland .NET User Group&lt;/a&gt; I had a discussion with someone about how it’s great that Data Annotations is being used by &lt;a href="http://blogs.msdn.com/jimoneil/archive/2008/07/08/dynamic-data-annotations.aspx" target="_blank"&gt;Dynamic Data&lt;/a&gt;, &lt;a href="http://blogs.microsoft.co.il/blogs/bursteg/archive/2009/04/14/Net-RIA-Services-DataForm-Validation.aspx" target="_blank"&gt;RIA services&lt;/a&gt;, and now &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx" target="_blank"&gt;ASP.NET MVC 2&lt;/a&gt;, but that there isn’t a WebForms validation control (like the PropertyProxyValidator in the Validation block of &lt;a href="http://www.codeplex.com/entlib" target="_blank"&gt;Enterprise Library&lt;/a&gt;) to auto-validate against Data Annotations. I suggested we write one. I did so this morning.&lt;/p&gt;  &lt;p&gt;If you aren’t familiar with Data Annotations, it’s a &lt;em&gt;really&lt;/em&gt; cool feature of .NET 3.5 SP1. Check out those 3 links above (Dynamic Data, RIA, and MVC) for more info of how they’re used elsewhere.&lt;/p&gt;  &lt;h2&gt;The DataAnnotationValidator Class&lt;/h2&gt;  &lt;p&gt;Here’s the code for the Data Annotations Validator that I built for WebForms. I just created this as a class file in the App_Code folder of my web project for testing, but you’d probably want to move it into your shared library (if you have one). You’ll need to add a reference to System.ComponentModel.DataAnnotations first.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SowK3UX9szI/AAAAAAAAARo/LCHS6IVsEyg/s1600-h/image%5B12%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SowK4HpINiI/AAAAAAAAARs/qW7RLfFt1kw/image_thumb%5B6%5D.png?imgmax=800" width="530" height="373" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And there’s just 2 properties in this class:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SowK4YvcSkI/AAAAAAAAARw/eC44QV4uAdA/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SowK48jTFDI/AAAAAAAAAR0/HhoqWepsLrE/image_thumb%5B3%5D.png?imgmax=800" width="322" height="282" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Data Annotating Your Class&lt;/h2&gt;  &lt;p&gt;Here’s a test class I wrote using some common annotations:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SowK5dqmNfI/AAAAAAAAAR4/b8huTMG24tE/s1600-h/image%5B13%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SowK5_wxOqI/AAAAAAAAAR8/VqklhGjc7Qw/image_thumb%5B7%5D.png?imgmax=800" width="517" height="354" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Here you see you can add multiple validators together (such as Required and StringLength in this example). And there’s also a RegularExpression validator:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SowK6XPxN8I/AAAAAAAAASA/m7DCNnDGvQg/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK6qFznJI/AAAAAAAAASE/2Hmzn9temQE/image_thumb%5B9%5D.png?imgmax=800" width="520" height="264" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Usage&lt;/h2&gt;  &lt;p&gt;To use this DataAnnotationValidator on your page, you must first register the namespace. (Note: you can also do this in the web.config to force it on all pages in your site.)&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SowK7IrSgHI/AAAAAAAAASI/FWw7TbVndfo/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SowK7rUCAKI/AAAAAAAAASM/11BM0iRhCFk/image_thumb%5B11%5D.png?imgmax=800" width="455" height="137" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The namespace value must match the namespace of DataAnnotationValidator. &lt;/p&gt;  &lt;p&gt;To add a validator to a form field, just create a new &amp;lt;val:DataAnnotationValidator&amp;gt; tag for each field:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SowK7xkGHtI/AAAAAAAAASQ/4MY4ODD7dXM/s1600-h/image%5B25%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK8TnQklI/AAAAAAAAASU/yj9MkEIXgMs/image_thumb%5B13%5D.png?imgmax=800" width="512" height="154" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice the SourceType property? That value must match the full type name of the object you’re validating.&lt;/p&gt;  &lt;p&gt;Now when you try and submit your form you get this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SowK82vY2CI/AAAAAAAAASY/-WMNudrmA1k/s1600-h/image%5B29%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK9QnwZkI/AAAAAAAAASc/7evWrpIu_4o/image_thumb%5B15%5D.png?imgmax=800" width="317" height="203" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;(In this example, the Address 2 field is not marked as required.)&lt;/p&gt;  &lt;p&gt;You can also simply add a ValidationSummary to the page to show what is wrong:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SowK9u7HhbI/AAAAAAAAASg/jOEgERRmrGk/s1600-h/image%5B33%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK98RmdQI/AAAAAAAAASk/nF1j2fjvWok/image_thumb%5B17%5D.png?imgmax=800" width="422" height="98" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And now we get a helpful list of errors:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SowK-fIU-fI/AAAAAAAAASo/khNB6BMFUGk/s1600-h/image%5B41%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK-pDXONI/AAAAAAAAASs/4eI2porj5rE/image_thumb%5B21%5D.png?imgmax=800" width="298" height="249" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You’re probably thinking, though, “what’s so special about this? I could just use a RequiredFieldValidator.” True, but we now have multiple validators per property with just one validator tag, and we don’t have to make the front end logic match the back end annotations. Separation of concerns!&lt;/p&gt;  &lt;p&gt;Here’s the RegularExpression data annotations validator at work:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SowK_D2SLvI/AAAAAAAAASw/Sdv24kZicZM/s1600-h/image%5B45%5D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SowK_chojhI/AAAAAAAAAS0/SXzbvu9gIZY/image_thumb%5B23%5D.png?imgmax=800" width="374" height="341" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;You can see where this becomes handy – you annotate your class once, and you can then use it in RIA services, ASP.NET MVC 2, and now WebForms, and you don’t have to have any validation logic in your front end code. This idea could easily be modified for Windows Forms or WPF as well. You could also easily modify the code to set a CSS style for the textbox that would change the background color on error.&lt;/p&gt;  &lt;p&gt;Hope this helps! Let me know any questions or concerns in the comments.&lt;/p&gt;  &lt;p&gt;Also, I couldn’t have done this without some guidance from the Enterprise Library PropertyProxyValidator source code, and &lt;a href="http://stackoverflow.com/questions/370826/how-to-use-data-annotation-validators-in-winforms" target="_blank"&gt;this Stack Overflow question/answer&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Update: Using DisplayName&lt;/h3&gt;  &lt;p&gt;I realized that I was forgetting a key part of data annotations – that it supports the DisplayNameAttribute! This removes all of the string error messages from the class definition and generates them for you. Below are the modifications to support DisplayName. If a display name is not given, it will use the property name instead, which is great for single word property names like “City”.&lt;/p&gt;  &lt;p&gt;In your class file that you’re annotating, import System.ComponentModel.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/Sows5ywerHI/AAAAAAAAAS4/BO0D_x8fxT0/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Sows6ZOo_NI/AAAAAAAAAS8/KKLzXK4NHa0/image_thumb%5B1%5D.png?imgmax=800" width="330" height="66" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In the DataAnnotationValidator class, modify the routine to look up the DisplayName or property name like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Sows6zb4V8I/AAAAAAAAATA/4umeUsI-ll4/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Sows7exI4-I/AAAAAAAAATE/AozMqSlb-8c/image_thumb%5B3%5D.png?imgmax=800" width="537" height="204" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Also make sure you modify the Me.ErrorMessage line to use attr.FormatErrorMessage(displayName) like above.&lt;/p&gt;  &lt;p&gt;Now, you can yank out all of those error message strings! If you’ve got a single word property name, like Id, you can just do this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sows70Z7_SI/AAAAAAAAATI/3OeoCQe1Eqo/s1600-h/image%5B13%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/Sows8l7mNcI/AAAAAAAAATM/94FdQ-Hgj9U/image_thumb%5B6%5D.png?imgmax=800" width="231" height="138" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And if you need to add a display name, you can add the DisplayName() attribute:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/Sows82yKQjI/AAAAAAAAATQ/6B1yhJciwKo/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sows9Yz6YzI/AAAAAAAAATU/mv2bR5fxKyM/image_thumb%5B8%5D.png?imgmax=800" width="388" height="151" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Once we’ve made these modifications (which make the class definition much more concise), we get the following output on our form, without having to write our own error messages:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sows9pOsTVI/AAAAAAAAATY/dpsJKz_uysA/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sows-F1DwJI/AAAAAAAAATc/C1gZ_tSQmCM/image_thumb%5B10%5D.png?imgmax=800" width="305" height="209" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;You’ll still want to keep the error message specified for the RegularExpression annotation validator, because it actually shows the RegEx expression in the error message, which will confuse your users.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-515813715962676330?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TlfAZTm7Gz5iGLTYUpAdE-7HJUY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TlfAZTm7Gz5iGLTYUpAdE-7HJUY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TlfAZTm7Gz5iGLTYUpAdE-7HJUY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TlfAZTm7Gz5iGLTYUpAdE-7HJUY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/515813715962676330/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=515813715962676330" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/515813715962676330?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/515813715962676330?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/08/aspnet-webforms-validation-with-data.html" title="ASP.NET: WebForms Validation with Data Annotations" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/_xvXvGivrKF0/SowK4HpINiI/AAAAAAAAARs/qW7RLfFt1kw/s72-c/image_thumb%5B6%5D.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;A0QCQXYzfyp7ImA9WxNTFUk.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-934836491316143880</id><published>2009-08-17T18:49:00.001-04:00</published><updated>2009-08-17T18:49:20.887-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-17T18:49:20.887-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="vb.net" /><category scheme="http://www.blogger.com/atom/ns#" term="dependency injection" /><category scheme="http://www.blogger.com/atom/ns#" term="ninject" /><title>First Steps into Dependency Injection with Ninject</title><content type="html">&lt;p&gt;I recently started playing around with dependency injection, but it was very much a by-hand process using constructor injection without any kind of framework. It worked well for my proof of concepts, but I had a breakthrough today when I tried Ninject. If you’re looking to get into DI/IoC, this hopefully will be a good place to start. I’m right there with you, I’m a newbie to DI as well.&lt;/p&gt;  &lt;p&gt;If you’re already confused by the first paragraph, Dependency Injection (hereafter called DI) and Inversion of Control (hereafter called IoC) are &lt;em&gt;almost&lt;/em&gt; synonyms for a development methodology where you aim to reduce coupling between classes as much as possible. Coupling means that one class depends on another, which increases complexity for large projects and almost ruins testability. For example, if your class needs to use a database connection, you might not want to couple it with SqlClient.SqlConnection, you might just want to couple it to the interface IDbConnection instead, so that it can accept any type of connection. (SqlConnection implements IDbConnection.) This makes your code more flexible for testing, because you can create a mock connection that implements IDbConnection and perform unit tests without hitting your database. This is just one example, although there are many reasons to use DI.&lt;/p&gt;  &lt;p&gt;While there are other methods of injection, I’m only going to talk about 2 in this post – &lt;strong&gt;constructor injection&lt;/strong&gt; and &lt;strong&gt;property injection&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;In this example, let’s say you have a Customer class that needs to use a database connection. Since you want to roll your own database connection wrapper classes, you also want to implement logging so you can keep track of your database requests.&lt;/p&gt;  &lt;p&gt;Let’s start out with a console application. &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Disclaimer:&lt;/em&gt; This is demo code only. It doesn’t actually connect to a database, and does not implement best practices for security or anything else. Please keep that in mind!&lt;/p&gt;  &lt;h2&gt;Downloading Ninject&lt;/h2&gt;  &lt;p&gt;You can download Ninject and take a short tutorial at &lt;a href="http://www.ninject.org"&gt;www.ninject.org&lt;/a&gt;.&amp;#160; The download is a .zip file with all of the Ninject DLLs that you’ll ever need, but really we’re just concerned with the Ninject.Core assembly.&lt;/p&gt;  &lt;h2&gt;Add Ninject as a Reference&lt;/h2&gt;  &lt;p&gt;Create a new console application, and from the My Project pages, add the extracted Ninject.Core.dll file as a reference.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneQVn9x2I/AAAAAAAAAPo/n8kTEBIu-dE/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SoneQ2t67wI/AAAAAAAAAPs/ahj2IDrzvT0/image_thumb%5B1%5D.png?imgmax=800" width="368" height="342" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;It’ll also make it easier later on to go ahead and import the Ninject.Core namespace from the References property page:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SoneRPtx0GI/AAAAAAAAAPw/ivt7XUeG4Kw/s1600-h/image%5B6%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SoneRhLpWTI/AAAAAAAAAP0/t-YO-XqvDzU/image_thumb%5B2%5D.png?imgmax=800" width="244" height="231" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;The Old Way&lt;/h2&gt;  &lt;p&gt;First, let’s look at how we might previously have implemented the Customer class without DI.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneR79_X_I/AAAAAAAAAP4/ULLnqHmhZ7k/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SoneScM5yjI/AAAAAAAAAP8/HrEde69MgWQ/image_thumb%5B5%5D.png?imgmax=800" width="511" height="370" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Here you can see that we’ve got a private SqlConnection object that is created in the constructor. There’s no way here to swap that out for a mock connection for testing, and we’ve got a coupling between Customer and SqlConnection.&lt;/p&gt;  &lt;p&gt;Now let’s look at how SqlConnection does its logging (note that this class is obviously just for demo purposes):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SoneSpJZdQI/AAAAAAAAAQA/AsIK0qcJ8wA/s1600-h/image%5B15%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SoneT0jGyHI/AAAAAAAAAQE/6cBsJiJlGcE/image_thumb%5B7%5D.png?imgmax=800" width="517" height="285" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;As you might have guessed, our SqlConnection object now has a tight coupling with ConsoleLogger. What if we wanted to log to a database or email instead? With this method, we can’t.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Dependency Injection By Hand&lt;/h2&gt;  &lt;p&gt;As I mentioned earlier, I started out by doing DI by hand, so let’s see what that might look like.&lt;/p&gt;  &lt;p&gt;First let’s make an interface for our database connection:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SoneUC_zchI/AAAAAAAAAQI/jtEajJARcYE/s1600-h/image%5B20%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SoneUu4F6DI/AAAAAAAAAQM/-49rVwOM2LA/image_thumb%5B10%5D.png?imgmax=800" width="500" height="165" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now, here’s what our SqlConnection class looks like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SoneU7lwaFI/AAAAAAAAAQQ/KdkmYB2Wn0Q/s1600-h/image%5B24%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SoneVRRvs8I/AAAAAAAAAQU/JIomqAQ9cDc/image_thumb%5B12%5D.png?imgmax=800" width="491" height="399" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We still have a dependency on ConsoleLogger, but we’ll remove that later.&lt;/p&gt;  &lt;p&gt;Now our customer class no longer has a dependency on SqlConnection:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SoneVsbFYWI/AAAAAAAAAQY/rbI7dx_l2Ko/s1600-h/image%5B28%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SoneWLdydtI/AAAAAAAAAQc/-9Iiyz-HT_8/image_thumb%5B14%5D.png?imgmax=800" width="503" height="352" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And here’s how we use it in our console app:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SoneWav6R4I/AAAAAAAAAQg/jhHP5dWtYPg/s1600-h/image%5B32%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SoneWvD39nI/AAAAAAAAAQk/IGJnd90wnGM/image_thumb%5B16%5D.png?imgmax=800" width="455" height="308" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And the result is (with our ConsoleLogger output):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneWxFHhVI/AAAAAAAAAQo/daliders30Q/s1600-h/image%5B36%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SoneXblPOjI/AAAAAAAAAQs/qfJCNaJruwM/image_thumb%5B18%5D.png?imgmax=800" width="462" height="248" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We still have to inject the SqlConnection by hand, which would work in front end code, but is not ideal. &lt;/p&gt;  &lt;p&gt;So, proceeding onto removing the dependency on ConsoleLogger, how would we accomplish this with the method above? Well, we’d probably have to pass in a new ConsoleLogger (implementing ILogger) into our customer object as well. However, then we’d have to pass that logger from the customer into the SqlConnection by a constructor or property. And what if we have to create multiple objects that use the same connection or logger? It becomes a mess very quickly. This is where Ninject steps in to help.&lt;/p&gt;  &lt;p&gt;Let’s wrap up a few more things, such as creating an interface for our loggers:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SoneXmYrMYI/AAAAAAAAAQw/TQmReOIvkOI/s1600-h/image%5B41%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SoneX1z0LqI/AAAAAAAAAQ0/hE0zfHmaqg4/image_thumb%5B21%5D.png?imgmax=800" width="280" height="132" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;Then we’d make ConsoleLogger implement ILogger.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SoneYShDZuI/AAAAAAAAAQ4/m5VkllXQXy0/s1600-h/image%5B45%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SoneYq12LoI/AAAAAAAAAQ8/ZLTNxm9X358/image_thumb%5B23%5D.png?imgmax=800" width="512" height="266" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Setting Up our Injections&lt;/h2&gt;  &lt;p&gt;How Ninject and other DI solutions work is by automatically wiring up our dependencies for us. For example, we need to wire up 2 dependencies: anytime we want an IDataConnection in this app we want to use a SqlConnection, and anytime we want an ILogger we want a ConsoleLogger. This makes the code testable because you can wire up in your tests to use a mock IDataConnection instead, with another type of logger if you wish.&lt;/p&gt;  &lt;p&gt;We’re going to use those two methods of injection as mentioned here before. First, &lt;strong&gt;constructor injection&lt;/strong&gt;. We want to use the constructor of the Customer object to inject a dependency on SqlConnection. Here’s how we mark that constructor for injection:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneYzlD2pI/AAAAAAAAARA/YQHo6QnItBg/s1600-h/image%5B49%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SoneZdxAE4I/AAAAAAAAARE/FinCFZr71ew/image_thumb%5B25%5D.png?imgmax=800" width="419" height="255" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next, we want to use &lt;strong&gt;property injection&lt;/strong&gt; to inject a dependency of ConsoleLogger into the SqlConnection. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneZlMEhDI/AAAAAAAAARI/qlVvKZyaes4/s1600-h/image%5B53%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SoneZy6VHkI/AAAAAAAAARM/U_xGSHSUSfQ/image_thumb%5B27%5D.png?imgmax=800" width="361" height="312" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note that we’re accomplishing the same goal, but using a Property instead of a Constructor.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Tying It All Together&lt;/h2&gt;  &lt;p&gt;Ninject uses the idea of a “kernel” to generate all the dependencies. And the kernel can have passed into it multiple “modules” to wire them all together. First we’ll create the DataModule, although you can call it whatever you like:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoneaLWiVNI/AAAAAAAAARQ/_FjyA6SycAQ/s1600-h/image%5B57%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SoneamgcYaI/AAAAAAAAARU/B8bn9QV307E/image_thumb%5B29%5D.png?imgmax=800" width="495" height="228" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note that it must inherit from StandardModule for this to work. &lt;/p&gt;  &lt;p&gt;Those 2 lines of code inside the Load method are pretty powerful. They’re saying, using generics, that anytime a class requests an IDataConnection, we want a SqlConnection, and anytime a class requests an ILogger, we get a ConsoleLogger. This is dependency injection at work!&lt;/p&gt;  &lt;p&gt;So now that we have our loosely coupled classes (because no class depends on another) and our module for wiring up our connection and logger, we need to actually use the kernel.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/Sonea70EqeI/AAAAAAAAARY/iszSW3qPI-E/s1600-h/image%5B61%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SonebQmLkRI/AAAAAAAAARc/3PTBc20V5DQ/image_thumb%5B31%5D.png?imgmax=800" width="492" height="488" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/Sonebmx2UCI/AAAAAAAAARg/H0wUugWYdaI/s1600-h/image%5B65%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Soneb4mjaBI/AAAAAAAAARk/eAabVMQl4fk/image_thumb%5B33%5D.png?imgmax=800" width="501" height="279" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Hooray for DI! Now, our front end code doesn’t need to know that it’s using a SqlConnection or ConsoleLogger, it’s happening for us behind the scenes. We could even make the SqlConnection or ConsoleLogger a singleton so that there’s only one instance of it in our application, just by adding the &amp;lt;Singleton()&amp;gt; attribute to the class.&lt;/p&gt;  &lt;p&gt;I hope this shows off the basics of using Ninject in an application. Beyond this, I’m not an expert. I only recently got involved in DI, and only today with Ninject. But I’m really impressed so far, and I think once you play around with it you will be too.&lt;/p&gt;  &lt;p&gt;Please do not hesitate to (kindly) let me know your questions or concerns in the comments.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-934836491316143880?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZZBYFt5s51XdUeKe0u6bOAXQDRE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZZBYFt5s51XdUeKe0u6bOAXQDRE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZZBYFt5s51XdUeKe0u6bOAXQDRE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZZBYFt5s51XdUeKe0u6bOAXQDRE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/934836491316143880/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=934836491316143880" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/934836491316143880?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/934836491316143880?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/08/first-steps-into-dependency-injection.html" title="First Steps into Dependency Injection with Ninject" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_xvXvGivrKF0/SoneQ2t67wI/AAAAAAAAAPs/ahj2IDrzvT0/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CUIDSXg-cSp7ImA9WxNTEUQ.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-3075813112078770742</id><published>2009-08-13T15:59:00.001-04:00</published><updated>2009-08-13T15:59:38.659-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-13T15:59:38.659-04:00</app:edited><title>Jacksonville, here I come!</title><content type="html">&lt;p&gt;I am happy to say that I have taken a position as a .NET developer at &lt;a href="http://www.footballfanatics.com/" target="_blank"&gt;Football Fanatics&lt;/a&gt; in Jacksonville! It’s a booming business with a lot of smart developers and they’re really doing some cool things. I’m excited to take on the challenge!&lt;/p&gt;  &lt;p&gt;And, to show that it will be a learning experience, they pointed out in my interview that my last post, &lt;a href="http://adventuresdotnet.blogspot.com/2009/08/net-conditionally-removing-items-from.html" target="_blank"&gt;Conditionally Removing Items from a Generic List&lt;/a&gt;, is probably not the best way to do things. After the interview, a large forehead-slap was in order. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SoRwqG8HqyI/AAAAAAAAAPg/Om5okWsQcHQ/s1600-h/image%5B5%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SoRwqi4LRDI/AAAAAAAAAPk/w0dfs-pZ1PQ/image_thumb%5B3%5D.png?imgmax=800" width="303" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So yes, you can remove items conditionally from the list by just using the RemoveAll function with a lambda passed in.&lt;/p&gt;  &lt;p&gt;D’oh. &lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-3075813112078770742?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ELdMqlZNaE9wM9my71certARpy0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ELdMqlZNaE9wM9my71certARpy0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ELdMqlZNaE9wM9my71certARpy0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ELdMqlZNaE9wM9my71certARpy0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/3075813112078770742/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=3075813112078770742" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3075813112078770742?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3075813112078770742?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/08/jacksonville-here-i-come.html" title="Jacksonville, here I come!" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_xvXvGivrKF0/SoRwqi4LRDI/AAAAAAAAAPk/w0dfs-pZ1PQ/s72-c/image_thumb%5B3%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0cMSXcyfSp7ImA9WxJaGU8.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-6032161086245144660</id><published>2009-08-10T12:18:00.001-04:00</published><updated>2009-08-10T12:18:08.995-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-10T12:18:08.995-04:00</app:edited><title>A New Adventure</title><content type="html">&lt;p&gt;After 2 years of living in Lakeland, my wife and I decided that now was a good point in our lives to make a very risky jump – to move to Jacksonville without any jobs lined up to speak of. With a bad job market, this may end up being a bad decision, but we’re confident that things will work out in one way or another. Jacksonville is more our speed, and we just aren’t really happy here. I let my work know today, and it’s going to be a nice, clean, professional break. The job opportunities I’ve been connected with seem like great ways to advance my career and work with some smart people, so I’m excited!&lt;/p&gt;  &lt;p&gt;In a month or so we’ll be relocating to Jax and starting the next chapter of our lives. In the mean time, I’ll make my last visit to the Lakeland .NET User Group as a resident of Lakeland, try to write at least another blog post (I still need to finish up one draft), and pack everything up. &lt;/p&gt;  &lt;p&gt;I look forward to joining the Jacksonville user groups and I’ll be attending the Jacksonville Code Camp (and helping Russ Fustino with his “It’s All About The Tools” channel9 episode filming) on August 29th. Hope to see you there!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-6032161086245144660?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Yej89Q2vciGwibeTqgL1eMllyC8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Yej89Q2vciGwibeTqgL1eMllyC8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Yej89Q2vciGwibeTqgL1eMllyC8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Yej89Q2vciGwibeTqgL1eMllyC8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/6032161086245144660/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=6032161086245144660" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/6032161086245144660?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/6032161086245144660?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/08/new-adventure.html" title="A New Adventure" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkMCQHw_eSp7ImA9WxJaFUQ.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-7372552656302087495</id><published>2009-08-06T16:22:00.003-04:00</published><updated>2009-08-06T16:27:41.241-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-06T16:27:41.241-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="generics" /><category scheme="http://www.blogger.com/atom/ns#" term="lists" /><title>Generics: Conditionally Removing Items from a List</title><content type="html">&lt;p&gt;Consider this scenario: you have a generic list of items, and you want to loop over each item in the list and if it matches some condition, you want to remove it.&lt;/p&gt;  &lt;p&gt;You might try the following code at first, to remove all even items from a list of integers, 0-9:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/Sns7hqxsNFI/AAAAAAAAAOo/EZ73wkbVgxk/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Sns7iQkZMhI/AAAAAAAAAOs/Swu25IObYGs/image_thumb%5B1%5D.png?imgmax=800" border="0" height="182" width="297" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The problem is, since you’re enumerating over the list in the first foreach loop, you actually are modifying the list as you’re enumerating over it, so it throws the following error:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/Sns7iyuPqcI/AAAAAAAAAOw/g51QLrAxgR0/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sns7jVEblmI/AAAAAAAAAO0/ukhJZ9ZGQv4/image_thumb%5B3%5D.png?imgmax=800" border="0" height="195" width="525" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Even though it’s clearly a beginner’s mistake, I still find myself wanting to be able to do this easily.&lt;/p&gt;  &lt;p&gt;So what are your other options? You can keep a separate list going of items to remove, and then enumerate over the list to remove and handle it that way, or you can skip the foreach entirely and operate based on indexes, but either way, you’re adding a lot of code to keep track of which objects to remove and to make sure you don’t encounter errors.&lt;/p&gt;  &lt;p&gt;What if you just wanted to have the items removed from the list as soon as you’re done enumerating over it? Unfortunately, to my knowledge, that’s not supported in .NET. &lt;strong&gt;Please correct me if I’m wrong!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;So, I created a quick helper class to handle this situation. It implements IEnumerable&amp;lt;T&amp;gt; so you can do a foreach over it, as well as IDisposable so that you can use it in a Using block and as soon as it goes out of scope, it removes the items from the list.&lt;/p&gt;  &lt;p&gt;Here’s the usage:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Sns7jVsT6VI/AAAAAAAAAO4/e6mi9xzFTMw/s1600-h/image%5B12%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/Sns7jm9hXtI/AAAAAAAAAO8/r03YKWbrQSw/image_thumb%5B6%5D.png?imgmax=800" border="0" height="229" width="362" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice that all you have to do is add one line of true code, a using block around your existing removal code, and just call “dc.Remove” (or “dc.RemoveAt”) instead of “data.Remove”! And in this example, I’m enumerating over “dc” just to show you that you can, but since nothing is actually removed until that ending curly brace of the using block, you could just as easily say “foreach (int i in data)” like before.&lt;/p&gt;  &lt;p&gt;Here’s the DelayedCleanup&amp;lt;T&amp;gt; class:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Sns7j3Ch1OI/AAAAAAAAAPA/9-ISRRWvI5E/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/Sns7kJZ1eYI/AAAAAAAAAPE/4MZqwHzQQzU/image_thumb%5B8%5D.png?imgmax=800" border="0" height="566" width="527" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;This implementation actually has a second list that stores the references (or values for value types) of the items to remove, but you could easily modify this to use indices and then sort them descending to remove the items.&lt;/p&gt;  &lt;p&gt;Hope this helps! Please leave constructive feedback in the comments, I’d love to hear any thoughts or concerns you have.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-7372552656302087495?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NHtuUS9t7PzKk9cf6p_as9kv28g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NHtuUS9t7PzKk9cf6p_as9kv28g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NHtuUS9t7PzKk9cf6p_as9kv28g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NHtuUS9t7PzKk9cf6p_as9kv28g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/7372552656302087495/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=7372552656302087495" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/7372552656302087495?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/7372552656302087495?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/08/net-conditionally-removing-items-from.html" title="Generics: Conditionally Removing Items from a List" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_xvXvGivrKF0/Sns7iQkZMhI/AAAAAAAAAOs/Swu25IObYGs/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;Ck4ERHoycSp7ImA9WxJbEko.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-3146716875715759078</id><published>2009-07-22T09:41:00.002-04:00</published><updated>2009-07-22T09:55:05.499-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-22T09:55:05.499-04:00</app:edited><title>Lakeland .NET User Group - Speaker Idol</title><content type="html">I had a great time last night at the Lakeland .NET User Group at PSC. (Polk State College, formerly Polk Community College. The new name still trips me up, especially since I used to work for the PSC, the Florida Public Service Commission.) Great speakers, lots of fun.&lt;br /&gt;&lt;br /&gt;The trifecta team of the school board each spoke, with great presentations on the Array class, RIA services and concurrency, and &lt;a href="http://bgeiger.net/blog/"&gt;Ben Geiger&lt;/a&gt; on the Balsamiq mockup software. Also, &lt;a href="http://geekswithblogs.net/campuskoder/Default.aspx"&gt;Nikita Polyakov&lt;/a&gt; gave an introduction to Windows Mobile development with WM 6.5 and the new Marketplace opening next week, and &lt;a href="http://orlandotechnuts.blogspot.com/"&gt;Megan Hopkins&lt;/a&gt; on what to do (and not to do) when trying to land a tech job.&lt;br /&gt;&lt;br /&gt;My talk was on VB's &lt;a href="http://msdn.microsoft.com/en-us/library/ms364068%28VS.80%29.aspx#vb9overview_topic6"&gt;XML Literals&lt;/a&gt; with a code-only presentation from scratch. The swag I took home was a free license of Balsamiq, which after Ben's talk, I'm very excited about! It's an Adobe AIR-based application that allows you to do SketchFlow-like things in a different way for creating UI mockups.&lt;br /&gt;&lt;br /&gt;(I ended up winning Speaker Idol, but I don't want that to take away from how great the other presentations were! Check out their blogs, follow them on Twitter.)&lt;br /&gt;&lt;br /&gt;I mentioned a video on Channel9 where a guy created an entire ASP.NET MVC view engine using only XML Literals in VB, with no .aspx files, so the entire website can be compiled into a single DLL. Amazing stuff. Make sure you &lt;a href="http://channel9.msdn.com/posts/funkyonex/ASPNET-MVC-using-Visual-Basic-XML-Literals/"&gt;check out the video&lt;/a&gt;. Even if you don't use VB, it's very fun to watch and think about.&lt;br /&gt;&lt;br /&gt;Tonight I'll be heading over to the Tampa UG (my first visit!) to check out &lt;a href="http://blogs.msdn.com/rfustino/archive/2009/07/16/it-s-all-about-the-tools-tv-show-expression-3-windows-live-writer-mobility-and-more-russ-fustino-bill-reiss-nikita-polyakov-and-stan-schultes.aspx"&gt;the filming of Russ' Tool Shed&lt;/a&gt;. Looking forward to meeting Tampa folks, and hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-3146716875715759078?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xFEZv0f2ZHFQEFuuIGkaHu3uWSU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xFEZv0f2ZHFQEFuuIGkaHu3uWSU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xFEZv0f2ZHFQEFuuIGkaHu3uWSU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xFEZv0f2ZHFQEFuuIGkaHu3uWSU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/3146716875715759078/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=3146716875715759078" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3146716875715759078?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/3146716875715759078?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/07/lakeland-net-user-group-speaker-idol.html" title="Lakeland .NET User Group - Speaker Idol" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0AFQ3s8eyp7ImA9WxJUFkU.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-5723584945823701688</id><published>2009-07-15T14:15:00.001-04:00</published><updated>2009-07-15T14:15:12.573-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-15T14:15:12.573-04:00</app:edited><title>ASP.NET: Serving ASPX files as .XML (or .HTML, etc.)</title><content type="html">&lt;p&gt;Say you want to serve/rename/rewrite a .aspx file as a .xml file so that your URL looks like &lt;a href="http://mysite.com/mypage.xml"&gt;http://mysite.com/mypage.xml&lt;/a&gt; instead of &lt;a href="http://mysite.com/mypage.aspx"&gt;http://mysite.com/mypage.aspx&lt;/a&gt;. This is useful for scenarios such as RSS feeds. (Or, perhaps, you want to serve it as a .html file, or something else. For the rest of this example, replace .xml with the file extension you want.)&lt;/p&gt;  &lt;h2&gt;Step 1: Rename Your File&lt;/h2&gt;  &lt;p&gt;First, create your .aspx file with a codebehind and verify that it works. Then, rename the .aspx file (and NOT the .aspx.vb or .aspx.cs file!) to .xml. You should then have 2 files that look like MyPage.xml and MyPage.aspx.vb (or MyPage.aspx.cs).&lt;/p&gt;  &lt;h2&gt;Step 2: Register the Build Provider&lt;/h2&gt;  &lt;p&gt;Open up your Web.config file, and locate the compilation/buildProviders section. Add a tag for the new extension to tie it to the System.Web.Compilation.PageBuildProvider build provider like so:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cnMo9i4I/AAAAAAAAANQ/MasNkUyO964/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cnTQQQLI/AAAAAAAAANU/2Z5QAMZiD1U/image_thumb%5B1%5D.png?imgmax=800" width="544" height="309" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Step 3: Register the HttpHandlers for IIS6 and IIs7&lt;/h2&gt;  &lt;p&gt;In our current environment, our development systems are running IIS7 while our production server is running IIS6, so I need to handle both cases. You may only need to handle the IIS6 or IIS7 specific tags, but it’s not a bad idea to handle both.&lt;/p&gt;  &lt;p&gt;For IIS6, locate the httpHandlers section of your Web.Config and add the .xml handler:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cnkKeJ_I/AAAAAAAAANY/IrXnHgd1Icc/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Sl4cn9ac49I/AAAAAAAAANc/n0l9NK7W6XU/image_thumb%5B3%5D.png?imgmax=800" width="558" height="136" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;For IIS7, locate the system.webServer/handlers section of your web.config and add the .xml handler as well:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4coEhMVpI/AAAAAAAAANg/eumQmpf21ZE/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4coXYA7oI/AAAAAAAAANk/NGNs49yAixA/image_thumb%5B5%5D.png?imgmax=800" width="566" height="70" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;Step 4a: Register the .XML Handler in IIS7&lt;/h2&gt;  &lt;p&gt;If you’re running IIS7, you may need to add a managed handler in the IIS Manager control panel by doing the following:&lt;/p&gt;  &lt;p&gt;1) Select the site you wish to enable this on.&lt;/p&gt;  &lt;p&gt;2) Open the Handler Mappings section:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cohuaLAI/AAAAAAAAANo/Lf-HgVnGU8M/s1600-h/image%5B14%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Sl4co4MQLEI/AAAAAAAAANs/LaogyiDJIU8/image_thumb%5B6%5D.png?imgmax=800" width="198" height="205" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;3) In the top-right pane, choose Add Managed Handler:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/Sl4cowH33SI/AAAAAAAAANw/PDen66Yow_0/s1600-h/image%5B17%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cpGEUSeI/AAAAAAAAAN0/H4OrthnoC6w/image_thumb%5B7%5D.png?imgmax=800" width="215" height="138" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4) Enter the following details:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cpchf_OI/AAAAAAAAAN4/qEmDo7Z1zLY/s1600-h/image%5B21%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/Sl4cpo8MQQI/AAAAAAAAAN8/J3sxBrpysFg/image_thumb%5B9%5D.png?imgmax=800" width="439" height="281" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Step 4b: Register the .XML Handler in IIS6&lt;/h2&gt;  &lt;p&gt;If you’re running II6, you may need to direct all .xml files (or all files) to the ASP.NET engine for handling.&lt;/p&gt;  &lt;p&gt;1) From the IIS6 manager, right click the site and choose Properties.&lt;/p&gt;  &lt;p&gt;2) Choose the Home Directory tab, and click Configuration:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cp5nOwEI/AAAAAAAAAOA/xtK1bvMRp3c/s1600-h/image%5B26%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cqMTptII/AAAAAAAAAOE/qhSDoqUVCN8/image_thumb%5B12%5D.png?imgmax=800" width="317" height="166" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;3a) (For just .XML files) Add a .xml handler to point to ASP.NET by clicking the Add button:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cqRGbZFI/AAAAAAAAAOI/9BS7_grryPc/s1600-h/image%5B30%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cqjArCVI/AAAAAAAAAOM/kFe6bhW5-9c/image_thumb%5B14%5D.png?imgmax=800" width="386" height="229" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Then add a .xml extension pointing to the aspnet_isapi.dll file (you can copy and paste the path from the .aspx entry in the list):&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cq1PJdMI/AAAAAAAAAOQ/jm15vJZAI7c/s1600-h/image%5B34%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4crNGQO4I/AAAAAAAAAOU/szslxA9k5r0/image_thumb%5B16%5D.png?imgmax=800" width="388" height="233" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;3b) (For all files) Add a wildcard handler by clicking Insert:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/Sl4crT-p1WI/AAAAAAAAAOY/OeRI-9CDd10/s1600-h/image%5B38%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4crg-r8QI/AAAAAAAAAOc/Buxy424rn8Y/image_thumb%5B18%5D.png?imgmax=800" width="395" height="168" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And paste in the same aspnet_isapi.dll path:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/Sl4cr3yDkOI/AAAAAAAAAOg/oPwo4tYIYCY/s1600-h/image%5B43%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/Sl4cr3dtqqI/AAAAAAAAAOk/rF_EQBJGCcE/image_thumb%5B21%5D.png?imgmax=800" width="389" height="132" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;If you’re using ASP.NET Routing, you may wish to uncheck Verify that File Exists. It’ll help you out later!&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;Conclusion&lt;/h2&gt;  &lt;p&gt;That’s it! Now you should be able to navigate to the same ASPX file but with the .xml file extension and it should work. If not, contact me or let me know in the comments.&lt;/p&gt;  &lt;p&gt;Hope this helps!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-5723584945823701688?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FkJwtIP1XpfoSpM40QcCuWBtPd0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FkJwtIP1XpfoSpM40QcCuWBtPd0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FkJwtIP1XpfoSpM40QcCuWBtPd0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FkJwtIP1XpfoSpM40QcCuWBtPd0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/5723584945823701688/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=5723584945823701688" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/5723584945823701688?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/5723584945823701688?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/07/aspnet-serving-aspx-files-as-xml-or.html" title="ASP.NET: Serving ASPX files as .XML (or .HTML, etc.)" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/_xvXvGivrKF0/Sl4cnTQQQLI/AAAAAAAAANU/2Z5QAMZiD1U/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DUYDQnw-cSp7ImA9WxJVEkQ.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-1167371780135652691</id><published>2009-06-29T13:39:00.001-04:00</published><updated>2009-06-29T13:39:33.259-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-29T13:39:33.259-04:00</app:edited><title>ASP.NET: Moving Session Out-of-Process with StateServer</title><content type="html">&lt;p&gt;I recently ran into an issue with the ASP.NET SessionState. It isn’t a fault of the SessionState itself, but likely an issue with my configuration or uses. Essentially the state was being reset too often. Although I had a timeout value of 1440 minutes, users were getting kicked out after 10-15 minutes. I eventually found out that (for some reason) the IIS worker process was being reset (although it wasn’t configured to self-reset), probably due to an unrecoverable error in some of our legacy-based code. And since our SessionState was set to InProc, all of the session data was stored in-the-process and was thus lost whenever it died.&lt;/p&gt;  &lt;p&gt;I started researching the alternatives and discovered the proper way to configure the StateServer that comes with ASP.NET to move your sessions out-of-process. This way, you can literally reset IIS (or if the StateServer is on another machine, reboot your IIS server machine) without losing session. This seemed like a very appealing situation, and one that many people online endorse as best practice.&lt;/p&gt;  &lt;p&gt;Another benefit of moving the SessionState out-of-process is that you set yourself up nicely for eventually moving to multiple web servers, or even running simultaneous multiple instances of your application pools on the same machine to boost performance. &lt;/p&gt;  &lt;p&gt;The only downside (and yes, there’s always a catch) is that out-of-process state does not give as good performance as InProc does. However, from my initial testing, I haven’t found any significant, noticeable difference after the session is initialized. Another catch, which I’ll discuss later, is that all data that goes into an out-of-process session must be serializable and flagged as such with the SerializableAttribute.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Introduction&lt;/h2&gt;  &lt;p&gt;Let’s start from the top. The SessionState is a collection of data that is persisted across multiple web requests to ASP.NET. This can be authentication information, a shopping cart, a theme, or whatnot – essentially any information that you want the server to remember for the next time the user “does something” on your site. This can also be accomplished on the page level with ViewState, but that sends more data back and forth between the client and your server.&lt;/p&gt;  &lt;p&gt;If you’re using the cookie method of “tagging” your SessionState (which you should, because &lt;a href="http://www.developerfusion.com/article/6678/top-10-application-security-vulnerabilities-in-webconfig-files-part-one/6/" target="_blank"&gt;cookieless is vulnerable to session hijacking&lt;/a&gt;), you’ll have a tiny little harmless cookie called ASP.NET_SessionId which contains a unique session ID that looks something like “okeiohntcofecw55svocxwiz”. This ID is sent to the web server to let the server know which session to retrieve.&lt;/p&gt;  &lt;p&gt;If the SessionState is running InProc, all ASP.NET has to do is look at the memory it has of that session information and retrieve or set the values required. However, if that process gets reset (due to an IIS reset, power outage, reboot, failed process, etc) then it no longer has a record of that session information, so that SessionId is no longer valid and the user is “kicked off”.&lt;/p&gt;  &lt;p&gt;Additionally, if you increase the number of worker processes per application pool, thinking you’ll be getting better performance on a multiprocessor server, you’ll find that the users continually get kicked off, because each process doesn’t know about the session state of the other so they continually reset the session on each other. This is the same problem you’ll encounter if you try to move to two load-balanced web servers.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;The StateServer Solution&lt;/h2&gt;  &lt;p&gt;Included with .NET is a Windows service called the ASP.NET State Service. This is disabled by default, so if you’re reading this far you may not know about it. This service runs as an additional process so that if the IIS worker process gets reset, the state service is still running with all the session information. &lt;/p&gt;  &lt;p&gt;You can even run this State Service on another Windows Server machine. This way, you can have one machine managing your session state, while you can have one or more web servers handling requests. An example situation might look something like this:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/Skj8UlgN_CI/AAAAAAAAANA/8asj91aVN5c/s1600-h/StateServer%5B4%5D.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="StateServer" border="0" alt="StateServer" src="http://lh3.ggpht.com/_xvXvGivrKF0/Skj8U1PTCsI/AAAAAAAAANE/fhu4NR4jISQ/StateServer_thumb%5B2%5D.jpg?imgmax=800" width="384" height="249" /&gt;&lt;/a&gt;     &lt;br /&gt;    &lt;br /&gt;(I was trying to find a shape to use for the StateServer to differentiate it from the others… and I chose the “eCommerce Server” shape. As in cash = cache… get it?)&lt;/p&gt;  &lt;p&gt;Even though that might be what a more advanced operation might look like, you will likely (such as in development or for a small-load web server) run the StateServer on the same machine as IIS.&lt;/p&gt;  &lt;p&gt;Keep in mind that the SessionState is still being stored in memory with the StateServer solution… there’s no persisting of the state to disk. So if the StateServer process gets restarted or rebooted, so does your session information.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;The SQL Server Solution&lt;/h2&gt;  &lt;p&gt;Another solution supported natively by ASP.NET is to use SQL Server to persist state information to disk. This way, even the server handling your state can be rebooted without losing session. This may be the preferred way of doing things for very high-end operations or situations where you need to maintain that information for security or contractual purposes. However, I will not be discussing that here, because I haven’t tried it myself. There’s many resources to learn about this on the web, such as &lt;a href="http://support.microsoft.com/kb/317604" target="_blank"&gt;this article from Microsoft&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Enabling StateServer&lt;/h2&gt;  &lt;p&gt;To enable the ASP.NET State Service, all you have to do is configure the service on both your development and production machines. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Click Start / Run or type Win + R.&lt;/li&gt;    &lt;li&gt;Type in &lt;strong&gt;services.msc&lt;/strong&gt; and press Enter or click OK.&lt;/li&gt;    &lt;li&gt;Locate the &lt;strong&gt;ASP.NET State Service&lt;/strong&gt; in the Services (local) list.&lt;/li&gt;    &lt;li&gt;Right click on it and choose &lt;strong&gt;Properties&lt;/strong&gt;.&lt;/li&gt;    &lt;li&gt;Change the Startup Type to &lt;strong&gt;Automatic&lt;/strong&gt; so that it starts on boot.&lt;/li&gt;    &lt;li&gt;Click the &lt;strong&gt;Start&lt;/strong&gt; button to get it started now.&lt;/li&gt;    &lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt; to close the dialog.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now, if you pull up Task Manager, you’ll notice a nice little aspnet_state.exe process running in addition to the IIS worker process (w3wp.exe). This process is the new StateServer that will maintain all your state data. But in order to use it, we must enable your ASP.NET web site to use the out-of-process StateServer.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Modifying your Web.Config&lt;/h2&gt;  &lt;p&gt;For the site that you’d like to have use the out-of-process StateServer, first open your web.config file for that site.&lt;/p&gt;  &lt;p&gt;Locate (or add) a sessionState element in the system.web section of the config file, like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/Skj8U-HZq2I/AAAAAAAAANI/ZSfoR2RpRtA/s1600-h/image%5B10%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/Skj8VClZWfI/AAAAAAAAANM/RjUQbqWFhZE/image_thumb%5B8%5D.png?imgmax=800" width="439" height="50" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Note the &lt;strong&gt;cookieless=”UseCookies” &lt;/strong&gt;and &lt;strong&gt;mode=”StateServer”&lt;/strong&gt; attributes. These are required to use the StateServer in a cookie’d fashion.&lt;/p&gt;  &lt;p&gt;The timeout attribute is the time, in minutes, that you want the session to remain valid.&lt;/p&gt;  &lt;p&gt;Also note that this example above is for &lt;em&gt;the StateServer running on the same machine as IIS.&lt;strong&gt; &lt;/strong&gt;&lt;/em&gt;With no connection string specified, it looks for a StateServer running on the local machine. If you need to move the StateServer onto another machine, you must match up your MachineKeys and set a StateServer connection string for IIS to connect to. Google is your friend.&lt;/p&gt;  &lt;p&gt;Now, your site should be using the StateServer for all of its session data. You may (or may not, but it might be a good idea) need to restart IIS for this to be optimally configured.&lt;/p&gt;  &lt;h2&gt;Non-Serializable Session Data&lt;/h2&gt;  &lt;p&gt;The only caveat in this post, and it’s a &lt;strong&gt;big one&lt;/strong&gt;, is that you will receive an error if you try to store non-Serializable data into the session now that you have an out-of-process state (i.e. a System.Data.DataView). Serializable classes are those that have the Serializable attribute set and are optimized for serialization (i.e. a System.Data.DataTable). &lt;/p&gt;  &lt;p&gt;You will need to review and test your code (or write new code accordingly) to make sure that you are not storing non-Serializable data to your session when using out-of-process state. If you are using custom classes to store session data, review them for serializable members and properties, and then mark them as serializable.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx" target="_blank"&gt;Read more about the SerializableAttribute at MSDN here&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;Final Thoughts&lt;/h2&gt;  &lt;p&gt;I’ve seen developers proclaim online that all ASP.NET devs should design their applications around an out-of-process session model, and now that I’ve discovered it, I am inclined to agree. If you design from the beginning to be compatible with a StateServer or SQL database state server, you can easily make the jump from one web server to two.&lt;/p&gt;  &lt;p&gt;A few things to think about are the amount of memory available to the state service, latency and the connection between servers if the StateService is running on another machine, and how to minimize state since it’s now being transferred between processes.&lt;/p&gt;  &lt;p&gt;What are your experiences with out-of-process state, and do you have any advice for others?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-1167371780135652691?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/B0bMLduRwN4Vpv4V5PQRVVI7s3E/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B0bMLduRwN4Vpv4V5PQRVVI7s3E/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/B0bMLduRwN4Vpv4V5PQRVVI7s3E/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/B0bMLduRwN4Vpv4V5PQRVVI7s3E/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/1167371780135652691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=1167371780135652691" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/1167371780135652691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/1167371780135652691?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/06/aspnet-moving-session-out-of-process.html" title="ASP.NET: Moving Session Out-of-Process with StateServer" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_xvXvGivrKF0/Skj8U1PTCsI/AAAAAAAAANE/fhu4NR4jISQ/s72-c/StateServer_thumb%5B2%5D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUcNR34zcSp7ImA9WxJWGUg.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-7969055167076207698</id><published>2009-06-25T15:07:00.003-04:00</published><updated>2009-06-25T15:11:36.089-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-25T15:11:36.089-04:00</app:edited><title>SQL Server 2008: Importing TIGER/Line Spatial GIS Data</title><content type="html">&lt;p&gt;If you’ve been itching to use the spatial data and query features of SQL Server 2008 but haven’t figured out a way to get data to use, you’re in the same boat I was. Until today.&lt;/p&gt;  &lt;p&gt;I have a whole slew of address information, but no way to convert that into latitude/longitude values to do any meaningful spatial querying – I was pretty much limited to Zip Code statistics only. Then I remembered that the US Census Bureau puts out a freely available database of everything from roads to highways to railways to geological and political borders with their coordinates called TIGER/Line. Since 2007, the TIGER/Line data has been in the Shapefile format, which makes it easier to use, although it is a binary file.&lt;/p&gt;  &lt;p&gt;It would be quite a bit of effort to try and parse the TIGER/Line data yourself, so the use of a utility greatly helps here. Download &lt;a href="http://www.sharpgis.net/page/SQL-Server-2008-Spatial-Tools.aspx" target="_blank"&gt;SQL Server 2008 Spatial Tools&lt;/a&gt; to follow along with this blog post, although Microsoft has a sponsored project on Codeplex which I haven’t used called &lt;a href="http://www.codeplex.com/sqlspatialtools" target="_blank"&gt;SQL Server Spatial Tools&lt;/a&gt; as well.&lt;/p&gt;  &lt;h2&gt;Step 1: Download the TIGER/Line Data&lt;/h2&gt;  &lt;p&gt;To start with, you’ll need to visit the &lt;a href="http://www2.census.gov/cgi-bin/shapefiles/national-files" target="_blank"&gt;TIGER/Line download site&lt;/a&gt;. From there, since you’ll likely want to start with just a small dataset of information (which is still relatively large), just download the files for your county. In my case, I chose Florida from the right-hand side, and then Polk County from the next page. On the county page, you’ll want to download the &lt;strong&gt;All Lines&lt;/strong&gt; package.&lt;/p&gt;  &lt;p&gt;This is a Zip file with a few files inside. The only one you’re concerned with is the one with the file extension of &lt;strong&gt;.shp&lt;/strong&gt; – this is the Shapefile format file that we can import with the SQL Server 2008 Spatial Tools into SQL Server. Extract this file somewhere on your hard drive. The only other file you may be interested in is the &lt;span style="font-weight: bold;"&gt;.shp.xml&lt;/span&gt; file -- this contains all the descriptions of the columns, which may be a bit cryptic for your tastes.&lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Do note that this, even though it’s just at the county level, contains a lot of information. Polk County’s file, for example, is 18.8 MB and contains over 100,000 rows of information. One thing you can do after the information is imported is blow away rows you don’t need (such as railways, geographical/political boundaries, etc.), but you may need all of it. Also there’s extra columns you may not need that, using the utility, you can choose not to import. After importing, my dataset took up over 35 MB in the database.&lt;/p&gt;  &lt;h2&gt;Step 2: Import the Data&lt;/h2&gt;  &lt;p&gt;Extract the SQL Server 2008 Spatial Tools from the zip file and run the &lt;strong&gt;Shape2Sql.exe&lt;/strong&gt; program. After putting in your SQL Server connection information, it looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SkPK285WQ6I/AAAAAAAAAMY/VxrEpigpgr0/s1600-h/image%5B3%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh3.ggpht.com/_xvXvGivrKF0/SkPK3OVbFuI/AAAAAAAAAMc/8lFTRrTDj90/image_thumb%5B1%5D.png?imgmax=800" width="401" border="0" height="356" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In the top box (by using the ellipsis button to the right), choose the .shp file that was extracted from the TIGER/Line Zip file.&lt;/p&gt;  &lt;p&gt;Now you’ll want to change the radio button from Planar Geometry to &lt;strong&gt;Geography (Spheric)&lt;/strong&gt;. This will allow you to query using lat/long values. I’m not sure how it would work with geometry in this example, anyways.&lt;/p&gt;  &lt;p&gt;Check the box beside &lt;strong&gt;Set SRID&lt;/strong&gt; and leave the value as &lt;strong&gt;4326.&lt;/strong&gt; Change the &lt;strong&gt;Table Name&lt;/strong&gt; field to give it a friendly name as you would want it in your database – if this table doesn’t exist, the utility will create it for you.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Advanced users:&lt;/strong&gt; if you’ve done this before, you will probably want to uncheck any columns on the right-side that you know you don’t need. However, if this is your first time, you’ll probably want to see all the data to see if you need to use it in your application.&lt;/p&gt;  &lt;p&gt;When done, click &lt;strong&gt;Upload to Database&lt;/strong&gt; and wait. For 102,000 rows, it took about 20 minutes from my machine.&lt;/p&gt;  &lt;h2&gt;Step 3: Query Data&lt;/h2&gt;  &lt;p&gt;Now that you’ve got the TIGER/Line data in your database, you can now query the data. The utility above created a column called “geom” on the table which is the SQL Geography data type.&lt;/p&gt;  &lt;p&gt;Doing a simple query of &lt;strong&gt;SELECT TOP 5000 * FROM TigerLine_Data WHERE FEATCAT=’S’;&lt;/strong&gt; returns the top 5000 results that are roads (“FEATCAT=’S’”). Here’s how the results look in SQL Server Management Studio 2008:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SkPK3k_A6mI/AAAAAAAAAMg/cP4-zlb4GvA/s1600-h/image%5B7%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SkPK30ON71I/AAAAAAAAAMk/8c7bI5KV47A/image_thumb%5B3%5D.png?imgmax=800" width="549" border="0" height="233" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice that since there’s a geography column returned, there’s now a “Spatial Results” tab. Here’s how it looks with these results:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SkPK4FGEj1I/AAAAAAAAAMo/ddv-0rGmyRs/s1600-h/image%5B11%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SkPK4UC9aAI/AAAAAAAAAMs/UK9IA51_BL8/image_thumb%5B5%5D.png?imgmax=800" width="550" border="0" height="374" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;If you’re from Polk County, you notice that that’s more or less the shape of it, but it’s missing a whole lot of roads, because the Spatial Results screen can’t handle more than 5000 records. We’re off to a good start, but that just isn’t really meaningful data just yet. Let’s set the “FULLNAME” column as the label column (do that on the panel on the right side of the Spatial Results tab) and zoom into some roads:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SkPK4gi66SI/AAAAAAAAAMw/BiBBv2Iqakk/s1600-h/image%5B15%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SkPK43LbgwI/AAAAAAAAAM0/rCuksWP_jPw/image_thumb%5B7%5D.png?imgmax=800" width="542" border="0" height="355" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Now that we can see that we’ve got some data there, let’s work with the spatial querying built into SQL Server 2008. Let’s say we wanted to see all roads within 2 KM of a given lat/long. Here’s the query I’ll use:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;SELECT * FROM TigerLine_Data   &lt;br /&gt;WHERE ROADFLG='Y' AND FEATCAT='S'    &lt;br /&gt;AND geom.STDistance(geography::STGeomFromText('POINT(-81.889472 28.009785)', 4326)) / 1000 &amp;lt; 2.0;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Notice the interesting syntax. We’re saying, in the last part of the where clause, that we want the distance between the value in the “geom” column and a given value, calculated from a POINT with a long/lat pair. (Note the order.) The STDistance function returns the distance, in meters, between the two points. So we divide that by 1000 and compare it less than 2.0 km.&lt;/p&gt;  &lt;p&gt;Here’s our results:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SkPK5PEQppI/AAAAAAAAAM4/HrpVdJ5vK9A/s1600-h/image%5B19%5D.png"&gt;&lt;img style="border: 0px none ; display: inline;" title="image" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SkPK5HLEsuI/AAAAAAAAAM8/7pSicltGstw/image_thumb%5B9%5D.png?imgmax=800" width="535" border="0" height="295" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Finally we can see what we’re working with! It’s not the prettiest thing in the world, but it helps you quickly visualize the spatial results of your query.&lt;/p&gt;  &lt;p&gt;Using functions like STDistance, you could do things such as finding all customers within a range of a certain latitude/longitude point, which I hope to explore in a future blog post. But once you overcome getting data into your system, it’s just SQL queries from here on out.&lt;/p&gt;&lt;p&gt;Oh, and did I mention that this is all &lt;span style="font-weight: bold;"&gt;free?&lt;/span&gt; :-)&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-7969055167076207698?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/qZ7XfvNSncJh99NGnHyNjBoBgi4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qZ7XfvNSncJh99NGnHyNjBoBgi4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/qZ7XfvNSncJh99NGnHyNjBoBgi4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/qZ7XfvNSncJh99NGnHyNjBoBgi4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/7969055167076207698/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=7969055167076207698" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/7969055167076207698?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/7969055167076207698?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/06/sql-server-2008-importing-tigerline.html" title="SQL Server 2008: Importing TIGER/Line Spatial GIS Data" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_xvXvGivrKF0/SkPK3OVbFuI/AAAAAAAAAMc/8lFTRrTDj90/s72-c/image_thumb%5B1%5D.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;CEMESHk-eip7ImA9WxJQE0Q.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-9105482548443190481</id><published>2009-05-26T22:43:00.002-04:00</published><updated>2009-05-26T22:46:49.752-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-26T22:46:49.752-04:00</app:edited><title>Lakeland .NET Users Group - I'm Speaking!</title><content type="html">Next month at the Lakeland .NET Users Group I'll be speaking on jQuery with ASP.NET. I'm covering everything from the barebones basics (assuming you know how to "alert" in JavaScript and what a function is) to animations, advanced selectors, working with server-side controls, and extending jQuery... along with a bunch of real-world examples.&lt;br /&gt;&lt;br /&gt;I'll have more details soon, but for now check out the Lakeland .NET Users Group site:&lt;br /&gt;&lt;a href="http://www.lakelandug.net"&gt;www.lakelandug.net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-9105482548443190481?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DojqdEVkIfjttwJPZAhBQP68RDk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DojqdEVkIfjttwJPZAhBQP68RDk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DojqdEVkIfjttwJPZAhBQP68RDk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DojqdEVkIfjttwJPZAhBQP68RDk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/9105482548443190481/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=9105482548443190481" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/9105482548443190481?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/9105482548443190481?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/05/lakeland-net-users-group-im-speaking.html" title="Lakeland .NET Users Group - I'm Speaking!" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMMSXs_eCp7ImA9WxJSEE8.&quot;"><id>tag:blogger.com,1999:blog-7087580115748722533.post-8209684476760689144</id><published>2009-04-29T13:01:00.001-04:00</published><updated>2009-04-29T13:01:28.540-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-29T13:01:28.540-04:00</app:edited><title>.NET: Getting HTTP Headers</title><content type="html">&lt;p&gt;As part of the Silverlight application I’m working on, I want to reduce our bandwidth requirements as well as give the users the option of having a faster experience by offering to cache the images locally on the user’s Isolated Storage. However, with Silverlight you only get 1 MB of Isolated Storage when online in-the-browser, and with Silverlight 3 you get 25 MB out-of-browser, but I need more than that. The problem is I didn’t want to download each file first to figure out how much space I needed to request from the Isolated Storage mechanism (because you have to specifically ask to increase the quota to a certain size, and then the user must accept it in a dialog).&lt;/p&gt;  &lt;p&gt;So HTTP headers come to the rescue. Using the HEAD command, I can get something that looks like the following from each of the images I know I need to cache, without having to download the whole thing:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/_xvXvGivrKF0/SfiH22R-MXI/AAAAAAAAAJs/RVuJKByVtNE/s1600-h/image%5B4%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/_xvXvGivrKF0/SfiH3T0EqOI/AAAAAAAAAJw/_zwjNYpP6YY/image_thumb%5B2%5D.png?imgmax=800" width="508" height="402" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice the Content-Length: 26529. That’s the size, in bytes, of that file. And also notice that there’s no data returned after the headers. That means that this request will go VERY fast, and I can blow through them all very quickly. Note that this is also useful for finding the last modified date, which I will be using to determine if the locally cached file is out of date.&lt;/p&gt;  &lt;p&gt;cURL gives a good interface for calling the HTTP HEAD verb, all you have to do is add the “--head” argument. But how do we do this in .NET?&lt;/p&gt;  &lt;p&gt;Answer: use System.Net.HttpWebRequest!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SfiH3vVOS7I/AAAAAAAAAJ0/46lx6Q0fhn8/s1600-h/image%5B8%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SfiH3xNBkeI/AAAAAAAAAJ4/9x_gBxlGtd4/image_thumb%5B4%5D.png?imgmax=800" width="512" height="268" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Notice line 8: here we’re telling the request object to use the HEAD verb so that no data is returned. Then, we call request.GetResponse to get the response, and the ContentLength is a property on that returned WebResponse object. Pretty easy! The output is:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SfiH4J72kHI/AAAAAAAAAJ8/3569mPjFSfU/s1600-h/image%5B12%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/_xvXvGivrKF0/SfiH4T2TvLI/AAAAAAAAAKA/aq_gbgBCzEk/image_thumb%5B6%5D.png?imgmax=800" width="523" height="274" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;And we see that the values match, of course. Make sure you put that request.Method = “HEAD” line in there. Other examples on the web left out that line, and so it was actually doing a full request.&lt;/p&gt;  &lt;p&gt;If you notice above, I didn’t give a type for the request and response objects. Even though I called &lt;strong&gt;HttpWebRequest&lt;/strong&gt;.Create(), it returns a WebRequest object. Although that works for getting the content length, there’s a bunch more you can do with the HttpWebRequest and HttpWebResponse objects. Let’s try the caching concept I mentioned earlier.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_xvXvGivrKF0/SfiH4qFaOKI/AAAAAAAAAKE/demzFRca5uk/s1600-h/image%5B16%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SfiH44EIGMI/AAAAAAAAAKI/yoz_9pfYnq8/image_thumb%5B8%5D.png?imgmax=800" width="547" height="488" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Using the HTTP Header of If-Modified-Since, we can give the web server the date of our cached version, and if it hasn’t changed since then, it returns an HTTP 304 Not Modified status code. If it has changed, it returns HTTP 200 OK. The HttpWebRequest actually throws a WebException if it gets a 304 code back, so we have to catch it.&lt;/p&gt;  &lt;p&gt;First, in the above code, we’re setting the HttpWebRequest.IfModifiedSince property to 1/1/2008. (The file was modified in 2006.) Then, if it’s been modified since 1/1/2008, we print out the response status code and description, as well as the content length and last-modified date. If it returns 304, it throws a WebException, but in the ex.Response property we can access the status code and description and other headers. So here’s what this example returns:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/_xvXvGivrKF0/SfiH5EGrX2I/AAAAAAAAAKM/TlJbV_uGUe8/s1600-h/image%5B20%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SfiH5c4iC1I/AAAAAAAAAKU/8Fgwm_r6Or0/image_thumb%5B10%5D.png?imgmax=800" width="523" height="276" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So now we know that we do not need to get the data, because it hasn’t been modified since our request date. But let’s move that request.IfModifiedSince date back to 2005 and see what happens.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/_xvXvGivrKF0/SfiH5gXg9gI/AAAAAAAAAKY/TyLSa5-GgU4/s1600-h/image%5B24%5D.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/_xvXvGivrKF0/SfiH5zWYgQI/AAAAAAAAAKc/uH5HrIsNuYo/image_thumb%5B12%5D.png?imgmax=800" width="533" height="283" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;So you can see that the file was modified in 2006, after our request date of 2005, so we should get the data.&lt;/p&gt;  &lt;p&gt;Note that if you’re strictly doing a cache-update scenario and you don’t need to pay attention to the file size, you don’t have to just do a HEAD request. You could do a full GET and have the data returned if it has been modified, and if it hasn’t, it’ll throw a 304 Not Modified without any data.&lt;/p&gt;  &lt;p&gt;Now, I’m not sure if the whole HttpWebRequest and HttpWebResponse API is available in Silverlight yet, but this at least gets me started.&lt;/p&gt;  &lt;p&gt;Hope this helps!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7087580115748722533-8209684476760689144?l=adventuresdotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AwKFdumY4PW_2BnGR1pLV6xikuM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AwKFdumY4PW_2BnGR1pLV6xikuM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AwKFdumY4PW_2BnGR1pLV6xikuM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AwKFdumY4PW_2BnGR1pLV6xikuM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://adventuresdotnet.blogspot.com/feeds/8209684476760689144/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7087580115748722533&amp;postID=8209684476760689144" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8209684476760689144?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7087580115748722533/posts/default/8209684476760689144?v=2" /><link rel="alternate" type="text/html" href="http://adventuresdotnet.blogspot.com/2009/04/net-getting-http-headers.html" title=".NET: Getting HTTP Headers" /><author><name>Paul</name><uri>http://www.blogger.com/profile/14607788470326553720</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_xvXvGivrKF0/SfiH3T0EqOI/AAAAAAAAAJw/_zwjNYpP6YY/s72-c/image_thumb%5B2%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total></entry></feed>

