<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">

<channel>
	<title>mhinze.com</title>
	<atom:link href="http://mhinze.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mhinze.com</link>
	<description>Matt Hinze's web log</description>
	<pubDate>Thu, 17 Jul 2008 16:31:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>First impressions of RenderAction in MVC Preview 4</title>
		<link>http://mhinze.com/first-impressions-of-renderaction-in-mvc-preview-4/</link>
		<comments>http://mhinze.com/first-impressions-of-renderaction-in-mvc-preview-4/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 12:50:04 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[ASP.NET MVC]]></category>

		<category><![CDATA[asp.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=48</guid>
		<description><![CDATA[After reviewing Rob Conery&#039;s post, a few notes:

Syntax (no &#60;%=):

&#60;% Html.RenderAction&#60;PersonComponentController&#62;(c=&#62;c.List()); %&#62;

The component does not share ViewData with the er, &#034;calling view&#034;..
You can use a View User Control (ascx) or a View Page (aspx).
By default the component is browsable. You can turn this off using IgnoreRoute:

routes.IgnoreRoute("PersonComponent/{action}");


On the implicit MVC violations, Phil says: 


My personal opinion [...]]]></description>
			<content:encoded><![CDATA[<p>After reviewing Rob Conery&#039;s <a href="http://blog.wekeroad.com/blog/asp-net-mvc-preview-4-componentcontroller-is-now-renderaction/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://blog.wekeroad.com/blog/asp-net-mvc-preview-4-componentcontroller-is-now-renderaction/');">post</a>, a few notes:</p>
<ul>
<li>Syntax (no &lt;%=):</li>
</ul>
<pre class="code"><span style="background: #ffee62">&lt;%</span> Html.RenderAction&lt;<span style="color: #2b91af">PersonComponentController</span>&gt;(c=&gt;c.List()); <span style="background: #ffee62">%&gt;</span></pre>
<ul>
<li>The component does not share ViewData with the er, &#034;calling view&#034;..<br/></li>
<li>You can use a View User Control (ascx) or a View Page (aspx).<br/></li>
<li>By default the component is browsable. You can turn this off using IgnoreRoute:</li>
</ul>
<pre class="code">routes.IgnoreRoute(<span style="color: #a31515">"PersonComponent/{action}"</span>);</pre>
<p><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a></p>
<ul>
<li>On the implicit MVC violations, <a href="http://haacked.com/archive/2008/07/16/aspnetmvc-codeplex-preview4.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://haacked.com/archive/2008/07/16/aspnetmvc-codeplex-preview4.aspx');">Phil says</a>: </li>
</ul>
<blockquote>
<p>My personal opinion is that this violates the separation of concerns so important to the MVC pattern. Having a method within your view calling back into a controller in order to render out a bit more view makes me feel a wee bit dirty ;). We’re developing prototypes for an alternative approach. In the meanwhile, I recognize that for a small sacrifice of pattern purity, this method is very useful, hence its inclusion in the MVC Futures assembly, but do understand that you use it at your own risk.</p>
</blockquote>
<p>Yeah, and these components need route data and other stuff from the view. It will be interesting to see what they come up with so that I can just drag in my UberGrid and forget about all this coding.&nbsp; (kidding!)&nbsp; </p>
<p>For now, this works and it&#039;s testable.</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/first-impressions-of-renderaction-in-mvc-preview-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Testing TempData in ASP.NET MVC Preview 4</title>
		<link>http://mhinze.com/testing-tempdata-in-aspnet-mvc-preview-4/</link>
		<comments>http://mhinze.com/testing-tempdata-in-aspnet-mvc-preview-4/#comments</comments>
		<pubDate>Thu, 17 Jul 2008 01:08:44 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[ASP.NET MVC]]></category>

		<category><![CDATA[asp.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[tdd]]></category>

		<category><![CDATA[tempdata]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=47</guid>
		<description><![CDATA[Eilon was correct - they made it easier!
It&#039;s trivial to test TempData now. This is all that&#039;s needed to port the example from his earlier post to Preview 4 (thanks Ben):
[TestFixture]
public class HomeControllerTests
{
    [Test]
    public void IndexSavesUserIDToTempDataAndRedirects()
    {
        var [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx');">Eilon</a> was correct - they made it easier!</p>
<p>It&#039;s trivial to test TempData now. This is all that&#039;s needed to port the example from his <a href="http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://weblogs.asp.net/leftslipper/archive/2008/04/13/mvc-unit-testing-controller-actions-that-use-tempdata.aspx');">earlier post</a> to Preview 4 (thanks <a href="http://flux88.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://flux88.com/');">Ben</a>):</p>
<pre class="code">[<span style="color: #2b91af">TestFixture</span>]
<span style="color: blue">public class </span><span style="color: #2b91af">HomeControllerTests
</span>{
    [<span style="color: #2b91af">Test</span>]
    <span style="color: blue">public void </span>IndexSavesUserIDToTempDataAndRedirects()
    {
        <span style="color: blue">var </span>homeController = <span style="color: blue">new </span><span style="color: #2b91af">HomeController</span>();
        homeController.TempData = <span style="color: blue">new </span><span style="color: #2b91af">TempDataDictionary</span>();

        <span style="color: blue">var </span>result = homeController.Index();

        <span style="color: #2b91af">Assert</span>.That(result.Values.ContainsKey(<span style="color: #a31515">"action"</span>));
        <span style="color: #2b91af">Assert</span>.That(result.Values[<span style="color: #a31515">"action"</span>], <span style="color: #2b91af">Is</span>.EqualTo(<span style="color: #a31515">"GreetUser"</span>));
        <span style="color: #2b91af">Assert</span>.That(homeController.TempData.ContainsKey(<span style="color: #a31515">"UserID"</span>));
        <span style="color: #2b91af">Assert</span>.That(homeController.TempData[<span style="color: #a31515">"UserID"</span>], <span style="color: #2b91af">Is</span>.EqualTo(<span style="color: #a31515">"user123"</span>));
    }

    [<span style="color: #2b91af">Test</span>]
    <span style="color: blue">public void </span>GreetUserWithNoUserIDRedirects()
    {
        <span style="color: blue">var </span>homeController = <span style="color: blue">new </span><span style="color: #2b91af">HomeController</span>();
        homeController.TempData = <span style="color: blue">new </span><span style="color: #2b91af">TempDataDictionary</span>();

        <span style="color: blue">var </span>result = homeController.GreetUser() <span style="color: blue">as </span><span style="color: #2b91af">RedirectToRouteResult</span>;

        <span style="color: #2b91af">Assert</span>.That(result, <span style="color: #2b91af">Is</span>.Not.Null);
        <span style="color: #2b91af">Assert</span>.That(result.Values.ContainsKey(<span style="color: #a31515">"action"</span>));
        <span style="color: #2b91af">Assert</span>.That(result.Values[<span style="color: #a31515">"action"</span>], <span style="color: #2b91af">Is</span>.EqualTo(<span style="color: #a31515">"ErrorPage"</span>));
        <span style="color: #2b91af">Assert</span>.That(homeController.TempData, <span style="color: #2b91af">Is</span>.Empty);
    }

    [<span style="color: #2b91af">Test</span>]
    <span style="color: blue">public void </span>GreetUserWithUserIDCopiesToViewDataAndRenders()
    {
        <span style="color: blue">var </span>homeController = <span style="color: blue">new </span><span style="color: #2b91af">HomeController</span>();
        homeController.TempData = <span style="color: blue">new </span><span style="color: #2b91af">TempDataDictionary</span>();

        homeController.TempData[<span style="color: #a31515">"UserID"</span>] = <span style="color: #a31515">"TestUserID"</span>;

        <span style="color: blue">var </span>result = homeController.GreetUser() <span style="color: blue">as </span><span style="color: #2b91af">ViewResult</span>;

        <span style="color: #2b91af">Assert</span>.That(result, <span style="color: #2b91af">Is</span>.Not.Null);
        <span style="color: #2b91af">Assert</span>.That(result.ViewName, <span style="color: #2b91af">Is</span>.EqualTo(<span style="color: #a31515">"GreetUser"</span>));
        <span style="color: #2b91af">Assert</span>.That(result.ViewData, <span style="color: #2b91af">Is</span>.Not.Null);
        <span style="color: #2b91af">Assert</span>.That(result.ViewData.ContainsKey(<span style="color: #a31515">"NewUserID"</span>));
        <span style="color: #2b91af">Assert</span>.That(result.ViewData[<span style="color: #a31515">"NewUserID"</span>], <span style="color: #2b91af">Is</span>.EqualTo(<span style="color: #a31515">"TestUserID"</span>));
    }
}</pre>
<p>If you actually need to test TempData, you can implement a stub ITempDataProvider and set the TempDataProvider propery on the controller:</p>
<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">TestTempDataProvider </span>: <span style="color: #2b91af">ITempDataProvider
</span>{
    <span style="color: blue">public </span><span style="color: #2b91af">TempDataDictionary </span>TempDataDictionary { <span style="color: blue">get</span>; <span style="color: blue">private set</span>; }

    <span style="color: blue">public </span><span style="color: #2b91af">TempDataDictionary </span>LoadTempData()
    {
        <span style="color: blue">return </span>TempDataDictionary;
    }

    <span style="color: blue">public void </span>SaveTempData(<span style="color: #2b91af">TempDataDictionary </span>tempDataDictionary)
    {
        TempDataDictionary = tempDataDictionary;
    }
}</pre>
<p>(Edited 6/17 with the proper usage from Ben)</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/testing-tempdata-in-aspnet-mvc-preview-4/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Long delays deleting a file in Visual Studio</title>
		<link>http://mhinze.com/slow-file-delete-visual-studio/</link>
		<comments>http://mhinze.com/slow-file-delete-visual-studio/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 17:08:33 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=46</guid>
		<description><![CDATA[For months I have been suffering from long delays when I delete a file from solution explorer in Visual Studio.&#160;
Minutes&#8230; slow, dreadful minutes.&#160;&#160;
I thought it was Resharper’s fault or VisualSVN&#039;s but nay.&#160; It’s because I have a large recycle bin, which is fully scanned every time you delete a file.&#160; After I emptied the recycle [...]]]></description>
			<content:encoded><![CDATA[<p>For <em>months</em> I have been suffering from long delays when I delete a file from solution explorer in Visual Studio.&nbsp;
<p>Minutes&#8230; slow, dreadful minutes.&nbsp;&nbsp;
<p>I thought it was Resharper’s fault or VisualSVN&#039;s but nay.&nbsp; It’s because I have a large recycle bin, which is fully scanned every time you delete a file.&nbsp; After I emptied the recycle bin files deleted much faster.
<p>Via <a href="http://tech.groups.yahoo.com/group/altdotnet/message/11685" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://tech.groups.yahoo.com/group/altdotnet/message/11685');">Jeff Brown on the alt.net list</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/slow-file-delete-visual-studio/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Refactoring DRY tests with Resharper's Inline Method</title>
		<link>http://mhinze.com/refactoring-dry-tests-with-inline-method/</link>
		<comments>http://mhinze.com/refactoring-dry-tests-with-inline-method/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 15:00:53 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<category><![CDATA[dry]]></category>

		<category><![CDATA[refactoring]]></category>

		<category><![CDATA[resharper]]></category>

		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=45</guid>
		<description><![CDATA[Dan North, in a recent article about DRY tests, says:
[Tests] are the documentation narrative that will guide future programmers (including yourself when you come back to change this code in three months time and you’ve forgotten what it does). In this case, clarity of intent is found in the quality of the narrative, not necessarily [...]]]></description>
			<content:encoded><![CDATA[<p>Dan North, in a <a href="http://dannorth.net/2008/06/let-your-examples-flow" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://dannorth.net/2008/06/let-your-examples-flow');">recent article about DRY tests</a>, says:</p>
<blockquote><p>[Tests] are the documentation narrative that will guide future programmers (including yourself when you come back to change this code in three months time and you’ve forgotten what it does). In this case, clarity of intent is found in the quality of the narrative, not necessarily in minimising duplication.</p>
</blockquote>
<p>I had a painful experience with DRY tests the other day.&nbsp; The code looked something like this, but on a larger, more hideous scale:</p>
<pre class="code">[<span style="color: #2b91af">Fact</span>]
<span style="color: blue">public void </span>SomeServiceWorks()
{
    <span style="color: blue">using </span>(<span style="color: blue">var </span>service = <span style="color: blue">new </span><span style="color: #2b91af">Service</span>())
    {
        RunTest(service);
    }
}

[<span style="color: #2b91af">Fact</span>]
<span style="color: blue">public void </span>AnotherTest()
{
    <span style="color: blue">using </span>(<span style="color: blue">var </span>service = <span style="color: #2b91af">Service</span>.MyService)
    {
        CheckProps(service);
    }
}

<span style="color: blue">private static void </span>CheckProps(<span style="color: #2b91af">Service </span>service)
{
    <span style="color: #2b91af">Assert</span>.NotNull(service.OtherThing);
    RunTest(service);
}

<span style="color: blue">private static void </span>RunTest(<span style="color: #2b91af">Service </span>service)
{
    <span style="color: #2b91af">Assert</span>.NotNull(service.Something);
}</pre>
<p><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a>So while the code is not clear, it is easy to see what the author was trying to do - keep his tests DRY.&nbsp; With a lot of tests this makes it very difficult to understand exactly what is going on.</p>
<p>Resharper has a nifty <a href="http://www.jetbrains.com/resharper/features/newfeatures.html#New_Refactorings" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.jetbrains.com/resharper/features/newfeatures.html#New_Refactorings');">new refactoring</a> that lets us do an <a href="http://www.refactoring.com/catalog/inlineMethod.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.refactoring.com/catalog/inlineMethod.html');">Inline Method</a> to clarify these tests.&nbsp; Just insert at the method name and use the Ctrl-Alt-N shortcut:</p>
<p>&nbsp;</p>
<p><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="424" alt="image" src="http://mhinze.com/wp-content/uploads/2008/07/image-thumb3.png" width="659" border="0"></p>
<p>I think the resulting code is much easier to read.</p>
<pre class="code">[<span style="color: #2b91af">Fact</span>]
<span style="color: blue">public void </span>SomeServiceWorks()
{
    <span style="color: blue">using </span>(<span style="color: blue">var </span>service = <span style="color: blue">new </span><span style="color: #2b91af">Service</span>())
    {
        <span style="color: #2b91af">Assert</span>.NotNull(service.Something);
    }
}

[<span style="color: #2b91af">Fact</span>]
<span style="color: blue">public void </span>AnotherTest()
{
    <span style="color: blue">using </span>(<span style="color: blue">var </span>service = <span style="color: #2b91af">Service</span>.MyService)
    {
        <span style="color: #2b91af">Assert</span>.NotNull(service.OtherThing);
        <span style="color: #2b91af">Assert</span>.NotNull(service.Something);
    }
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/refactoring-dry-tests-with-inline-method/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Audit options with NHibernate</title>
		<link>http://mhinze.com/audit-options-with-nhibernate/</link>
		<comments>http://mhinze.com/audit-options-with-nhibernate/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 13:55:27 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<category><![CDATA[auditing]]></category>

		<category><![CDATA[ddd]]></category>

		<category><![CDATA[nhibernate]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=43</guid>
		<description><![CDATA[In this post I am talking about auditing for the business, not the technical infrastructure.&#160; As an example story, users will want to see certain fields highlighted on a grid if that field has changed in the last week, and the info about the change (who, when, what) should be a tooltip for the cell.
Database [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I am talking about auditing for the business, not the technical infrastructure.&nbsp; As an example story, users will want to see certain fields highlighted on a grid if that field has changed in the last week, and the info about the change (who, when, what) should be a tooltip for the cell.</p>
<p><strong>Database trigger</strong></p>
<ul>
<li>See Jon Galloway&#039;s post on <a href="http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://weblogs.asp.net/jgalloway/archive/2008/01/27/adding-simple-trigger-based-auditing-to-your-sql-server-database.aspx');">Auditing with SQL Server</a></li>
<li>To <a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:59412348055');">generate an audit trigger in oracle</a> you can do something similar.</li>
</ul>
<p><strong>NH Interceptor</strong> (per NH in action and the <a href="http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html_single/#manipulatingdata-interceptors" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/html_single/#manipulatingdata-interceptors');">NH docs</a>)</p>
<p><strong>NH Listener</strong> (per the <a href="http://www.hibernate.org/318.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.hibernate.org/318.html');">Hibernate docs</a>)</p>
<p><strong>Domain model</strong></p>
<p>Because auditing is a simple application of interceptors there is a lot of guidance online about that approach, and using an interceptor was my first attempt at auditing. </p>
<p>But since the concept of an audit entry is important to the application (and the users!), it makes sense to promote this concept to a domain object.&nbsp; Reporting is simple and the behavior is easier to manage.&nbsp; Create a class called AuditEntry (with supporting mapping file) and hang collections of AuditEntry from the entity. Manage this collection in regular behavior:</p>
<pre class="code"><span style="color: blue">public virtual void </span>ChangeStatus(<span style="color: #2b91af">Employee </span>employee, <span style="color: #2b91af">DateTime </span>time, <span style="color: #2b91af">OrderStatus </span>status)
{
    <span style="color: blue">if</span>(<span style="color: blue">this</span>.Status != status)
    {
        <span style="color: #2b91af">AuditEntry </span>entry = <span style="color: blue">new </span><span style="color: #2b91af">AuditEntry</span>(employee, time, <span style="color: blue">this</span>.Status, status);
        _auditEntries.Add(entry);
    }
    Status = status;
}</pre>
<p><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a></p>
<p>After having gone down the database trigger path and the interceptor path and encountering friction I now recommend the domain model approach.</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/audit-options-with-nhibernate/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My boss' boss' boss</title>
		<link>http://mhinze.com/my-boss-boss-boss/</link>
		<comments>http://mhinze.com/my-boss-boss-boss/#comments</comments>
		<pubDate>Thu, 10 Jul 2008 01:54:03 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Deep thoughts]]></category>

		<category><![CDATA[business]]></category>

		<category><![CDATA[culture]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=42</guid>
		<description><![CDATA[I had a one on one meeting with my boss&#039; boss&#039; boss today.&#160; In the organizational chart he is a direct report to the CIO.&#160; He was meeting with everyone reporting to our director to assess the state of our transition after a merger.
As a disclaimer, this is a 55k employee, $11 bil. company.
He said [...]]]></description>
			<content:encoded><![CDATA[<p>I had a one on one meeting with my boss&#039; boss&#039; boss today.&nbsp; In the organizational chart he is a direct report to the CIO.&nbsp; He was meeting with everyone reporting to our director to assess the state of our transition after a merger.</p>
<p>As a disclaimer, this is a 55k employee, $11 bil. company.</p>
<p>He said he wanted to organize &#034;communities of practice&#034; (in other words: &#034;networks of experts&#034;) so that people interested and expert in various IT subjects could collaborate.&nbsp; So, for example, there would be a .NET community of practice - a venue, for example, for questions, answers, ideas and experiences to be shared across a globally and organizationally distributed set of company .NET developers.</p>
<p>This was taking some time - his directs are wanting plans, structure, resources and causing delays. </p>
<p>I&#039;m definitely not at the level my boss (3rd removed) is at, nor do I have anything approaching his experience in business or IT, but this struck me as super strange.</p>
<p>We spend millions of dollars on servers, client software and email servers to facilitate these discussions.&nbsp; I told him he could do it in 5 minutes.&nbsp; Send an email to the helpdesk requesting that an email distribution list be created, all the developers subscribed to the list.&nbsp; Then send a note to the list asking everyone to send an introductory email.&nbsp; If the list gets busy and starts asking questions and sending interesting things, problem solved, task accomplished.&nbsp; If they don&#039;t, then you don&#039;t need the community of practice to begin with.&nbsp; If the list needs to share code snippets or something then they&#039;ll find a service or make one. </p>
<p>I&#039;m sure there&#039;s more to this than what I understand, but I can&#039;t help but wonder if sometimes we think an entire culture needs to change when all it really needs is an email to the helpdesk.</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/my-boss-boss-boss/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Looking back</title>
		<link>http://mhinze.com/looking-back/</link>
		<comments>http://mhinze.com/looking-back/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 21:48:15 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Deep thoughts]]></category>

		<category><![CDATA[career]]></category>

		<category><![CDATA[continuous improvement]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=41</guid>
		<description><![CDATA[Taking a moment to look back.&#160; When I accepted my current job in January 2006 I was looking to grow up as a software developer. Since then I&#039;ve learned a lot of things and these, for me and in no particular order, were the some of the most important.
1.&#160; The strategy pattern and others
Chapter 1 [...]]]></description>
			<content:encoded><![CDATA[<p>Taking a moment to look back.&nbsp; When I accepted my current job in January 2006 I was looking to grow up as a software developer. Since then I&#039;ve learned a lot of things and these, for me and in no particular order, were the some of the most important.</p>
<p>1.&nbsp; The strategy pattern and others</p>
<p>Chapter 1 of Head First Design Patterns changed my life, and I&#039;m not afraid to admit it.&nbsp; I devoured the rest of the book.&nbsp; And then, newly motivated, I read a bunch of other books.&nbsp; This led to the understanding of other patterns and formalized principles behind OOP, and I gained a base upon which to build more skill.</p>
<p>2. Inversion of control</p>
<p>Tools that transform patterns and principles out of the realm of &#034;elegance&#034; and into the reality of &#034;efficiency&#034; have changed the way I work.</p>
<p>3. Test first</p>
<p>I attended TechEd 2005 and the VS 2005 team was showing off all the new features.&nbsp; The one that grabbed my attention was the &#034;object workbench&#034; - where you could instantiate objects and play with them in isolation.&nbsp; &#034;This is great,&#034; I thought, &#034;because now I&#039;ll be able to see exactly what my code is doing.&#034;&nbsp; I never did play with the object workbench (was it just vapor?), but when I understood later that this vision had been realized already in the form of unit testing I was immediately hooked. </p>
<p>I didn&#039;t get it at first.&nbsp; Like everything else, I had to cut my teeth on it.&nbsp; I picked some side project and did it with TDD.&nbsp; I could see my design being different than I would have done it before.&nbsp; When I went to make a change I was able to do so with confidence.</p>
<p>I test drive almost everything now.&nbsp; And trust me - I still make many stupid mistakes.&nbsp; But I understand that&#039;s part of the process and it&#039;s trivial to fix most of them.</p>
<p>4. Refactoring</p>
<p>Specifically <a href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672');">the book</a>.&nbsp; This is something they don&#039;t (or didn&#039;t) teach at University.&nbsp; I can actually use a rigorous process to correct myself!</p>
<p>5. The transition from ADO.NET to ORM</p>
<p>I started with ADO.NET (that&#039;s all I knew about) and had my little helper classes and everything, just like everyone else did.&nbsp; I built some nice active recordy type frameworks for applications I wrote. </p>
<p>I read with great enthusiasm Mitchell&#039;s data access tutorials for/from Microsoft and built entire applications with those practices.&nbsp; I remember cringing every time I had to add a row to a grid or change a screen - the logic was almost entirely in the markup.</p>
<p>I discovered Subsonic, and found it very cool but mostly unusable for several reasons I won&#039;t list.</p>
<p>Then I finally got around to reading <a href="http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx');">Billy McAfferty&#039;s NHibernate article</a> and stepped through the demos.&nbsp; What took me so long? I built a sample app to cut my teeth and have never looked back.&nbsp; Nothing in my career, in my daily tasks, has saved my company more money than my tiny start at understanding NHibernate.&nbsp; &#034;Finally,&#034; I thought, &#034;I can program with objects.&#034;&nbsp; I later tried several other ORMs and shelved them for reasons usually related to friction.</p>
<p>I find it very odd that a lot of guidance from Microsoft (MSDN, the <a href="http://www.microsoft.com/learning/en/us/syllabi/2124Cfinal.mspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.microsoft.com/learning/en/us/syllabi/2124Cfinal.mspx');">MOC</a> I was teaching as an MCT) centers around object orientation but their data access strategies do not properly support it.&nbsp; Line of business software is (or has been, for me this is starting to change) all about data - reports, CRUD, legacy data, etc. is involved in almost every feature I deliver to the business.&nbsp; And if the data access is not OO, nothing is OO.</p>
<p>6. Domain driven design</p>
<p>I have to admit I haven&#039;t trudged my way through the entire book.. I have it and I&#039;ve probably read most of the words in it but I find it a terrible beating to read straight through.&nbsp; My understanding is therefore limited.&nbsp; But concepts I have picked up while working on open source and through the community have helped.&nbsp; I also read <a href="http://www.infoq.com/news/2006/12/domain-driven-design" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.infoq.com/news/2006/12/domain-driven-design');">DDD Quickly</a>, a summary pdf ebook.&nbsp; I get the <a href="http://tech.groups.yahoo.com/group/domaindrivendesign/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://tech.groups.yahoo.com/group/domaindrivendesign/');">yahoo group</a> messages in my email inbox.</p>
<p>DDD has allowed me to further my application of object oriented programming even more. DDD took what I had learned from NHibernate examples and blew it up to a fuller and richer object orientation.</p>
<p>7. Contributing to open source&#8230;</p>
<p>&#8230; is one of the most exhilarating things in the world for me.&nbsp; This is not an exaggeration.. there is <em>nothing</em> like it.&nbsp; I will never forget my first sweaty-palmed commit, watching cctray like a hawk.</p>
<p>8. Community</p>
<p>I spent a long time just looking for communities without realizing that&#039;s what I was doing.&nbsp; Joining them has elevated my level of discourse (technically), exposed me to new ideas, and introduced me to people I can social network with.&nbsp; Communities oriented around software user groups, ecosystems and practices are extremely helpful.&nbsp; Mentors are the best - if you don&#039;t have one, get one.&nbsp; A lot of the time, online, you don&#039;t even need their permission.&nbsp; =)</p>
<p>I have had 5 minute phone conversations with people that have enabled me to jump ahead farther than any one book or principle.</p>
<p>I have always been pretty good at using social networking tools, but now I have a frame of reference that allows me to collect more and better information.</p>
<p>Passion breeds quality.&nbsp; Passionate people are involved in communities.&nbsp; Involving myself in communities and surrounding myself with other passionate people has upped my quality.</p>
<p>9. Vertical slices</p>
<p>My professional experience with Agile is limited.&nbsp; It is not &#034;what we do&#034; on my current team.&nbsp; Because I usually work on projects by myself and have a large degree of control over the software I produce, I am able to practice pieces of it on a micro level.&nbsp; The main tenet that I have found to be helpful is to deliver working software early.&nbsp; Working software is all we have to give, the rest are &#034;gets&#034;.&nbsp; As I work in vertical slices rather than in horizontal tiers, and refactor as I go, my designs are much more robust and flexible.&nbsp; Frictionlessness is also key.&nbsp; XP concepts like contiuous integration have really made things much easier than the &#034;Program and pray&#034; method.&nbsp; Time to login screen is a great metric.</p>
<p>10. The old &#034;The more you know the more you know you don&#039;t know&#034; thing</p>
<p>I realize that a lot of these things are so common now and passe (at least it feels that way compared to the level of the people in the communities I listen to).&nbsp; I strive to be the &#034;dumbest guy in the room.&#034;</p>
<p>11. Technical books read different</p>
<p>I have learned that reading technical books is different than reading textbooks and not at all like reading fiction or prose.&nbsp; I always thought I was a quick reader, but I am not afraid to read a page several times to understand it completely.</p>
<p>12. I do something new in every project</p>
<p>Because of the level of control I have over my projects I require myself to try something new with each one.&nbsp; This has not caused me more friction - I consider it self guided training.&nbsp; I spike random stuff more often.</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/looking-back/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Relativism, crucibles and criticism</title>
		<link>http://mhinze.com/relativism-crucibles-criticism/</link>
		<comments>http://mhinze.com/relativism-crucibles-criticism/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 11:20:13 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Deep thoughts]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=40</guid>
		<description><![CDATA[
Crucibles&#160; 

A crucible is a &#034;severe test&#034; or a &#034;trial&#034; - something through which an idea is passed so that it may be refined, hardened by time, sharpened with experience, and clarified by intellect until it becomes acceptable for practice.
A good idea has suffered through the crucibles of competition and community, emerged from it more [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>Crucibles&nbsp; </li>
<ul>
<li>A crucible is a &#034;severe test&#034; or a &#034;trial&#034; - something through which an idea is passed so that it may be refined, hardened by time, sharpened with experience, and clarified by intellect until it becomes acceptable for practice.
<li>A good idea has suffered through the crucibles of competition and community, emerged from it more robust, and is elevated within those communities as more optimal than alternatives.
<li>There&#039;s really no other way for non-scientific ideas to prove useful or not.</li>
</ul>
<li>Criticism </li>
<ul>
<li>Criticism as an aspect of crucible is vital
<li>Criticism as avoidance of crucible is crippling
<li>How do we know the difference? </li>
<ul>
<li>Crucible criticism: Practiced, intentional, provides alternatives, instructive, cautionary, demonstratable, clear
<li>Crippling criticism: Defensive, personal, unfamiliar with alternatives, destructive, reactionary, abstract</li>
</ul>
</ul>
<li>There&#039;s a better way of doing things. It&#039;s not relative.
<li>If you don&#039;t understand that, you&#039;ll never <em>find</em> a better way of doing things.&nbsp; There&#039;s no motivation to grow and adapt if the status quo is acceptable.
<li>Software development, while still a young field, has a rich history of internal debate, agreed-upon best practices, and deep community expertise.
<li>Nothing is set in stone, but that doesn&#039;t mean you&#039;re not doing it wrong.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/relativism-crucibles-criticism/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Tree Surgeon 2.0 released</title>
		<link>http://mhinze.com/treesurgeon-20-released/</link>
		<comments>http://mhinze.com/treesurgeon-20-released/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 10:51:47 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<category><![CDATA[treesurgeon]]></category>

		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=39</guid>
		<description><![CDATA[Bil Simser just released Tree Surgeon 2.0.
TreeSurgeon automates the creation of a new project development tree, complete with a VS solution, a test project, a console project and a &#034;core&#034; project.&#160; It also automates the creation of a Nant build file which is set up to generate an Ncover report.
&#160;&#160; 
The first thing I wanted [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://weblogs.asp.net/bsimser/archive/2008/06/30/tree-surgeon-2-0-released.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://weblogs.asp.net/bsimser/archive/2008/06/30/tree-surgeon-2-0-released.aspx');">Bil Simser just released</a> <a href="http://www.codeplex.com/treesurgeon" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.codeplex.com/treesurgeon');">Tree Surgeon 2.0</a>.</p>
<p>TreeSurgeon automates the creation of a new project development tree, complete with a VS solution, a test project, a console project and a &#034;core&#034; project.&nbsp; It also automates the creation of a Nant build file which is set up to generate an Ncover report.</p>
<p><a href="http://mhinze.com/wp-content/uploads/2008/07/image.png" ><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="266" alt="image" src="http://mhinze.com/wp-content/uploads/2008/07/image-thumb.png" width="191" border="0"></a>&nbsp;&nbsp; </p>
<p>The first thing I wanted to do was add other tools I use in almost every project.&nbsp; This turned out to be way easy.&nbsp; Just copy the binaries in the skeleton folder (these get copied to every new tree) and edit the project file templates to add a reference.</p>
<p>Here I added Rhino Mocks:</p>
<p><a href="http://mhinze.com/wp-content/uploads/2008/07/image1.png" ><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="269" alt="image" src="http://mhinze.com/wp-content/uploads/2008/07/image-thumb1.png" width="539" border="0"></a>&nbsp;</p>
<p>And added a few lines to the template file:</p>
<p><a href="http://mhinze.com/wp-content/uploads/2008/07/image2.png" ><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="403" alt="image" src="http://mhinze.com/wp-content/uploads/2008/07/image-thumb2.png" width="630" border="0"></a> </p>
<p>Easy!&nbsp; Thanks Bil!</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/treesurgeon-20-released/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Resolving HttpContext members using Ninject providers</title>
		<link>http://mhinze.com/httpcontext-ninject-providers/</link>
		<comments>http://mhinze.com/httpcontext-ninject-providers/#comments</comments>
		<pubDate>Tue, 24 Jun 2008 15:17:42 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
		
		<category><![CDATA[Tools]]></category>

		<category><![CDATA[asp.net]]></category>

		<category><![CDATA[ninject]]></category>

		<guid isPermaLink="false">http://mhinze.com/?p=28</guid>
		<description><![CDATA[I am building a simple &#034;single sign-on&#034; ASP.NET application that interprets the current user&#039;s ASP.NET integrated security credentials to a vendor site&#039;s credentials.&#160; One of the services I wrote required the IIdentity as a constructor parameter to begin the interpretation process.&#160; 
This was straightforward with regards to TDD - I simply mocked the IIdentity and [...]]]></description>
			<content:encoded><![CDATA[<p>I am building a simple &#034;single sign-on&#034; ASP.NET application that interprets the current user&#039;s ASP.NET integrated security credentials to a vendor site&#039;s credentials.&nbsp; One of the services I wrote required the <a href="http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.aspx');">IIdentity</a> as a constructor parameter to begin the interpretation process.&nbsp; </p>
<p>This was straightforward with regards to TDD - I simply mocked the IIdentity and kept going.&nbsp; When I began implementing dependency injection with an IoC container I struggled until I found a nice way to do this with <a href="http://ninject.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ninject.org/');">Ninject</a>.</p>
<p>Ninject offers a pretty cool <a href="http://davidhayden.com/blog/dave/archive/2008/06/20/NinjectDependencyInjectionASPNETWebPagesSample.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://davidhayden.com/blog/dave/archive/2008/06/20/NinjectDependencyInjectionASPNETWebPagesSample.aspx');">suite of ASP.NET integration points</a> in the <a href="http://ninject.googlecode.com/svn/trunk/src/Framework/Web/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ninject.googlecode.com/svn/trunk/src/Framework/Web/');">Ninject.Framework.Web</a> namespace.&nbsp; And without using System.Web.Abstractions, the best way I found to resolve a property of HttpContext.Current (User.Identity in my case) was to leverage a provider.</p>
<p class="post-update">Update (6/25): Duncan Godwin, in the comments, explained what&#039;s perhaps a better way to do this using ToFactoryMethod()</p>
<h3>Ninject providers</h3>
<p><a href="http://dojo.ninject.org/wiki/display/NINJECT/Providers+and+the+Activation+Context" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://dojo.ninject.org/wiki/display/NINJECT/Providers+and+the+Activation+Context');">Ninject providers</a>, IProvider and the simple implementation SimpleProvider&lt;T&gt;, allow the developer to customize the resolution of these hard-to inject objects.&nbsp; We&#039;re <a href="http://groups.google.com/group/ninject/browse_thread/thread/6ca3bc6dd2078cc5" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://groups.google.com/group/ninject/browse_thread/thread/6ca3bc6dd2078cc5');">talking providers today</a> on the <a href="http://groups.google.com/group/ninject" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://groups.google.com/group/ninject');">Ninject list</a>.</p>
<p>Here&#039;s the one I used to resolve IIdentity:</p>
<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">WebIdentityProvider </span>: <span style="color: #2b91af">SimpleProvider</span>&lt;<span style="color: #2b91af">IIdentity</span>&gt;
{
    <span style="color: blue">protected override </span><span style="color: #2b91af">IIdentity </span>CreateInstance(<span style="color: #2b91af">IContext </span>context)
    {
        <span style="color: blue">return </span><span style="color: #2b91af">HttpContext</span>.Current.User.Identity;
    }

    <span style="color: blue">public override bool </span>IsCompatibleWith(<span style="color: #2b91af">IContext </span>context)
    {
        <span style="color: blue">return </span><span style="color: #2b91af">HttpContext</span>.Current != <span style="color: blue">null</span>;
    }
}</pre>
<p><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a></p>
<p>Here is sample code like I used in Global.asax.cs:</p>
<p><a href="http://11011.net/software/vspaste" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://11011.net/software/vspaste');"></a>
<pre class="code"><span style="color: blue">public class </span><span style="color: #2b91af">Global </span>: <span style="color: #2b91af">NinjectHttpApplication
</span>{
    <span style="color: green">// ...

    </span><span style="color: blue">protected override </span><span style="color: #2b91af">IKernel </span>CreateKernel()
    {
        <span style="color: blue">var </span>module = <span style="color: blue">new </span><span style="color: #2b91af">InlineModule</span>(
            m =&gt; m.Bind&lt;<span style="color: #2b91af">IIdentity</span>&gt;().ToProvider&lt;<span style="color: #2b91af">WebIdentityProvider</span>&gt;(),
            m =&gt; m.Bind&lt;<span style="color: #2b91af">IIdentityService</span>&gt;().To&lt;<span style="color: #2b91af">IdentityService</span>&gt;(),
            m =&gt; m.Bind&lt;<span style="color: #2b91af">IDisplayName</span>&gt;().To&lt;<span style="color: #2b91af">DisplayName</span>&gt;()
            );
        <span style="color: blue">return new </span><span style="color: #2b91af">StandardKernel</span>(module, <span style="color: blue">new </span><span style="color: #2b91af">Log4netModule</span>());
    }
}</pre>
<p>When binding to the provider HttpContext.Current and the user&#039;s IIdentity are available.</p>
<p>I have a feeling this isn&#039;t the last one I&#039;ll use.</p>
<p><a href="http://mhinze.com/static-content/NinjectWeb.zip" onclick="javascript:pageTracker._trackPageview('/downloads/static-content/NinjectWeb.zip');">Here is sample code</a> with log4net&#039;s <a href="http://logging.apache.org/log4net/release/sdk/log4net.Appender.AspNetTraceAppender.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://logging.apache.org/log4net/release/sdk/log4net.Appender.AspNetTraceAppender.html');">AspNetTraceAppender</a> turned on (using <a href="http://mhinze.com/logging-with-ninject/" >Ninject logging</a> of course).</p>
]]></content:encoded>
			<wfw:commentRss>http://mhinze.com/httpcontext-ninject-providers/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
