<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Krzysztof Kozmic</title><link>http://devlicio.us/blogs/krzysztof_kozmic/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>How to force Nuget not to update log4net to 1.2.11</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/31/how-to-force-nuget-not-to-update-log4net-to-1-2-11.aspx</link><pubDate>Tue, 31 Jan 2012 12:28:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69451</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=69451</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/31/how-to-force-nuget-not-to-update-log4net-to-1-2-11.aspx#comments</comments><description>&lt;p&gt;That&amp;rsquo;s a quick one. There&amp;rsquo;s been a new release of log4net recently that&amp;rsquo;s signed with a new key, and therefore is incompatible with old version 1.2.10.&lt;/p&gt;
&lt;p&gt;Therefore, due to near-ubiquity of the library in .NET space, it may cause some problems if you happen to have a dependency (direct or indirect) on it.&lt;/p&gt;
&lt;p&gt;The matters are made worse by Nuget&amp;rsquo;s default of getting the latest available version of the package. I dealt with this problem the other day, and I saw a few people in my twitter stream struggling with the same issue.&lt;/p&gt;
&lt;p&gt;The solution is quite simple. It&amp;rsquo;s not specific to log4net and I&amp;rsquo;m not picking on log4net here. Here&amp;rsquo;s how you can restrict Nuget&amp;rsquo;s package to specific version in your solution.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So imagine you install a package that has a dependency on log4net. In this case, the dependency is specified as specifically version 1.2.10 (as opposed to Nuget&amp;rsquo;s default: this version of newer).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_core_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_core" alt="nuget_core" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_core_5F00_thumb.png" border="0" height="287" width="660" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If after that we install another package that also depends on log4net but doesn&amp;rsquo;t restrict the version, we&amp;rsquo;ll have a problem.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_log4net_fail" alt="nuget_log4net_fail" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_thumb.png" border="0" height="327" width="660" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The package we were trying to install doesn&amp;rsquo;t get installed. Actually, even if it did, we would have a problem since it most likely was compiled against log4net 1.2.10 anyway, and if Nuget updated log4net to version 1.2.11 the app would throw an exception at runtime due to mismatched assembly.&lt;/p&gt;
&lt;p&gt;So there is a solution to restrict version of the package to specific version (in this case 1.2.10) &lt;a href="http://docs.nuget.org/docs/reference/versioning" target="_blank"&gt;as specified in the documentation.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_solution_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_log4net_fail_solution" alt="nuget_log4net_fail_solution" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_solution_5F00_thumb.png" border="0" height="339" width="691" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;After adding allowedVersions=&amp;rdquo;[1.2.10]&amp;rdquo; we can try again and this time the package will install properly.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_avoided_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_log4net_fail_avoided" alt="nuget_log4net_fail_avoided" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_log4net_5F00_fail_5F00_avoided_5F00_thumb.png" border="0" height="226" width="660" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Notice it says it installed log4net 1.2.11. I checked my packages folder, and project dependencies and the version referenced was 1.2.10 so all is good.&lt;/p&gt;
&lt;p&gt;Hope that helps&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69451" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Testing framework is not just for writing… tests</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/18/testing-framework-is-not-just-for-writing-tests.aspx</link><pubDate>Wed, 18 Jan 2012 13:06:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69335</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>8</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=69335</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/18/testing-framework-is-not-just-for-writing-tests.aspx#comments</comments><description>&lt;p&gt;Quick question &amp;ndash; from the top of your head, without running the code, what is the result of:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var foo = -00.053200000m; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var result = foo.ToString(&lt;span style="color:#006080;"&gt;&amp;quot;##.##&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Or a different one:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var foo = &lt;span style="color:#006080;"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var bar = &lt;span style="color:#006080;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var foobar = &lt;span style="color:#006080;"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; + &lt;span style="color:#006080;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var concaternated = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder(foo).Append(bar).ToString(); &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var result1 = AreEqual(foobar, concaternated); &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var result2 = Equals(foobar, concaternated);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; AreEqual(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; one, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; two) &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{ &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; one == two; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;How about this one from NHibernate?&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var parent = session.Get&amp;lt;Parent&amp;gt;(1); &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;DoSomething(parent.Child.Id); &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var result = NHibernateUtil.IsInitialized(parent.Child);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;The point being?&lt;/h3&gt;
&lt;p&gt;Well, if you can answer all of the above without running the code, &lt;a href="http://readify.net/work-with-us" target="_blank"&gt;we&amp;rsquo;re hiring&lt;/a&gt;. I don&amp;rsquo;t, and I suspect most people don&amp;rsquo;t either. That&amp;rsquo;s fine. Question is &amp;ndash; what are you going to do about it? What do you do when some 3rd party library, or part of standard library exhibits unexpected behaviour? How do you go about learning if what you think should happen, is really what does happen?&lt;/p&gt;
&lt;h3&gt;Scratchpad&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve seen people open up Visual Studio, create ConsoleApplication38, write some code using the API in question including plenty of Console.WriteLine along the way (curse whoever decided Client Profile should be the default for Console applications, switch to full .NET profile) compile, run and discard the code. And then repeat the process with ConsoleApplication39 next time.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The solution I&amp;rsquo;m using feels a bit more lightweight, and has worked for me well over the years. It is very simple &amp;ndash; I leverage my existing test framework and test runner. I create an empty test fixture called Scratchpad.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_2.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="scratchpad" alt="scratchpad" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_thumb.png" border="0" height="185" width="198" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_fixture_5F00_2.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="scratchpad_fixture" alt="scratchpad_fixture" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_fixture_5F00_thumb.png" border="0" height="231" width="282" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This class gets committed to the VCS repository. That way every member of the team gets their own scratchpad to play with and validate their theories, ideas and assumptions. However, as the name implies, this all is a one-off throwaway code. After all, you don&amp;rsquo;t really need to test the BCL. One would hope Microsoft already did a good job at that.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using git, you can easily tell it not to track changes to the file, by running the following command (after you commit the file):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;git update-index --assume-unchanged Scratchpad.cs&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_git_5F00_2.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="scratchpad_git" alt="scratchpad_git" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_git_5F00_thumb.png" border="0" height="210" width="636" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;With this simple set up you will have quick place to validate your assumptions (and answer questions about API behaviour) with little friction.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_test_5F00_4.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="scratchpad_test" alt="scratchpad_test" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/scratchpad_5F00_test_5F00_thumb_5F00_1.png" border="0" height="147" width="383" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;So there you have it, a new, useful technique in your toolbelt.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69335" width="1" height="1"&gt;</description></item><item><title>Approval testing – value for the money</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/16/approval-testing-value-for-the-money.aspx</link><pubDate>Mon, 16 Jan 2012 12:29:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:69327</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=69327</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2012/01/16/approval-testing-value-for-the-money.aspx#comments</comments><description>&lt;p&gt;I am a believer in the &lt;a href="http://kozmic.pl/2011/02/27/tests-are-your-airbag/" target="_blank"&gt;value&lt;/a&gt; of testing. However not all tests are equal, and actually not all tests provide value at all. Raise your hand if you’ve ever seen (unit) tests that tested every corner case of trivial piece of code that’s used once in a blue moon in an obscure part of the system. Raise your other hand if that test code was not written by human but generated.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;As with any type of code, test code is a liability. It takes time to write it, and then it takes even more time to read it and maintain it. Considering time is money, rather then blindly unit testing everything we need to constantly ask ourselves how do we get the best value for the money – what’s the best way to spend time writing code, to write the least amount of it, to best cover the widest range of possible failures in the most maintainable fashion.&lt;/p&gt;  &lt;p&gt;Notice we’re optimising quite a few variables here. We don’t want to blindly write plenty of code, we don’t want to write sloppy code, and we want the test code to properly fulfil its role as our safety net, alarming us early when things are about to go belly up.&lt;/p&gt;  &lt;h3&gt;Testing conventions&lt;/h3&gt;  &lt;p&gt;What many people seem to find challenging to test is conventions in their code. When all you have is a hammer (unit testing) it’s hard to hit a nail, that not only isn’t really a nail, but isn’t really explicitly there to being with. To make matters worse the compiler is not going to help you really either. How would it know that LoginController not implementing IController is a problem? How would it know that the new dependency you introduced onto the controller is not registered in your IoC container? How would it know that the public method on your &lt;a href="http://nhforge.org" target="_blank"&gt;NHibernate&lt;/a&gt; entity needs to be virtual?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In some cases the tool you’re using will provide some level of validation itself. NHibernate knows the methods ought to be virtual and will give you quite good exception message when you set it up. You can verify that quite easily in a simple test. Not everything is so black and white however. One of diagnostics provided by &lt;a href="http://docs.castleproject.org/Windsor.MainPage.ashx" target="_blank"&gt;Castle Windsor&lt;/a&gt; is called “&lt;strong&gt;Potentially&lt;/strong&gt; misconfigured components”. Notice the vagueness of the first word. They might be misconfigured, but not necessarily are – it all depends on how you’re using them and the tool itself cannot know that. How do you test that efficiently?&lt;/p&gt;  &lt;h3&gt;Enter approval testing&lt;/h3&gt;  &lt;p&gt;One possible solution to that, which we’ve been quite successfully using on my current project is approval testing. The concept is very simple. You write a test that runs producing an output. Then the output is reviewed by someone, and assuming it’s correct, it’s marked as approved and committed to the VCS repository. On subsequent runs the output is generated again, and compared against approved version. If they are different the test fails, at which point someone needs to review the change and either mark the new version as approved (when the change is legitimate) or fix the code, if the change is a bug.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If the explanation above seems dry and abstract let’s go through an example. Windsor 3 introduced way to programmatically access its diagnostics. We can therefore write a test looking through the potentially misconfigured components, so that we get notified if something on the list changes. I’ll be using &lt;a href="http://approvaltests.sourceforge.net/" target="_blank"&gt;ApprovalTests&lt;/a&gt; library for that.&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;[Test]&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Approved_potentially_misconfigured_components()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; WindsorContainer();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    container.Install(FromAssembly.Containing&amp;lt;HomeController&amp;gt;()); &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var handlers = GetPotentiallyMisconfiguredComponents(container);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var message = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var inspector = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DependencyInspector(message);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (IExposeDependencyInfo handler &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; handlers)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;        handler.ObtainDependencyDetails(inspector);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    Approvals.Approve(message.ToString());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&amp;#160;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; IHandler[] GetPotentiallyMisconfiguredComponents(WindsorContainer container)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var host = container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey) &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IDiagnosticsHost;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var diagnostic = host.GetDiagnostic&amp;lt;IPotentiallyMisconfiguredComponentsDiagnostic&amp;gt;();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    var handlers = diagnostic.Inspect();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; handlers;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;background-color:white;margin:0em;border-left-style:none;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;What’s important here is we’re setting up the container, getting the misconfigured components out of it, produce readable output from the list and passing it down to the approval framework to do the rest of the job.&lt;/p&gt;

&lt;p&gt;Now if you’ve set up the framework to pup-up a diff tool when the approval fails you will be greeted with something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/approval_5F00_diff_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="approval_diff" border="0" alt="approval_diff" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/approval_5F00_diff_5F00_thumb.png" width="640" height="388" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You have all the power of your diff tool to inspect the change. In this case we have one new misconfigured component (HomeController) which has a new parameter, appropriately named missingParameter that the container doesn’t know how to provide to it. Now you either slap yourself in the forehead and fix the issue, if that really is an issue, or approve that dependency, by copying the diff chunk from the left pane to the right, approved pane. By doing the latter you’re notifying the testing framework and your teammates that you do know what’s going on and you know it’s not an issue the way things are going to work. Coupled with a sensible commit message explaining why you chose to approve this difference you get a pretty good trail of exception to the rule and reasons behind them.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;That’s quite an elegant approach to a quite hard problem. We’re using it for quite a few things, and it’s been giving us really good value for little effort it took to write those tests, and maintain them as we keep developing the app, and the approved files change.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;So there you have it, a new, useful tool in your toolbelt.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=69327" width="1" height="1"&gt;</description></item><item><title>API design challenge – builder</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/12/31/api-design-challenge-builder.aspx</link><pubDate>Sat, 31 Dec 2011 01:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68884</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68884</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/12/31/api-design-challenge-builder.aspx#comments</comments><description>&lt;p&gt;Now that &lt;a href="http://kozmic.pl/2011/12/16/castle-windsor-3-0-is-released/" target="_blank"&gt;Windsor 3 is released&lt;/a&gt; I can concentrate on some of my other ideas and projects. While working on one of them, &lt;a href="https://github.com/kkozmic/Cartographer" target="_blank"&gt;called Cartographer&lt;/a&gt;, I encountered an interesting API design problem.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I have a class (a builder to be precise) that has a task of setting up a central object (an IMapper implementation) in Cartographer (If you&amp;rsquo;ve ever used &lt;a href="http://autofac.org" target="_blank"&gt;Autofac&lt;/a&gt;, it is somewhat analogous to ContainerBuilder). What is interesting about it, is I have three goals for that class:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Provide API for high level configuration and extension points that are universal to and intrinsic to any IMapper implementation.&lt;/li&gt;
&lt;li&gt;Provide API for low level configuration of the default IMapper implementation that the builder creates, that will meet the following criteria:&lt;ol&gt;
&lt;li&gt;Not force user to customize anything, as the default setup should be enough to get started in most cases.&lt;/li&gt;
&lt;li&gt;Allow users to easily swap/extend parts of the dependency chain of the default mapper.&lt;/li&gt;
&lt;li&gt;Work well and be natural both with and without IoC container .&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Be simple and discoverable to the users (and provide good Intellisense experience).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How would you design the API for this class?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Oh, and happy new year.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68884" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Design/default.aspx">Design</category></item><item><title>Castle Windsor 3.0 is released</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/12/16/castle-windsor-3-0-is-released.aspx</link><pubDate>Fri, 16 Dec 2011 12:55:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68848</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68848</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/12/16/castle-windsor-3-0-is-released.aspx#comments</comments><description>&lt;p&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Castle Windsor" alt="Castle Windsor" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/wc_5F00_logo100_5B00_1_5D005F00_3.png" height="100" width="100" border="0" /&gt; &lt;/p&gt;
&lt;p&gt;After successful &lt;a href="http://kozmic.pl/2011/08/15/windsor-3-beta-1-is-released-along-with-other-goodies/" target="_blank"&gt;beta&lt;/a&gt; and &lt;a href="http://kozmic.pl/2011/11/20/getting-closer-castle-windsor-3-rc-1/" target="_blank"&gt;RC releases&lt;/a&gt; final version of &lt;a href="http://docs.castleproject.org/Windsor.MainPage.ashx" target="_blank"&gt;Castle Windsor&lt;/a&gt; (as well as Castle Core, and a whole set of facilities) has now been released. There are no major changes between final version and RC. The difference is some minor bug fixes, improved exception messages and some small improvements all over the place.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The packages are available now, on &lt;a href="http://docs.castleproject.org/Windsor.MainPage.ashx" target="_blank"&gt;Nuget&lt;/a&gt; (with symbols), and via &lt;a href="http://sourceforge.net/projects/castleproject/files/Windsor/3.0/Castle.Windsor.3.0.0.zip/download" target="_blank"&gt;standard .zip download&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Last but not least - thank you to everyone who downloaded beta and release candidate and provided feedback. You guys rock.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68848" width="1" height="1"&gt;</description></item><item><title>Getting closer… Castle Windsor 3 RC 1</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/11/20/getting-closer-castle-windsor-3-rc-1.aspx</link><pubDate>Sun, 20 Nov 2011 12:10:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68406</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68406</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/11/20/getting-closer-castle-windsor-3-rc-1.aspx#comments</comments><description>&lt;p&gt;Few weeks later than originally expected but here it is &amp;ndash; Castle Windsor 3.0 (along with its facilities and Castle.Core) achieved release candidate status.&lt;/p&gt;
&lt;p&gt;There is one major new feature in this release: registration API gained ability to specify properties to ignore/require. There are some scenarios where that&amp;rsquo;s useful, for example where integrating with some 3rd party framework that forces you to inherit from a base class which exposes its dependencies as properties. Creating pass-through constructors for each inherited class can be mundane. In those cases you can simply mark those base class properties as required, in which case Windsor will not allow them to be resolved unless all base property dependencies are satisfied. PropertyFilter enum supports several other most common scenarios, and for advanced cases there&amp;rsquo;s an overload that gives you more control.&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;Container.Register(&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    Classes.FromThisAssembly()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        .BasedOn&amp;lt;ICommon&amp;gt;()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        .Configure(c =&amp;gt; c.Properties(PropertyFilter.RequireBase)));&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;To address performance hit at startup Windsor no longer enables &lt;a href="http://docs.castleproject.org/Windsor.Performance-Counters.ashx" target="_blank"&gt;performance counters&lt;/a&gt; by default. Now, you have to do it explicitly:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; WindsorContainer();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var diagnostic = LifecycledComponentsReleasePolicy.GetTrackedComponentsDiagnostic(container.Kernel);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var counter = LifecycledComponentsReleasePolicy.GetTrackedComponentsPerformanceCounter(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PerformanceMetricsFactory());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;container.Kernel.ReleasePolicy = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LifecycledComponentsReleasePolicy(diagnostic, counter);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Full changelog is included in the packages. Please, if possible, take the time to upgrade to this version and if you find any issues report them so that the final release is rock solid. If no major issues are found, the final release will be published in two weeks.&lt;/p&gt;
&lt;p&gt;The binaries are available on Nuget right now, and soon &lt;a href="http://castleproject.org/castle/projects.html" target="_blank"&gt;on our website&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68406" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/IoC/default.aspx">IoC</category></item><item><title>Connector: Simple, zero friction Github –&gt; AppHarbor integration</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/09/18/connector-simple-zero-friction-github-gt-appharbor-integration.aspx</link><pubDate>Sun, 18 Sep 2011 09:53:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68184</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68184</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/09/18/connector-simple-zero-friction-github-gt-appharbor-integration.aspx#comments</comments><description>&lt;p&gt;Recently to play with some new technology I came up with an idea to build an integration layer between Github and AppHarbor. What that means, is give you ability to work with your Github repository, reaping benefits of all of it’s VCS-centric features, and automatically, continuously deploy your code to AppHarbor.&lt;/p&gt;  &lt;p&gt;The actual scenario I had in mind is to be able to use that for deployment of Open Source projects. AppHarbor is fantastic, no-headache deployment in the cloud, but Github is perfect for keeping and developing your code in the open, in social way. To have the cake and eat it too, Connector was born.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/Connector_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Connector" border="0" alt="Connector" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/Connector_5F00_thumb.png" width="644" height="391" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I hope you find it useful. it is free, use-at-your-own-risk-and-don’t-sue-me-if-something-breaks software. There’s still some work to be done, feature-wise and a whole lot of polishing but I decided to announce it early and get early feedback. If you have any suggestions, ideas or (gulp) bugs, let me know!&lt;/p&gt;  &lt;p&gt;link: &lt;a title="http://connector.apphb.com/" href="http://connector.apphb.com/"&gt;http://connector.apphb.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Hope that helps.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68184" width="1" height="1"&gt;</description></item><item><title>Windsor 3 beta 1 – dozen of Nuget packages and SymbolSource.org support</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/09/04/windsor-3-beta-1-dozen-of-nuget-packages-and-symbolsource-org-support.aspx</link><pubDate>Sun, 04 Sep 2011 10:47:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68165</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68165</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/09/04/windsor-3-beta-1-dozen-of-nuget-packages-and-symbolsource-org-support.aspx#comments</comments><description>&lt;p&gt;As &lt;a href="http://kozmic.pl/2011/08/15/windsor-3-beta-1-is-released-along-with-other-goodies/" target="_blank"&gt;promised&lt;/a&gt;, I released Nuget packages for beta 1 of Windsor 3. This is my first major rollout of Nuget packages, so please report any issues working with them.&lt;/p&gt;
&lt;h3&gt;Nuget and beta packages&lt;/h3&gt;
&lt;p&gt;Nuget is quickly evolving and getting more useful with each release. However one feature it&amp;rsquo;s missing right now is support for pre-release packages (&lt;a href="http://twitter.com/#!/davidebbo/status/109564923935330305" target="_blank"&gt;this is coming in the next version&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/davidebbo_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="davidebbo" alt="davidebbo" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/davidebbo_5F00_thumb.png" border="0" height="350" width="613" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This is not really a big deal, however it means there are a few things you should be aware of.&lt;/p&gt;
&lt;h3&gt;Recommended version&lt;/h3&gt;
&lt;p&gt;Since the new package is a pre-release, while I would really like for everyone to start using it immediately and report all issues they find, I quite understand that many people will rather prefer to stick to the last official version for the time being. To accommodate that the new packages are not made recommended versions, so your Nuget explorer will still point to the last stable (2.5.3) version if you search for Windsor, Castle.Core or any other pre-existing package.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_explorer_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_explorer" alt="nuget_explorer" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_explorer_5F00_thumb.png" border="0" height="450" width="800" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you go to command line and install one of the packages without specifying version number, it will install the latest, that is beta 1 version.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_commandline_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="nuget_commandline" alt="nuget_commandline" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/nuget_5F00_commandline_5F00_thumb.png" border="0" height="188" width="630" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;SymbolSource.org and debugging into Windsor&lt;/h3&gt;
&lt;p&gt;Folks at &lt;a href="http://www.symbolsource.org/" target="_blank"&gt;SymbolSource.org&lt;/a&gt; added recently support for Nuget (and &lt;a href="http://www.openwrap.org/" target="_blank"&gt;OpenWrap&lt;/a&gt; as well) and the new Castle packages take advantage of that. What it gives you, is you can now easily debug into Windsor&amp;rsquo;s code, just like .NET framework reference source (&lt;a href="http://www.symbolsource.org/Public/Home/VisualStudio" target="_blank"&gt;there&amp;rsquo;s a simple guide at SymbolSource on how to do it&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;After you&amp;rsquo;re all set you can step into any of Castle methods in your debugger and watch the magic happen. Very cool thing, even if I say so myself.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/windsor_2D00_source_2D00_debugging_5F00_2.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="windsor-source-debugging" alt="windsor-source-debugging" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/windsor_2D00_source_2D00_debugging_5F00_thumb.png" border="0" height="397" width="833" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;List of packages&lt;/h3&gt;
&lt;p&gt;Here&amp;rsquo;s the full list of v3 beta 1 packages (notice those are not all Castle packages, just those that were published as v3 beta 1 rollout of Windsor):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Core" target="_blank"&gt;Castle.Core&lt;/a&gt; &amp;ndash; Contains Castle.Core.dll which includes DynamicProxy, DictionaryAdapter, EmailSender, logging abstractions and some other goodies.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Core-log4net" target="_blank"&gt;Castle.Core-log4net&lt;/a&gt; &amp;ndash; Contains Castle.Services.Logging.Log4netIntegration.dll, that is implementation of Castle logging abstractions for log4net&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Core-NLog" target="_blank"&gt;Castle.Core-NLog&lt;/a&gt; &amp;ndash; Contains Castle.Services.Logging.NLogIntegration.dll, that is implementation of Castle logging abstractions for NLog&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Windsor" target="_blank"&gt;Castle.Windsor&lt;/a&gt; &amp;ndash; Contains Castle.Windsor.dll which has Windsor itself and two most commonly used facilities &amp;ndash; &lt;a href="http://docs.castleproject.org/Windsor.Typed-Factory-Facility.ashx" target="_blank"&gt;Typed Factory facility&lt;/a&gt; and &lt;a href="http://docs.castleproject.org/Windsor.Startable-Facility.ashx" target="_blank"&gt;Startable facility&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.LoggingFacility" target="_blank"&gt;Castle.LoggingFacility&lt;/a&gt; &amp;ndash; Contains &lt;a href="http://docs.castleproject.org/Windsor.Logging-Facility.ashx" target="_blank"&gt;logging facility&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Windsor-log4net" target="_blank"&gt;Castle.Windsor-log4net&lt;/a&gt; &amp;ndash; Empty package that just installs logging facility and Castle.Core-log4net (and their dependencies obviously).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.Windsor-NLog" target="_blank"&gt;Castle.Windsor-NLog&lt;/a&gt; &amp;ndash; Empty package that just installs logging facility and Castle.CoreNLog (and their dependencies obviously).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.WcfIntegrationFacility"&gt;Castle.WcfIntegrationFacility&lt;/a&gt; &amp;ndash; Windsor&amp;rsquo;s &lt;a href="http://docs.castleproject.org/Windsor.WCF-Integration-Facility.ashx" target="_blank"&gt;WCF facility&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.SynchronizeFacility"&gt;Castle.SynchronizeFacility&lt;/a&gt; &amp;ndash; Windsor&amp;rsquo;s &lt;a href="http://docs.castleproject.org/Windsor.Synchronize-Facility.ashx" target="_blank"&gt;Synchronize facility&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.RemotingFacility"&gt;Castle.RemotingFacility&lt;/a&gt; &amp;ndash; Windsor&amp;rsquo;s &lt;a href="http://docs.castleproject.org/Windsor.Remoting-Facility.ashx" target="_blank"&gt;Remoting facility&lt;/a&gt; (extracted out of Castle.Windsor.dll)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.EventWiringFacility"&gt;Castle.EventWiringFacility&lt;/a&gt; &amp;ndash; Windsor&amp;rsquo;s &lt;a href="http://docs.castleproject.org/Windsor.Event-Wiring-Facility.ashx" target="_blank"&gt;Event Wiring facility&lt;/a&gt; (extracted out of Castle.Windsor.dll)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nuget.org/List/Packages/Castle.FactorySupportFacility"&gt;Castle.FactorySupportFacility&lt;/a&gt;&amp;ndash; Windsor&amp;rsquo;s &lt;a href="http://docs.castleproject.org/Windsor.Factory-Support-Facility.ashx" target="_blank"&gt;Factory Support facility&lt;/a&gt; (extracted out of Castle.Windsor.dll)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope this will make it easier for everyone to test drive Windsor. And if you find any issues, have any suggestions or ideas, do not hesitate to bring them up, either on our &lt;a href="http://groups.google.com/group/castle-project-users" target="_blank"&gt;google group&lt;/a&gt;, or &lt;a href="http://issues.castleproject.org/dashboard" target="_blank"&gt;issue tracker&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68165" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category></item><item><title>Simple guide to running Git server on Windows, in local network (kind of)</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/08/20/simple-guide-to-running-git-server-on-windows-in-local-network-kind-of.aspx</link><pubDate>Sat, 20 Aug 2011 07:50:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68118</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68118</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/08/20/simple-guide-to-running-git-server-on-windows-in-local-network-kind-of.aspx#comments</comments><description>&lt;p&gt;Last year I found myself in a sudden and quick need to set up working environment for a team of four, and as I like Git very much, I wanted to use it as our VCS. The problem was, we weren&amp;rsquo;t allowed to use any third party provider, so GitHub was off the table. As I searched the Internet there were a few guides to set up team Git environment on Windows, but they all seemed very complicated and time consuming. For our modest needs we experimented a little and came up with a solution that was very simple, didn&amp;rsquo;t require any additional software to be installed anywhere and worked like a charm.&lt;/p&gt;
&lt;p&gt;Recently I used it again on my current engagement, and one of my colleagues suggested I should blog it, so here goes.&lt;/p&gt;
&lt;h3&gt;Ready, steady, go&lt;/h3&gt;
&lt;p&gt;The guide assumes you already have your local Git set up. For that, there are plenty of resources on the Internet, including &lt;a href="http://kozmic.pl/2011/01/26/git-tooling-for-net-developers/" target="_blank"&gt;my own blogpost about Windows Git tooling&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The entire tricks works like this &amp;ndash; expose folder containing your shared Git repository as Windows network share.&lt;/p&gt;
&lt;h3&gt;Step one &amp;ndash; bare git repository&lt;/h3&gt;
&lt;p&gt;There are two twists to the entire solution &amp;ndash; one of them is &amp;ndash; your shared repository needs to be initialized with --bare flag.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/git_5F00_bare_5F00_repository_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="git_bare_repository" alt="git_bare_repository" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/git_5F00_bare_5F00_repository_5F00_thumb.png" height="375" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Step two &amp;ndash; Windows share&lt;/h3&gt;
&lt;p&gt;Second step is to expose the folder with our newly created repository on the Windows share. You also use your standard Windows mechanisms to control and limit access to the folder (make sure you give the developers write access!).&lt;/p&gt;
&lt;h3&gt;Step three &amp;ndash; Map the share as network drive&lt;/h3&gt;
&lt;p&gt;This step is perhaps not exactly necessary but I couldn&amp;rsquo;t get it to work otherwise, so here comes the second twist. In order for your developers to be able to access the shared folder via Git they need to map it as network drive.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sshot_2D00_10_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="sshot-10" alt="sshot-10" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sshot_2D00_10_5F00_thumb.png" height="464" width="632" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;Step four &amp;ndash; Add remote repository in Git and code away&lt;/h3&gt;
&lt;p&gt;Last step is the standard Git procedure &amp;ndash; every developer on your team needs to add the repository sitting under their newly created network drive as remote. Notice the use of &amp;ldquo;file:///&amp;rdquo; prefix in front of the mapped drive name.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sshot_2D00_11_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="sshot-11" alt="sshot-11" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sshot_2D00_11_5F00_thumb.png" height="375" width="644" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Step five&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s all. I hope you find it useful, and if you know a way to eliminate step three, let me know in the comments.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68118" width="1" height="1"&gt;</description></item><item><title>Windsor 3 beta 1 is released (along with other goodies)</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/08/15/windsor-3-beta-1-is-released-along-with-other-goodies.aspx</link><pubDate>Mon, 15 Aug 2011 10:49:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:68106</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=68106</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/08/15/windsor-3-beta-1-is-released-along-with-other-goodies.aspx#comments</comments><description>&lt;p&gt;&lt;img src="http://castleproject.org/images/wc_logo.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The title says it all. If you can&amp;rsquo;t wait grab the binaries &lt;a href="http://sourceforge.net/projects/castleproject/files/Windsor/3.0/Castle.Windsor.3.0.0.beta1.zip/download%20" target="_blank"&gt;here (Windsor with Castle Core and facilities)&lt;/a&gt; and &lt;a href="http://sourceforge.net/projects/castleproject/files/Core/3.0/Castle.Core.3.0.0.beta1.zip/download" target="_blank"&gt;here (just Core)&lt;/a&gt;. Nuget package will hopefully follow soon.&lt;/p&gt;
&lt;h3&gt;What&amp;rsquo;s in it?&lt;/h3&gt;
&lt;p&gt;This is a major release and there&amp;rsquo;s quite a lot of new features, as well as some significant changes under the covers. &lt;a href="http://docs.castleproject.org/Windsor.Whats-New-In-Windsor-3.ashx" target="_blank"&gt;There&amp;rsquo;s a high level overview of highlights for the release in the wiki&lt;/a&gt;, so please have a look there. More detailed changelog, and list of breaking changes is available as part of the package.&lt;/p&gt;
&lt;p&gt;Remember it&amp;rsquo;s a beta release. Documentation and samples are still being updated and some features are not yet implemented or not fully baked. However it is very important that you don&amp;#39;t wait for the final release to upgrade, so that we can find and fix all the issues before final release. I&amp;#39;m not asking you to use it in production, but I&amp;#39;d really appreciate if you&amp;#39;d take the time to branch your apps, try to upgrade, run your unit tests, play with new version, and report any issues you may find. And ask your colleagues, friends and random people on the street to do the same!&lt;/p&gt;
&lt;p&gt;And if you find any issues, &lt;a href="http://issues.castleproject.org" target="_blank"&gt;do report them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;   &lt;br /&gt;Have fun and happy coding,     &lt;br /&gt;I hope you like it&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=68106" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/.NET/default.aspx">.NET</category><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/IoC/default.aspx">IoC</category></item><item><title>What's new in Windsor 3: Container debugger diagnostics improvements</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/04/25/what-s-new-in-windsor-3-container-debugger-diagnostics-improvements.aspx</link><pubDate>Sun, 24 Apr 2011 23:56:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67100</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=67100</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/04/25/what-s-new-in-windsor-3-container-debugger-diagnostics-improvements.aspx#comments</comments><description>&lt;blockquote&gt;As we&amp;#39;re nearing the release date of &lt;a href="http://docs.castleproject.org/" target="_blank"&gt;Castle Windsor&lt;/a&gt; 3.0 (codename Wawel) I will be blogging about some of the new features and improvements introduced in the new version. &lt;/blockquote&gt;
&lt;p&gt;In the previous post I introduced one new diagnostic, and in this post we&amp;rsquo;ll explore other improvements in this area.&lt;/p&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;In the screenshot below (and all other) the upper window is Windsor 2.5, lower window is Windsor 3. All screenshots were taken running one of open source applications.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_2.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_thumb.png" border="0" height="330" width="732" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;As you can see there are some additional diagnostics present in the new version. Altogether the number rose from 4 in previous version to 7 in Wawel (you&amp;rsquo;re not seeing &lt;a href="http://docs.castleproject.org/Windsor.Debugger-views.ashx" target="_blank"&gt;all of them&lt;/a&gt; in the screenshots above because some of them only activate if they have something to show). The new ones are:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Default component per service&lt;/i&gt; &amp;ndash; if you have multiple components exposing one service this will show you which one of them is the default (that is which one will be used primarily to satisfy dependencies of that type). &lt;/li&gt;
&lt;li&gt;&lt;i&gt;Potential Service Locator usage &lt;/i&gt;&amp;ndash; &lt;a href="http://kozmic.pl/2011/04/24/whats-new-in-windsor-3-service-locator-usage-detection/" target="_blank"&gt;was discussed previously&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Objects tracked by release policy&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_6.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_thumb_5F00_2.png" border="0" height="203" width="735" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This one is pretty self explanatory. It shows you all objects tracked by release policy in your container, grouped by component. Do not underestimate the value of it. This is a fantastic tool for locating objects with mismanaged lifetime (in other words &amp;ndash; objects that should have been released but weren&amp;rsquo;t). If you see a number next to any of your components is suspiciously high or rising you may have just discovered a flaw in lifetime management in your app.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is worth noting that there were some significant changes around release policies in Windsor 3 and what is tracked by the policy has changed as well. Those changes will be covered in a future post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Components view&lt;/h3&gt;
&lt;p&gt;Most of the debugger views deals with showing components and there are some improvements in this area. Let&amp;rsquo;s go through most notable of them.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_4.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/image_5F00_thumb_5F00_1.png" border="0" height="474" width="735" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Top level view no longer shows a sequence number as &amp;ldquo;Name&amp;rdquo;. The number had no real meaning and we&amp;rsquo;re showing instead a much more important information &amp;ndash; lifestyle of the component. &lt;/li&gt;
&lt;li&gt;If lifestyle was not set explicitly (and Windsor falls back to its default for it) there will be an additional star (*) next to the lifestyle, like the &amp;ldquo;Now&amp;rdquo; component on the screenshot. &lt;/li&gt;
&lt;li&gt;How we display the component was also greatly simplified to make it much more readable.      
&lt;ul&gt;
&lt;li&gt;We&amp;rsquo;re not showing the name Windsor&amp;rsquo;s using for the component, unless you explicitly set it. Otherwise it&amp;rsquo;s just noise. &lt;/li&gt;
&lt;li&gt;We&amp;rsquo;re showing C#-ified names of types so that they are much easier to read. &lt;/li&gt;
&lt;li&gt;To show open generic services we put dots (&amp;middot;) around generic parameters, so that they stand out from normal types. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Several other more minor improvements were introduced as well, but I won&amp;rsquo;t go into too much detail here.&lt;/p&gt;
&lt;h3&gt;Accessing diagnostics in code&lt;/h3&gt;
&lt;p&gt;Ever since the feature was introduced there were requests to provide programmable access to those diagnostics. It is now possible. Thanks to changes in internal infrastructure you can use new IDiagnostic&amp;lt;&amp;gt; interface (and it&amp;rsquo;s subinterfaces) to write code like this:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var host = Container.Kernel.GetSubSystem(SubSystemConstants.DiagnosticsKey) &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IDiagnosticsHost;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var diagnostic = host.GetDiagnostic&amp;lt;IUsingContainerAsServiceLocatorDiagnostic&amp;gt;();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;var serviceLocators = diagnostic.Inspect();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;Assert.IsEmpty(serviceLocators);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I hope you&amp;rsquo;ll find all of those improvements useful.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67100" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category></item><item><title>What's new in Windsor 3: Service Locator usage detection</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/04/24/what-s-new-in-windsor-3-service-locator-usage-detection.aspx</link><pubDate>Sun, 24 Apr 2011 09:41:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:67092</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=67092</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/04/24/what-s-new-in-windsor-3-service-locator-usage-detection.aspx#comments</comments><description>&lt;blockquote&gt;
&lt;p&gt;As we&amp;#39;re nearing the release date of &lt;a href="http://docs.castleproject.org/" target="_blank"&gt;Castle Windsor&lt;/a&gt; 3.0 (codename Wawel) I will be blogging about some of the new features and improvements introduced in the new version.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;One of the features that were introduced in current version 2.5 was support for &lt;a href="http://kozmic.pl/2010/07/02/new-castle-windsor-feature-ndash-debugger-diagnostics/" target="_blank"&gt;debugger diagnostic views&lt;/a&gt; in Windsor.&lt;/p&gt;
&lt;p&gt;In Wawel one of the improvements is addition of a new diagnostic - detection of cases where the container is being used as Service Locator. For those unfamiliar with what Service Locator is, it&amp;#39;s an approach that breaks the basic rule of Inversion of Control, by explicitly calling out to the container from within application.&lt;/p&gt;
&lt;h3&gt;Here&amp;#39;s where I tell you Service Locator is bad&lt;/h3&gt;
&lt;p&gt;I spent last two days reading through the &lt;a href="http://stackoverflow.com" rel="nofollow"&gt;StackOverflow&lt;/a&gt; archive of IoC related questions and one of the most common sources of problems is that container is being used as Service Locator.&lt;/p&gt;
&lt;p&gt;I wrote why Service Locator (particularly when implemented via IoC container) is a bad idea on few occasions (for example &lt;a href="http://kozmic.pl/2010/06/22/how-i-use-inversion-of-control-containers-ndash-pulling-from/"&gt;here&lt;/a&gt;). Also &lt;a href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx"&gt;Mark has a good overview&lt;/a&gt; of drawbacks of this approach so I won&amp;#39;t rehash it again.&lt;/p&gt;
&lt;p&gt;Good news is - even if someone from your team starts using the container as Service Locator, Windsor will now help you detect those cases.&lt;/p&gt;
&lt;h3&gt;Here&amp;#39;s where I give you an example&lt;/h3&gt;
&lt;p&gt;Take a look at the following class:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;[Singleton]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ComponentFactory&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IKernel kernel;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ComponentFactory(IKernel kernel)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.kernel = kernel;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt; &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Create(String name)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; kernel.Resolve&amp;lt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;&amp;gt;(name);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It is part of the application layer (and not infrastructure layer) and as such it should not be aware of the container, yet it depends on IKernel. Also quick look at its Create method is enough to see that it most likely is passed around throughout the application and used to pull components from the container without giving it much thought, which as you&amp;#39;re surely guessing by now is a recipe for trouble.&lt;/p&gt;
&lt;h3&gt;Here&amp;#39;s where I show you how it looks&lt;/h3&gt;
&lt;p&gt;If you navigate in debug mode to a container instance where components like the one described above exists a new entry in the debugger view will appear listing those components.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sl_2D00_detection_5F00_2.png"&gt;&lt;img style="border-right-width:0px;margin:5px 0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="sl-detection" alt="sl-detection" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/krzysztof_5F00_kozmic/sl_2D00_detection_5F00_thumb.png" border="0" height="194" width="586" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Here&amp;#39;s where I tell you how it works&lt;/h3&gt;
&lt;p&gt;Windsor doesn&amp;#39;t have the whole picture of your application, so it can only detect a subset of cases of Service Locator usage. In particular it is unable to detect the case when a Service Locator is built completely on top of the container as commonly found, where container is assigned to a public field of a static class and accessed through that field.&lt;/p&gt;
&lt;p&gt;Since Windsor only knows about the components you register with it, it looks for components that depend on the container and are not extending infrastructure of the container itself (like for example Interceptors are). All such components are flagged as potential service locator and presented to you.&lt;/p&gt;
&lt;p&gt;I hope you&amp;#39;ll find this feature useful.&lt;/p&gt;
&lt;h3&gt;Here&amp;#39;s where you tell me what you think&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=67092" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Castle/default.aspx">Castle</category></item><item><title>Working with NHibernate without default constructors</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/20/working-with-nhibernate-without-default-constructors.aspx</link><pubDate>Sun, 20 Mar 2011 05:58:02 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66719</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=66719</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/20/working-with-nhibernate-without-default-constructors.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://kozmic.pl/2011/03/19/nhibernate-and-default-constructors/"&gt;the previous post &lt;/a&gt;we established that the usage of default constructor required by NHibernate is theoretically not required. The fact that NHibernate does use them though has to do with technical limitations of CLR. Turns out in most cases there is a workaround, which is not perfect but was a fun experiment to implement.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The code presented here is just an experiment. It is not of production quality – it is merely a proof of concept so if you use it in production and the world blows up, don’t blame me.&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;Interceptor&lt;/h3&gt;  &lt;p&gt;The place that NHibernate lets you plug into to instantiate entities and components as they are pulled from database is in NHibernate’s IInterceptor (not to be confused with Castle DynamicProxy IInerceptor) interface and its instantiate method. NHibernate has also a IObjectsFactory interface but that one is used to instantiate everything including NHibernate’s own infrastructure (like IUserTypes for example) and we want to override only activation of entities and components.&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ExtensibleInterceptor : EmptyInterceptor&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; INHibernateActivator activator;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ISessionFactory SessionFactory { get; set; }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ExtensibleInterceptor(INHibernateActivator activator)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activator = activator;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Instantiate(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; clazz, EntityMode entityMode, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; id)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (entityMode == EntityMode.Poco)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            var type = Type.GetType(clazz);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (type != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; activator.CanInstantiate(type))&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                var instance = activator.Instantiate(type);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                SessionFactory.GetClassMetadata(clazz).SetIdentifier(instance, id, entityMode);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; instance;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.Instantiate(clazz, entityMode, id);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The code here is straightforward. The INHibernateActivator is a custom interface that we’ll discuss in details below. That’s where the actual activation happens. We’re also using ISessionFactory so that we properly set the id of retrieved instance.&lt;/p&gt;

&lt;h3&gt;Proxy validator&lt;/h3&gt;

&lt;p&gt;Turns out that is not enough. In the interceptor we activate objects we fully obtain from the database. However big part of NHibernate performance optimisation is to ensure we don’t load more data that we need (a.k.a. lazy loading) and to do it transparently NHibernate uses proxies.&lt;/p&gt;

&lt;p&gt;For every persistent type NHibernate uses object called proxy validator to ensure object meets all the requirements it has to be able to properly proxy a type and that work is done by IProxyValidator.&lt;/p&gt;

&lt;p&gt;Part of the work of proxy validator is to check for default constructor so we need to override that logic to reassure NHibernate we have things under control.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CustomProxyValidator : DynProxyTypeValidator&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;const&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; iDontCare = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; HasVisibleDefaultConstructor(Type type)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; iDontCare;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Proxy factory&lt;/h3&gt;

&lt;p&gt;Now that we told NHibernate we can handle proxying types without default constructor it’s time to write code that actually does it. That’s the task of ProxyFactory which uses Castle DynamicProxy under the cover.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CustomProxyFactory : AbstractProxyFactory&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IInternalLogger log = LoggerProvider.LoggerFor(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt; (CustomProxyFactory));&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; DefaultProxyBuilder proxyBuilder = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DefaultProxyBuilder();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; INHibernateActivator activator;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CustomProxyFactory(INHibernateActivator activator)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.activator = activator;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; INHibernateProxy GetProxy(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; id, ISessionImplementor session)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            var proxyType = IsClassProxy&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                ? proxyBuilder.CreateClassProxyType(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    PersistentClass,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    Interfaces,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    ProxyGenerationOptions.Default)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                : proxyBuilder.CreateInterfaceProxyTypeWithoutTarget(&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    Interfaces[0],&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    Interfaces,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                    ProxyGenerationOptions.Default);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            var proxy = activator.Instantiate(proxyType);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            var initializer = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LazyInitializer(EntityName, PersistentClass, id, GetIdentifierMethod, SetIdentifierMethod,&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                                                    ComponentIdType, session);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            SetInterceptors(proxy, initializer);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            initializer._constructed = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (INHibernateProxy) proxy;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception e)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            log.Error(&lt;span style="color:#006080;"&gt;&amp;quot;Creating a proxy instance failed&amp;quot;&lt;/span&gt;, e);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; HibernateException(&lt;span style="color:#006080;"&gt;&amp;quot;Creating a proxy instance failed&amp;quot;&lt;/span&gt;, e);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; GetFieldInterceptionProxy()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var proxyGenerationOptions = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ProxyGenerationOptions();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var interceptor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; LazyFieldInterceptor();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        proxyGenerationOptions.AddMixinInstance(interceptor);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var proxyType = proxyBuilder.CreateClassProxyType(PersistentClass, Interfaces, proxyGenerationOptions);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var proxy = activator.Instantiate(proxyType);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        SetInterceptors(proxy, interceptor);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        SetMixin(proxy, interceptor);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; proxy;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SetInterceptors(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; proxy, &lt;span style="color:#0000ff;"&gt;params&lt;/span&gt; IInterceptor[] interceptors)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var field = proxy.GetType().GetField(&lt;span style="color:#006080;"&gt;&amp;quot;__interceptors&amp;quot;&lt;/span&gt;);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        field.SetValue(proxy, interceptors);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SetMixin(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; proxy, LazyFieldInterceptor interceptor)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var fields = proxy.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        var mixin = fields.Where(f =&amp;gt; f.Name.StartsWith(&lt;span style="color:#006080;"&gt;&amp;quot;__mixin&amp;quot;&lt;/span&gt;)).Single();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        mixin.SetValue(proxy, interceptor);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It is pretty standard and not very interesting. We’re again using the INHibernateActivator, we’ve yet to discuss, to create instances. Also since we’re not calling any constructors to do it, we have to set the proxy dependencies that would otherwise by provided via constructor inline. For that we’re using some internal knowledge about how DynamicProxy lays out its proxy types.&lt;/p&gt;

&lt;p&gt;Good news is – we’re almost there. Actually we might want to also override NHibernate reflection optimizer. As its name implies replaces some actions that are performed via reflection with faster, compiled versions. The default one works with assumption that default constructor is available and may fail otherwise but we can disable that feature for our simple proof of concept application.&lt;/p&gt;

&lt;h3&gt;Proxy factory factory&lt;/h3&gt;

&lt;p&gt;There’s one more step actually – we need to attach out proxy factory and proxy validator to session factory and we do that via ridiculously named IProxyFactoryFactory&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CustomProxyFactoryFactory : IProxyFactoryFactory&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IProxyFactory BuildProxyFactory()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomProxyFactory(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; NHibernateActivator());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; IsInstrumented(Type entityClass)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; IsProxy(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; entity)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; (entity &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; INHibernateProxy);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IProxyValidator ProxyValidator&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomProxyValidator(); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;h3&gt;Putting it all together&lt;/h3&gt;

&lt;p&gt;Now that we have all these pieces let’s see how we put them together (with some help from FluentNHibernate)&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var config = Fluently.Configure()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    .Mappings(c =&amp;gt; c.FluentMappings.AddFromAssemblyOf&amp;lt;Program&amp;gt;())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    .Database(MsSqlConfiguration.MsSql2008&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                .ConnectionString(s =&amp;gt; s.Database(&lt;span style="color:#006080;"&gt;&amp;quot;NHExperiment&amp;quot;&lt;/span&gt;).Server(&lt;span style="color:#006080;"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;).TrustedConnection())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;                .ProxyFactoryFactory&amp;lt;CustomProxyFactoryFactory&amp;gt;())&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    .BuildConfiguration();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var interceptor = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ExtensibleInterceptor(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; NHibernateActivator());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;config.Interceptor = interceptor;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;NHibernate.Cfg.Environment.UseReflectionOptimizer = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;var factory = config.BuildSessionFactory();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;interceptor.SessionFactory = factory;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;We set up our standard stuff – mapping and connection string. Then we need to tell NHibernate to use our custom ProxyFactoryFactory. Then we build configuration object and set our custom interceptor to it. Having done that we can build session factory and give the interceptor reference to the session factory. Certainly not the smoothest ride but gets the job done. Oh – and as I mentioned we disable reflection optimizer so that we don’t have to override yet another class (two actually).&lt;/p&gt;

&lt;p&gt;That is all it takes to be able to get rid of all the seemingly superfluous constructors and have a much simpler model.&lt;/p&gt;

&lt;h3&gt;Well not quite – what about the activator&lt;/h3&gt;

&lt;p&gt;Right – the activator. How do we make that happen? Here’s all the code in this class.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; NHibernateActivator : INHibernateActivator&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;{&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; CanInstantiate(Type type)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; Instantiate(Type type)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; FormatterServices.GetUninitializedObject(type);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;    }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Remember how I said that NHibernate can be viewed as fancy serializer? Here we make it obvious by using System.Runtime.Serialization.FormatterServices class to give us an uninitialized instance of given type. Uninitialized means that all the fields will be null or 0 and no code will be ran. This however is precisely what we want for the reasons outlined in previous post. We then throw the object to NHibernate machinery to perform all the necessary initialization for us, so that when the object is returned from the session it is fully created and usable. We could also implement a mechanism similar to one of the options that standard .NET serialization provides to allow the object to initialize its volatile state.&lt;/p&gt;

&lt;h5&gt;Final words&lt;/h5&gt;

&lt;p&gt;That is all it takes to make the model a bit more persistence ignorant. Like I said this approach won’t work always. It requires full trust environment and probably if you have complex volatile state the solution will be too simplistic. I would be interested to hear what do you think about the approach in general. Can you spot any severe shortcomings or flaws? Do you like it? Would you use it?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66719" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>NHibernate and default constructors</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/19/nhibernate-and-default-constructors.aspx</link><pubDate>Sat, 19 Mar 2011 08:48:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66718</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=66718</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/19/nhibernate-and-default-constructors.aspx#comments</comments><description>&lt;p&gt;One of the first things you learn about &lt;a href="http://nhforge.org" target="_blank"&gt;NHibernate&lt;/a&gt; is that in order for it to be able construct your instances and take advantage of lazy loading every persistent class must have&amp;nbsp; the default, parameterless constructor. This leads to having entities looking like this (standard blog with posts and comments example).&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Post&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IList&amp;lt;Comment&amp;gt; comments = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;Comment&amp;gt;();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; Blog blog;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    [Obsolete(&lt;span style="color:#006080;"&gt;&amp;quot;For NHibernate&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; Post()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;       &lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Post(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; title, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; body, Blog blog)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Blog = blog;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Title = title;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Body = body;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Published = DateTimeOffset.Now;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Id { get; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; DateTimeOffset Published { get; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Title { get; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Body { get; set; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; IEnumerable&amp;lt;Comment&amp;gt; Comments&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; comments; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; Blog Blog&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; blog; }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        set&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (blog != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color:#006080;"&gt;&amp;quot;already set&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            blog = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (blog != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                blog.AddPost(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    [EditorBrowsable(EditorBrowsableState.Never)]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;internal&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; AddComment(Comment comment)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        comments.Add(comment);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Notice the first constructor. It doesn&amp;rsquo;t do anything. As the obsolete message (which is out there to get compilation warning in case some developer accidently calls this constructor in their code) points out &amp;ndash; this constructor is there only so that NHibernate can do its magic. Some people do put there initialization logic for collections, (especially when you use automatic properties) but I use fields and initialize them inline. In that case the constructor is pretty much useless. I started thinking why is it even there and that perhaps it doesn&amp;rsquo;t really belong to the class. But let&amp;rsquo;s start at the beginning.&lt;/p&gt;
&lt;h3&gt;What is a constructor&lt;/h3&gt;
&lt;p&gt;As basic as the question may seem, it is useful to remind ourselves why we need constructors at all. &lt;a href="http://www.amazon.com/CLR-via-Dev-Pro-Jeffrey-Richter/dp/0735627045?SubscriptionId=0JTCV5ZMHMF7ZYTXGFR2&amp;amp;tag=krzkomicsblo-20&amp;amp;linkCode=xm2&amp;amp;camp=2025&amp;amp;creative=165953&amp;amp;creativeASIN=0735627045" target="_blank"&gt;The best book about C# and .NET&lt;/a&gt; defines them as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Constructors are special methods that allow an instance of a type to be initialized to a good state.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Notice two important things about this definition. First, it doesn&amp;rsquo;t say that constructor creates the instance or that constructors are the only way to create the instance. Second, constructors initialize newly created object to their initial state so that anything that uses the object afterwards deals with fully constructed, valid object.&lt;/p&gt;
&lt;h3&gt;Constructors and persistence&lt;/h3&gt;
&lt;p&gt;The above definition very well applies to the other constructor we have on the Post class. That constructor initializes the Post to a valid state. In this case valid means the following.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Post is part of a blog &amp;ndash; we can&amp;rsquo;t have a post that lives on its own. Our posts need to be part of a blog and we make this requirement explicit by requiring a Blog instance to be provided when constructing Post.&lt;/li&gt;
&lt;li&gt;Post requires a title and a body and that&amp;rsquo;s why we also require those two properties to be provided when constructing a post.&lt;/li&gt;
&lt;li&gt;Posts are usually displayed in a inverse chronological order hence we set the Published timestamp.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We do none of the above in the other, &amp;ldquo;nhibernate&amp;rdquo; constructor. That means that according to the definition of a constructor it is not really doing what a constructor is supposed to be doing. It is never used to construct an object.&lt;/p&gt;
&lt;h3&gt;Hydration&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s take a step back now. What NHibernate is doing with objects in nutshell is serialization. You create an object in your code and initialize it using constructor, do some stuff with it and then you save the object away, so that it can be retrieved later, after your app has been closed, or perhaps on another server instance. You save away the state of the object so that the state representation of the object can live longer than volatile, in-memory representation of the object. If you follow this path of though the next obvious conclusion is that if you have a load-balanced system and two server instances work with Post#123 they both are dealing with the same object, even though they are two separate machines.&lt;/p&gt;
&lt;p&gt;The conclusion of that is that when NHibernate is retrieving an object from the persistent store it is not constructing it. It is recreating an in-memory representation of an object that had been created and persisted previously.&amp;nbsp; Hence we are merely recreating object that already has a well known state and had been initialized and just providing different representation for it. This process is called hydration.&lt;/p&gt;
&lt;h3&gt;Persistent and Volatile state&lt;/h3&gt;
&lt;p&gt;The full picture is a bit more complicated than what I painted so far. The database and in-memory object are two representation of the same entity but they don&amp;rsquo;t have to be fully one to one. Specifically it is possible for the in-memory representation to have state beyond the persistent state. In other words the in-memory object may have some properties that are specific to it, and not relevant to the in-database representation. A convenient example that most people will be able to relate to would be a logger. Please don&amp;rsquo;t quote me as advocating using logging in your entities but logger is one of the things you may want to have on your in-memory object and use it while executing code in your application but then let them go once you no longer need the object and not persist them. If we had one in the Post class the empty constructor would change to the following:&lt;/p&gt;
&lt;div style="text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;border:1px solid silver;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;[Obsolete(&lt;span style="color:#006080;"&gt;&amp;quot;For NHibernate&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; Post()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    logger = LoggerProvider.LoggerFor(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Post));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If we don&amp;rsquo;t use constructor for recreation of the object, how can we get the logger in? How do we make NHibernate hold the contructor semantics and give us fully initialized object? Remember I said one way of looking at NHibernate from the object&amp;rsquo;s perspective is that&amp;rsquo;s just a fancy serializer/deserializer. Turns out serialization mechanism in .NET offers us four(that I know of, possibly more) ways of tacking this issue&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you can use serialization surrogate that knows how to recreate the full state of the object&lt;/li&gt;
&lt;li&gt;you can use &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ideserializationcallback.aspx" target="_blank"&gt;deserialization callback interface&lt;/a&gt; to be notified when the object has been fully deserialized and then initialize the volatile state.&lt;/li&gt;
&lt;li&gt;you can use &lt;a href="http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx" target="_blank"&gt;serialization callback attributes&lt;/a&gt; to be notified when various steps in the serialization/deserialization process happen and initialize the volatile state.&lt;/li&gt;
&lt;li&gt;you can use ISerializable interface and implement serialization constructor which is used to deserialize the object.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Notice that only one of those approaches uses special constructor. Since as we discussed NHibernate doesn&amp;rsquo;t really need the default constructor (in theory that is), can we really get rid of it? Turns one we can (in most cases), and we&amp;rsquo;ll look at how to do it in the next post.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66718" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/NHibernate/default.aspx">NHibernate</category></item><item><title>Testing conventions</title><link>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/09/testing-conventions.aspx</link><pubDate>Wed, 09 Mar 2011 03:52:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:66692</guid><dc:creator>Krzysztof Koźmic</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/krzysztof_kozmic/rsscomments.aspx?PostID=66692</wfw:commentRss><comments>http://devlicio.us/blogs/krzysztof_kozmic/archive/2011/03/09/testing-conventions.aspx#comments</comments><description>&lt;p&gt;I already blogged about the topic of validating conventions in the past (&lt;a href="http://kozmic.pl/2010/04/08/build-your-conventions/" target="_blank"&gt;here&lt;/a&gt; and &lt;a href="http://kozmic.pl/2010/03/21/validate-your-conventions/" target="_blank"&gt;here&lt;/a&gt;). Doing this has been a fantastic way of keeping consistency across codebases I&amp;rsquo;ve worked on, and several of my colleagues at &lt;a href="http://readify.net/" target="_blank"&gt;Readify&lt;/a&gt; adopted this approach with great success.&lt;/p&gt;
&lt;p&gt;Recently I found myself using this approach even more often and in scenarios I didn&amp;rsquo;t think about initially. Take this two small tests I wrote today for Windsor.&lt;/p&gt;
&lt;div style="border:1px solid silver;text-align:left;padding:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;max-height:700px;font-size:8pt;overflow:auto;cursor:text;" id="codeSnippetWrapper"&gt;
&lt;div style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;" id="codeSnippet"&gt;
&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;[TestFixture]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ConventionVerification&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;{&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    [Test]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Obsolete_members_of_kernel_are_in_sync()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var message = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var kernelMap = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(DefaultKernel).GetInterfaceMap(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IKernel));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; kernelMap.TargetMethods.Length; i++)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            var interfaceMethod = kernelMap.InterfaceMethods[i];&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            var classMethod = kernelMap.TargetMethods[i];&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            Scan(interfaceMethod, classMethod, message);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Assert.IsEmpty(message.ToString(), message.ToString());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    [Test]&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Obsolete_members_of_windsor_are_in_sync()&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var message = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var kernelMap = &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(WindsorContainer).GetInterfaceMap(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IWindsorContainer));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (var i = 0; i &amp;lt; kernelMap.TargetMethods.Length; i++)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            var interfaceMethod = kernelMap.InterfaceMethods[i];&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            var classMethod = kernelMap.TargetMethods[i];&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            Scan(interfaceMethod, classMethod, message);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        Assert.IsEmpty(message.ToString(), message.ToString());&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Scan(MethodInfo interfaceMethod, MethodInfo classMethod, StringBuilder message)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var obsolete = EnsureBothHave&amp;lt;ObsoleteAttribute&amp;gt;(interfaceMethod, classMethod, message);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (obsolete.Item3)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (obsolete.Item1.IsError != obsolete.Item2.IsError)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Different error levels for {0}&amp;quot;&lt;/span&gt;, interfaceMethod));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (obsolete.Item1.Message != obsolete.Item2.Message)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Different message for {0}&amp;quot;&lt;/span&gt;, interfaceMethod));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;\t interface: {0}&amp;quot;&lt;/span&gt;, obsolete.Item1.Message));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;\t class    : {0}&amp;quot;&lt;/span&gt;, obsolete.Item2.Message));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var browsable = EnsureBothHave&amp;lt;EditorBrowsableAttribute&amp;gt;(interfaceMethod, classMethod, message);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (browsable.Item3 == &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;EditorBrowsable not applied to {0}&amp;quot;&lt;/span&gt;, interfaceMethod));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (browsable.Item1.State != browsable.Item2.State || browsable.Item2.State != EditorBrowsableState.Never)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Different/wrong browsable states for {0}&amp;quot;&lt;/span&gt;, interfaceMethod));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;&amp;nbsp;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; Tuple&amp;lt;TAttribute, TAttribute, &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&amp;gt; EnsureBothHave&amp;lt;TAttribute&amp;gt;(MethodInfo interfaceMethod, MethodInfo classMethod, StringBuilder message)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TAttribute : Attribute&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var fromInterface = interfaceMethod.GetAttributes&amp;lt;TAttribute&amp;gt;().SingleOrDefault();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var fromClass = classMethod.GetAttributes&amp;lt;TAttribute&amp;gt;().SingleOrDefault();&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        var bothHaveTheAttribute = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (fromInterface != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (fromClass == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Method {0} has {1} on the interface, but not on the class.&amp;quot;&lt;/span&gt;, interfaceMethod, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TAttribute)));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                bothHaveTheAttribute = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (fromClass != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            {&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;                message.AppendLine(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#006080;"&gt;&amp;quot;Method {0} has {1}  on the class, but not on the interface.&amp;quot;&lt;/span&gt;, interfaceMethod, &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(TAttribute)));&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;            bothHaveTheAttribute = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Tuple.Create(fromInterface, fromClass, bothHaveTheAttribute);&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:white;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;    }&lt;/pre&gt;

&lt;pre style="border-style:none;text-align:left;padding:0px;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;,courier,monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;All they do is ensure that whenever I obsolete a method on the container, I do that consistently between the interface and the class that implements it (setting the same warning message, and the same warning/error flag state). It also validates that I hide the obsolete method from Intellisense for people who have the option enabled in their Visual Studio.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Those are kinds of things, that are important, but they neither cause a compiler error, or compiler warning, nor do they fail at runtime. Those are kinds of things you can validate in a test. Those are small things that make a big difference, and having a comprehensive battery of tests for conventions in your application, can greatly improve confidence and morale of the team.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=66692" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/krzysztof_kozmic/archive/tags/Design/default.aspx">Design</category></item></channel></rss>
