<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Jason Dentler</title>
	
	<link>http://jasondentler.com/blog</link>
	<description>I'm just here for the code</description>
	<lastBuildDate>Fri, 30 Jul 2010 22:49:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/BasiclyEverything" /><feedburner:info uri="basiclyeverything" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>I’m on Hanselminutes talking about NH 3</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/wC8MJrqdZG0/</link>
		<comments>http://jasondentler.com/blog/2010/07/im-on-hanselminutes-talking-about-nh-3/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 22:49:05 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Cookbook]]></category>
		<category><![CDATA[Hanselminutes]]></category>
		<category><![CDATA[Podcast]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/07/im-on-hanselminutes-talking-about-nh-3/</guid>
		<description><![CDATA[Our friend Fabio was up to no good earlier this week, and as a result, I ended up on Hanselminutes talking about NHibernate 3 with Scott Hanselman. 
We talk about where to get NHibernate, a quick overview of starting an NH app, the state of NHForge, tooling and commercial support, the NHibernate ecosystem, and we [...]]]></description>
			<content:encoded><![CDATA[<p>Our friend <a href="http://fabiomaulo.blogspot.com/" target="_blank">Fabio</a> was up to no good earlier this week, and as a result, I ended up on <a href="http://www.hanselminutes.com" target="_blank">Hanselminutes</a> talking about NHibernate 3 with <a href="http://www.hanselman.com/blog/" target="_blank">Scott Hanselman</a>. </p>
<p>We talk about where to get <a href="http://nhforge.org" target="_blank">NHibernate</a>, a quick overview of starting an NH app, the state of NHForge, tooling and commercial support, the NHibernate ecosystem, and we compare the new EF “unicorn” features to features in NHibernate.</p>
<p>So, <a href="http://hanselminutes.com/default.aspx?showID=243" target="_blank">go listen now</a>. </p>
<p>Thank you Scott, Fabio, and the guys at Pwop! I think the show turned out great, despite my nerves.</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/wC8MJrqdZG0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/07/im-on-hanselminutes-talking-about-nh-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/07/im-on-hanselminutes-talking-about-nh-3/</feedburner:origLink></item>
		<item>
		<title>NHibernate 3.0 Alpha 1 released.</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/Z9xBlxzIFVw/</link>
		<comments>http://jasondentler.com/blog/2010/07/nhibernate-3-0-alpha-1-released/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 12:22:29 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/07/nhibernate-3-0-alpha-1-released/</guid>
		<description><![CDATA[This morning, Fabio released the official NH 3 Alpha 1 binaries and source on SourceForge. Go play! 
&#160;
Oh, yeah. Frist!!!!!1!!!!one!!
]]></description>
			<content:encoded><![CDATA[<p>This morning, <a href="http://fabiomaulo.blogspot.com/" target="_blank">Fabio</a> released the <a href="http://sourceforge.net/projects/nhibernate/files/" target="_blank">official NH 3 Alpha 1 binaries and source</a> on SourceForge. Go play! </p>
<p>&#160;</p>
<p>Oh, yeah. Frist!!!!!1!!!!one!!</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/Z9xBlxzIFVw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/07/nhibernate-3-0-alpha-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/07/nhibernate-3-0-alpha-1-released/</feedburner:origLink></item>
		<item>
		<title>Visual Studio 2010 publish / web.config conflict</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/8E26QzMKXB8/</link>
		<comments>http://jasondentler.com/blog/2010/07/visual-studio-2010-publish-web-config-conflict/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 17:55:04 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/07/visual-studio-2010-publish-web-config-conflict/</guid>
		<description><![CDATA[Yesterday, I suddenly and mysteriously started getting this error message when trying to build my ASP.NET MVC 2 application. 
It is an error to use a section registered as allowDefinition=&#8217;MachineToApplication&#8217; beyond application level

It’s mysterious because I didn’t change my .configs. Double-clicking on the error took me to the &#60;authentication&#62; section of the web.config at the [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, I suddenly and mysteriously started getting this error message when trying to build my ASP.NET MVC 2 application. </p>
<blockquote><p>It is an error to use a section registered as allowDefinition=&#8217;MachineToApplication&#8217; beyond application level</p>
</blockquote>
<p>It’s mysterious because I didn’t change my .configs. Double-clicking on the error took me to the &lt;authentication&gt; section of the web.config at the root of my app. It’s legal to define it there. Strange.</p>
<p>After trying a few different things, I started commenting out larger and larger chunks of my config, until it looked like this:</p>
<pre class="brush:xml">&lt;configuration&gt;&lt;!-- ... --&gt;&lt;/configuration&gt;</pre>
<p>Clearly, the error message was wrong.</p>
<p>As it turns out, this was my first time to build the app after using VS 2010’s Publish feature to throw it up on a server for a demo &amp; user testing. Publishing packages up the website under .\obj\Release\Package, and it doesn’t clean up after itself. The next time I built my application, the compiler barked because I had a web.config hidden a few layers deep under .\obj with an &lt;authentication&gt; element. </p>
<p>I discovered the issue when I compiled my app at the command line and saw the full path on the error message. So, kill the .\obj folder after each publish, and you’ll never have this trouble.</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/8E26QzMKXB8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/07/visual-studio-2010-publish-web-config-conflict/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/07/visual-studio-2010-publish-web-config-conflict/</feedburner:origLink></item>
		<item>
		<title>NHibernate Auditing v3 – Poor Man’s Envers</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/xAkfs2n7Txg/</link>
		<comments>http://jasondentler.com/blog/2010/07/nhibernate-auditing-v3-poor-mans-envers/#comments</comments>
		<pubDate>Sun, 04 Jul 2010 19:40:41 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/07/nhibernate-auditing-v3-poor-mans-envers/</guid>
		<description><![CDATA[First, let me explain the title of this post. The Hibernate folks – you know, that NHibernate knock off written in the Java (pronounced “ex em el”) programming language – have a project called Envers. Among other things, It audits changes to entities, then allows you to easily retrieve the entity as it was at [...]]]></description>
			<content:encoded><![CDATA[<p>First, let me explain the title of this post. The Hibernate folks – you know, that <a href="http://nhforge.org" target="_blank">NHibernate</a> knock off written in the Java (pronounced “ex em el”) programming language – have a project called Envers. Among other things, It audits changes to entities, then allows you to easily retrieve the entity as it was at any previous point in time. </p>
<p>Well, Simon Duduica is porting this over to .NET and NHibernate, and he’s making some AMAZING progress. On June 28th, he shared this news with us on the NH Contrib development group:</p>
<blockquote><p>Hi everybody,</p>
<p>I have news regarding Envers.NET. I&#8217;ve commited a version that works in basic tests for CUD operations, with entities that have relationships between them, also with entities that are not audited. To make things work I had to make two small modifications of NHibernate, both modifications were tested running all NHibernate unit tests and they all passed. I already sent the first modification to Fabio and the second I will send this evening. I would like to thank Tuna for helping me out with good advices when I was stuck <img src='http://jasondentler.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
</blockquote>
<p>&#160;</p>
<p>So, on to the topic of this post. For <u>NHibernate 3.0 Cookbook</u>, I’ve included a section that explains how to use NHibernate to generate audit triggers. Originally, I had planned to use the code from <a href="http://jasondentler.com/blog/2009/12/generate-audit-triggers-from-nhibernate-v2/" target="_blank">my previous blog post on the topic</a>, but I didn’t like its structure. I also didn’t want to include all that plumbing code in the printed book. Instead, I’ve rewritten and contributed the “framework” code to <a href="http://code.google.com/p/unhaddins/" target="_blank">uNHAddIns</a>. The “how-to use it” is explained in the book, so I won’t explain it here.</p>
<p>Today, I was writing an integration test for this contribution, and thought the idea was worth sharing. I have a simple Cat class:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://jasondentler.com/blog/wp-content/uploads/2010/07/ClassDiagram1.png" width="163" height="143" /> </p>
<p>When I do anything to this cat, in addition to the normal INSERT, UPDATE, or DELETE, a database trigger records that action in a table called CatAudit:</p>
<p><a href="http://jasondentler.com/blog/wp-content/uploads/2010/07/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jasondentler.com/blog/wp-content/uploads/2010/07/image_thumb.png" width="206" height="159" /></a> </p>
<p>I wanted an easy way to investigate the contents of this table to prove that my audit triggers worked. Here’s what I came up with, along with help from Jose Romaniello (@jfroma). First, I created a class to match this table:</p>
<p><a href="http://jasondentler.com/blog/wp-content/uploads/2010/07/ClassDiagram11.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ClassDiagram1" border="0" alt="ClassDiagram1" src="http://jasondentler.com/blog/wp-content/uploads/2010/07/ClassDiagram1_thumb.png" width="150" height="240" /></a> </p>
<p>Next, I mapped it, made it readonly and excluded it from hbm2ddl with this mapping:</p>
<pre class="brush:xml">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;hibernate-mapping xmlns=&quot;urn:nhibernate-mapping-2.2&quot;
				   assembly=&quot;uNhAddIns.Test&quot;
				   namespace=&quot;uNhAddIns.Test.Audit.TriggerGenerator&quot;&gt;
  &lt;typedef class=&quot;NHibernate.Type.EnumStringType`1[[uNhAddIns.Audit.TriggerGenerator.TriggerActions, uNhAddIns]], NHibernate&quot;
           name=&quot;triggerActions&quot; /&gt;
  &lt;class name=&quot;CatAudit&quot;
         mutable=&quot;false&quot;
         schema-action=&quot;none&quot;&gt;
    &lt;composite-id&gt;
      &lt;key-property name=&quot;Id&quot; /&gt;
      &lt;key-property name=&quot;AuditUser&quot; /&gt;
      &lt;key-property name=&quot;AuditTimestamp&quot; /&gt;
    &lt;/composite-id&gt;
    &lt;property name=&quot;Color&quot;/&gt;
    &lt;property name=&quot;AuditOperation&quot; type=&quot;triggerActions&quot; /&gt;
  &lt;/class&gt;

&lt;/hibernate-mapping&gt;</pre>
<p>I made it readonly by setting mutable=&quot;false&quot; and excluded it from hbm2ddl with schema-action=&quot;none&quot;. That’s it!</p>
<p>By the way, the &lt;typedef&gt; along with type=&quot;triggerActions&quot; just tells NHibernate I&#8217;ve stored my TriggerActions enum values as strings, not numbers.</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/xAkfs2n7Txg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/07/nhibernate-auditing-v3-poor-mans-envers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/07/nhibernate-auditing-v3-poor-mans-envers/</feedburner:origLink></item>
		<item>
		<title>Reviewed: NHibernate 2 Beginner’s Guide</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/KBY2CoWUD6I/</link>
		<comments>http://jasondentler.com/blog/2010/06/review-nhibernate-2-beginners-guide/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 16:22:09 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/06/review-nhibernate-2-beginners-guide/</guid>
		<description><![CDATA[ 
NHibernate 2 Beginner’s Guide by Aaron Cure is the 3rd published book about NHibernate. Each example in this book is presented in both C# and VB.NET, and some knowledge of these languages, as well as some basic understanding of ASP.NET WebForms is assumed. 
Overall, for OR/M beginners and Entity Framework refugees, it provides a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jasondentler.com/blog/wp-content/uploads/2010/06/8907OS_MockupCover_Beginersguide2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="8907OS_MockupCover_Beginers guide(2)" border="0" alt="8907OS_MockupCover_Beginers guide(2)" align="left" src="http://jasondentler.com/blog/wp-content/uploads/2010/06/8907OS_MockupCover_Beginersguide2_thumb.jpg" width="198" height="244" /></a> </p>
<p><a href="https://www.packtpub.com/nhibernate-2-x-beginners-guide/book" target="_blank">NHibernate 2 Beginner’s Guide</a> by Aaron Cure is the 3rd published <a href="http://nhforge.org/content/Books.aspx" target="_blank">book about NHibernate</a>. Each example in this book is presented in both C# and VB.NET, and some knowledge of these languages, as well as some basic understanding of ASP.NET WebForms is assumed. </p>
<p>Overall, for OR/M beginners and Entity Framework refugees, it provides a good foundation of NHibernate knowledge. The examples are simple enough to understand, and can easily be applied to real-world scenarios. There are, however, a few points of concern, such as the database-first approach, and the prescription of code generation.</p>
<p>Here’s a quick summary of what’s covered in each chapter:</p>
<p>As you might expect, chapter 1 gives a general overview of <a href="http://nhforge.org" target="_blank">NHibernate</a>, along with some code listings. </p>
<p>Chapter 2 sets up the database and table structure for the example model. </p>
<p>In chapter 3, the author takes us in to the world of POCO model design. He shows us NHibernate data types and their corresponding .NET data types, as well as setting up a collection for a one-to-many relationship. </p>
<p>In chapter 4, we begin the mapping process. After just a few pages, we have a completed NHibernate xml mapping. The chapter ends with a nice, quick example of a Fluent NHibernate code mapping. <a href="https://www.packtpub.com/sites/default/files/8907-chapter-4-data-cartography.pdf" target="_blank">Chapter 4 is available for preview on the Packt Website</a>.</p>
<p>In chapter 5, we start to get in to true NHibernate territory. The author shows us how to build a session factory, open a session, and then explains the proper use of transactions (Yes!). I would have preferred an example of session-per-request over the session provider singleton. Folks, save a kitten. Don’t use singletons. </p>
<p>Chapter 6 shows off all the log4net goodness baked in to NHibernate. </p>
<p>Chapter 7 explains the ins and outs of NHibernate configuration, with code and xml examples. </p>
<p>Chapter 8 shows us an example Data Access Object and how to build some Criteria queries with projections, paging, and sorting, It’s good stuff for beginners, but it doesn’t cover HQL. </p>
<p>In Chapter 9, the author shows us how to use NHibernate with ASP.NET WebForms data binding. No beginner’s book would be complete without showing the Microsoft way. </p>
<p>Chapter 10 deals with ASP.NET security and authorization, including a membership provider based on NHibernate.</p>
<p>Chapter 11 shows off several code generation tools. While this is the logical destination for anyone using a database-first approach, with a model-first approach, its unnecessary for all but the largest projects. </p>
<p><em>Disclosure: In exchange for </em><a href="http://www.packtpub.com/article/author_reviewing_for_packt" target="_blank"><em>non-monetary compensation</em></a><em>, I worked as one of two technical reviewers on this book, and I am currently writing </em><em><u>NHibernate</u></em><em><u> 3 Cookbook</u>, to be published by Packt later this year. </em></p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/KBY2CoWUD6I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/06/review-nhibernate-2-beginners-guide/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/06/review-nhibernate-2-beginners-guide/</feedburner:origLink></item>
		<item>
		<title>March Updates</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/dndTqvIktcM/</link>
		<comments>http://jasondentler.com/blog/2010/03/march-updates/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 14:43:51 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[NHibernate Cookbook]]></category>
		<category><![CDATA[Nenverse]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/03/march-updates/</guid>
		<description><![CDATA[Some news from the month of March. 
Simon Duduica of Bucharest, Romania and his team are porting Hibernate Envers to .NET / NHibernate. 
Michele Minorello is working on NHibernate Search to add Loquacious configuration and Linq2Lucene. 
I have a book deal with Packt Publishing. NHibernate 3.0 Cookbook will cover existing and new 3.0 features of [...]]]></description>
			<content:encoded><![CDATA[<h5>Some news from the month of March. </h5>
<p>Simon Duduica of Bucharest, Romania and his team are porting Hibernate Envers to .NET / <a href="http://nhforge.org" target="_blank">NHibernate</a>. </p>
<p>Michele Minorello is working on NHibernate Search to add Loquacious configuration and Linq2Lucene. </p>
<p>I have a book deal with Packt Publishing. <u>NHibernate 3.0 Cookbook</u> will cover existing and new 3.0 features of NHibernate, as a series of short, easy to follow recipes that can be combined to build great NHibernate applications. In addition to NHibernate 3, the book also covers NHContrib projects, some ideas from uNHAddIns, fluent &amp; auto-mapping with Fluent NHibernate, and ConfORM.</p>
<p>I&#8217;d like to send a HUGE thank you to my technical reviewers, including Fabio Maulo, Jose Romaniello, and Tuna Toksoz.</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/dndTqvIktcM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/03/march-updates/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/03/march-updates/</feedburner:origLink></item>
		<item>
		<title>Big hairy bugs and other weird looking stuff.</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/rp_5IXZ9Cl4/</link>
		<comments>http://jasondentler.com/blog/2010/02/big-hairy-bugs-and-other-weird-looking-stuff/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 00:52:25 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/02/big-hairy-bugs-and-other-weird-looking-stuff/</guid>
		<description><![CDATA[Yesterday, I spent an embarrassing amount of time searching for a bug. I’m sure this is well-documented somewhere on MSDN. It even generates a compiler warning in some cases. Still, it’s not the behavior one would expect from C#.
When creating lambdas (including LINQ expressions) inside a for each loop, don’t use the iterator variable in [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday, I spent an embarrassing amount of time searching for a bug. I’m sure this is well-documented somewhere on MSDN. It even generates a compiler warning in some cases. Still, it’s not the behavior one would expect from C#.</p>
<p>When creating lambdas (including LINQ expressions) inside a for each loop, don’t use the iterator variable in your lambda. Let me explain with some code:</p>
<pre class="brush:csharp">foreach (Type controllerType in controllerTypes)
{
     kernel.Bind(controllerType).ToSelf().InRequestScope();
     kernel.Bind&lt;IController&gt;().ToMethod(ctx =&gt; ctx.kernel.Get(controllerType)).Named(GetName(controllerType));
}</pre>
<p>Why am I using a method to get the controller? It just so happens that my AccountController is also a <a href="http://jasondentler.com/blog/2009/11/simple-domain-events/" target="_blank">domain event handler</a> for my AccountNameAlreadyUsed event. This goes back to Ayende&#8217;s tip in my <a href="http://jasondentler.com/blog/2009/11/simple-domain-events/" target="_blank">domain events post</a>: To get a message back to the UI, fire a new event and have the UI listen for it. In this case, I need the UI to complain when the account name they selected is already being used. </p>
<p>In case your mind has wandered to the dark side, throwing exceptions is not an acceptable way of passing messages in an application.</p>
<p>Now, why the odd mappings? Let&#8217;s say I bind IController and IHandle&lt;AccountNameAlreadyUsed&gt; to AccountController in the request scope. It doesn&#8217;t quite work like you would first expect. You will have one instance of AccountController returned for IController and a separate instance for IHandle&lt;AccountNameAlreadyUsed&gt;. </p>
<p>Instead, I’m saying that for each request for an IController, go get an AccountController, essentially delegating the request to the ToSelf() binding. I have a similar ToMethod() lambda binding for IHandle&lt;AccountNameAlreadyUsed&gt;. Since both interface bindings are fulfilled by the ToSelf binding, only one instance of AccountController is created for the request, instead of two.</p>
<p>So, this explains why I need the lambda in the first place. Why didn’t the code above work?</p>
<p>As it turns out, there was some funny business going on underneath the covers between the foreach iterator and the lambda. Here’s the symptom: No matter which “instance” of the lambda was being referenced, inside the lambda, the iterator variable (controllerType) was always the first value that was iterated. No matter which controller I requested, I always got an instance of AccountController, since it happens to be first alphabetically.</p>
<p>Once you realize what’s going on, the fix is simple. Create another variable and use it inside the lambda instead. So, instead of the code above, we get this:</p>
<pre class="brush:csharp">foreach (Type controllerType in controllerTypes)
{
     var controllerType2 = controllerType;
     kernel.Bind(controllerType).ToSelf().InRequestScope();
     kernel.Bind&lt;IController&gt;().ToMethod(ctx =&gt; ctx.kernel.Get(controllerType2)).Named(GetName(controllerType));
}</pre>
<p>If, instead of a lambda, we had a LINQ expression, the compiler would generate a warning about this issue – at least in VB.NET. If I hadn’t already seen that warning from LINQ expressions, I would probably still be bug hunting.</p>
<p>Jason</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/rp_5IXZ9Cl4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/02/big-hairy-bugs-and-other-weird-looking-stuff/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/02/big-hairy-bugs-and-other-weird-looking-stuff/</feedburner:origLink></item>
		<item>
		<title>February Updates</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/B9xB8S34pkI/</link>
		<comments>http://jasondentler.com/blog/2010/02/february-updates/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 02:49:37 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[NHibernate]]></category>
		<category><![CDATA[Nenverse]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/02/february-updates/</guid>
		<description><![CDATA[I have a few quick announcements.

Fabio has been busy on some really amazing mapping magic.
Aaron Cure’s NHibernate 2.x Beginners Guide from Packt Publishing will be out in May.
I’m making progress on Project Nenverse. The concept is similar to Hibernate’s Envers. I’m not ready to announce it to the world just yet, but you want to [...]]]></description>
			<content:encoded><![CDATA[<p>I have a few quick announcements.</p>
<ul>
<li><a href="http://fabiomaulo.blogspot.com/" target="_blank">Fabio</a> has been busy on some really amazing <a href="http://fabiomaulo.blogspot.com/2010/01/map-nhibernate-using-your-api.html" target="_blank">mapping</a> <a href="http://fabiomaulo.blogspot.com/2010/02/conform-nhibernate-un-mapping.html" target="_blank">magic</a>.</li>
<li>Aaron Cure’s <a href="http://www.packtpub.com/nhibernate-2-x-beginners-guide/book" target="_blank">NHibernate 2.x Beginners Guide</a> from Packt Publishing will be out in May.</li>
<li>I’m making progress on Project <a href="http://code.google.com/p/nenverse/" target="_blank">Nenverse</a>. The concept is similar to Hibernate’s Envers. I’m not ready to announce it to the world just yet, but you want to look over the code or even contribute, it’s out there.</li>
<li>In an effort to avoid meta-blogging at all cost, I won’t mention the cool new stuff over on the right, or the new text up above.</li>
</ul>
<p>That’s it for now.</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/B9xB8S34pkI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/02/february-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/02/february-updates/</feedburner:origLink></item>
		<item>
		<title>Sharpening My C# Skills</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/L5CP3Atsh0I/</link>
		<comments>http://jasondentler.com/blog/2010/01/sharpening-my-c-skills/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 03:34:26 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/2010/01/sharpening-my-c-skills/</guid>
		<description><![CDATA[You may have noticed a lack of VB.NET source code on my blog recently. There’s a reason. I’ve always been able to read and write C#. at least enough to order off the menu or ask for directions to the Men’s room. 
The ALT.NET crowd is almost exclusively C#, except where they’ve moved beyond it.&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>You may have noticed a lack of VB.NET source code on my blog recently. There’s a reason. I’ve always been able to read and write C#. at least enough to order off the menu or ask for directions to the Men’s room. </p>
<p>The ALT.NET crowd is almost exclusively C#, except where they’ve moved beyond it.&#160; If I’m going to participate, it’s past time for me to become fluent. Until at least April, I won’t write a single line of VB.NET outside of work. </p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/L5CP3Atsh0I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/01/sharpening-my-c-skills/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/01/sharpening-my-c-skills/</feedburner:origLink></item>
		<item>
		<title>Exploiting Context_Info for Fun and Audit</title>
		<link>http://feedproxy.google.com/~r/BasiclyEverything/~3/N5HwUjHt7z8/</link>
		<comments>http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 17:05:22 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[NHibernate]]></category>

		<guid isPermaLink="false">http://jasondentler.com/blog/?p=505</guid>
		<description><![CDATA[This is a continuation of my posts about auditing with triggers. 
The Problem
My previous examples have used system_user as the source of user information in the audit log, which required you to impersonate users down to the database level, that is to open the connection in the context of the application user, not some shared [...]]]></description>
			<content:encoded><![CDATA[<p>This is a continuation of my posts about auditing with triggers. </p>
<h3>The Problem</h3>
<p>My previous examples have used system_user as the source of user information in the audit log, which required you to impersonate users down to the database level, that is to open the connection in the context of the application user, not some shared generic account. There are several reasons why this is not a good idea:</p>
<ol>
<li>You either don’t have per-user credentials appropriate to create SQL server accounts (typical in public-facing web applications), or are unable to do so for various reasons ranging from security concerns to account management workload. </li>
<li>When each user authenticates with their own credentials, this effectively disables connection pooling. Especially in high-volume web scenarios, this will kill performance and put a strain on server resources. </li>
<li>I believe the loss of connection pooling will also burn through your license pool with per-user licensed SQL servers. I may be mistaken on this point, as I haven’t worked with a per-user licensed SQL server for the better part of a decade. </li>
<li>If you are unwilling to use SQL server authentication, you will most likely have to set up Kerberos constrained delegation so that your database server trusts your web server to authenticate users. This is a royal PITA to implement. </li>
</ol>
<h3>The Trouble With Triggers</h3>
<p>As far as input inside a trigger, you only have access to the data being manipulated, system functions, and very little else. You can’t use SELECT statements in triggers either, at least not against normal tables and views. </p>
<h3>SQL Context Info</h3>
<p>Starting with MS SQL Server 2000, you can associate up to 128 bytes of data with the current connection using the SET CONTEXT_INFO command. Starting with SQL 2005, you can use the CONTEXT_INFO function to retrieve this data. This data is available everywhere, including triggers. </p>
<p>If you use connection pooling (and you probably are), this data is not reset when the connection is reused. </p>
<p>To set your context info data, use the <a href="http://msdn.microsoft.com/en-us/library/aa259199(SQL.80).aspx" target="_blank">SET CONTEXT_INFO</a> command like so:</p>
<pre class="brush:sql">DECLARE @Ctx varbinary(128)
SELECT @Ctx = CONVERT(varbinary(128), 'My context data goes here.')
SET CONTEXT_INFO @Ctx</pre>
<p>SET CONTEXT_INFO can only be used with variables and constants, meaning you can’t CONVERT data types or concatenate strings or any other calculation in the same command. </p>
<p>To retrieve the context data, use the <a href="http://msdn.microsoft.com/en-us/library/ms180125(SQL.90).aspx" target="_blank">CONTEXT_INFO</a> function:</p>
<pre class="brush:sql">DECLARE @CtxData varchar(128)
SELECT @CtxData = CONVERT(VarChar(128), CONTEXT_INFO())
PRINT @CtxData</pre>
<p>This will output ‘My context data goes here.\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0’ etc. Note – The \0 is ASCII character 0 (NULL). Why? We’re converting the string to fixed-length binary and then converting it back.</p>
<h3>Know Your Roots</h3>
<p><a href="http://jasondentler.com/blog/wp-content/uploads/2010/01/image.png"><img style="border-right-width: 0px; margin: 4px 10px 4px 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" align="left" src="http://jasondentler.com/blog/wp-content/uploads/2010/01/image_thumb.png" width="137" height="59" /></a> There was a time when programmers weren’t protected from the fact that strings are just chunks of memory. Just like programmers in the old days, you have two options: Pascal strings or C strings. You can stuff a length byte at the beginning of your context as in Pascal, or you can search for the null termination of your string as in the C language. </p>
<p>Also, because nchar and nvarchar are UNICODE UCS-2 strings, they use two bytes (of your 128 maximum) per character. char and varchar only use one byte per character, but the character set is limited. It’s a trade-off. </p>
<h3>How does this help me?</h3>
<p>We can use context info data to get information from our application in to our audit triggers. For example, we can get the current user name from our application or evem some identifying information about the location in our application, such as the name of the controller and action that triggered the event. Just be conscious of the 128 byte limitation. It&#8217;s probably better to store an id for more information such as the id of the user account, or an id that references some lookup table with application locations.</p>
<h3>The Code, Sir. </h3>
<p>We will override the GetConntion() method of DriverConnectionProvider so that every NHibernate connection will have the current username stored in the context.</p>
<pre class="brush:csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Connection;
using System.Data;

namespace NHibernate.Connection
{
    public class ContextDriverConnectionProvider : DriverConnectionProvider
    {

        public override System.Data.IDbConnection GetConnection()
        {
            var conn = base.GetConnection();
            SetContext(conn);
            return conn;
        }

        private const string CONTEXT_SQL = &quot;declare @Length tinyint\ndeclare @Ctx varbinary(128)\nselect @Length = len(@username)\nselect @Ctx = convert(binary(1), @Length) + convert(varbinary(127), @username)\nset context_info @Ctx&quot;;

        protected virtual void SetContext(IDbConnection conn)
        {
            IDbCommand cmd = conn.CreateCommand();
            IDbDataParameter param = cmd.CreateParameter();
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = CONTEXT_SQL;

            param.ParameterName = &quot;@username&quot;;
            param.DbType = DbType.AnsiString;
            param.Size = 127;
            param.Value = System.Environmnt.UserName;
            cmd.Parameters.Add(param);

            cmd.ExecuteNonQuery();
        }

    }
}</pre>
<p>This will run the following SQL code when NHibernate opens a SQL connection. Note that @username is a variable defined as a parameter on our IDbCommand. Also, I chose to use Pascal strings with the length stored in the first byte.</p>
<pre class="brush:sql">declare @Length tinyint
declare @Ctx varbinary(128)
select @Length = len(@username)
select @Ctx = convert(binary(1), @Length) + convert(varbinary(127), @username)
set context_info @Ctx</pre>
<p>We&#8217;ll alter our trigger code to get the username from the context instead of system_user.</p>
<pre class="brush:sql">set nocount on
declare @Username varchar(127)
declare @Length tinyint
declare @Ctx varbinary(128)
select @Ctx = CONTEXT_INFO()
select @Length = convert(tinyint, substring(@Ctx, 1, 1))
select @Username = convert(varchar(127), substring(@Ctx, 2, 1 + @Length))
if (@Username is null) select @Username = SYSTEM_USER</pre>
<h3>Security Implications</h3>
<p>I am not a security expert. I am certainly not a SQL security expert. However, I believe this method is secure for most scenarios. In my opinion, this is at least as secure as auditing through NHibernate interceptors and events. </p>
<p>Here’s a few ways to circumvent the system, and how you can prevent that from happening:</p>
<ul>
<li><strong>Manipulate the audit logs directly.</strong> Obviously, in any audit scenario, you should set permission on your audit tables to make them select and insert only. </li>
<li><strong>Alter the context_info data directly.</strong> A user overwrites their own context_info with that of another user, effectively blaming their actions on someone else. This can be done through a SQL injection attack some other security breach. If you go on vacation with the front door open, don’t be surprised when your house is robbed. </li>
<li><strong>Fail to set context_info.</strong> Again, this requires some other security breach. You may also change your trigger code to ROLLBACK TRANSACTION and RAISERROR when context_info is not set. This will force a rollback of the transaction (or in the case of no explicit transaction, the SQL statement that caused the trigger), abort the remainder of the SQL batch, and report an error. The approach requires everyone, including your DBA, to set an appropriate context_info before altering any audited data. </li>
</ul>
<p>This is certainly my worst blog post this year, but don’t worry. I can do worse. </p>
<p>- Jason</p>
<img src="http://feeds.feedburner.com/~r/BasiclyEverything/~4/N5HwUjHt7z8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://jasondentler.com/blog/2010/01/exploiting-context_info-for-fun-and-audit/</feedburner:origLink></item>
	</channel>
</rss>
