<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>IIrrelevant - .NET</title>
    <link>http://www.milkcarton.com/blog/</link>
    <description>Irrelevant musings about software development</description>
    <language>en-us</language>
    <copyright>Dan Morphis</copyright>
    <lastBuildDate>Mon, 05 Jul 2010 09:28:36 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>blog@milkcarton.com</managingEditor>
    <webMaster>blog@milkcarton.com</webMaster>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=e31f3ad6-343d-4a2e-98a4-0e38a159b4c5</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,e31f3ad6-343d-4a2e-98a4-0e38a159b4c5.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,e31f3ad6-343d-4a2e-98a4-0e38a159b4c5.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e31f3ad6-343d-4a2e-98a4-0e38a159b4c5</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
For the past week or so, I've been developing a couple of sample apps in <a href="http://www.mono-project.com/">Mono</a> with
Cocoa on my Mac. In that time, I've struggled quite a bit, and learned quite a bit.
One of the biggest things I've learned is things are much harder when you try and
mix-in paradimes for which things were not designed.
</p>
        <p>
Take for example <a href="http://www.cocoadev.com/index.pl?NSTableViewTutorial">NSTableView</a>.
Because <a href="http://en.wikipedia.org/wiki/Objective-C">Objective-C</a> is <a href="http://en.wikipedia.org/wiki/Duck_typing">duck
typed</a>, you set Delegate property of your table to <em>this</em> (<em>self</em> in
Objective-C) and implement the selectionDidChange method and you will get notified
when a row is selected.
</p>
        <p>
Because C# is not <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typed</a>,
you have to <a href="http://www.milkcarton.com/blog/2010/07/05/Databinding+To+An+NSTableView+With+A+MonoMac+App.aspx">write
a whole lot of ceremony code</a> to get notified when a row is selected. And figuring
out that ceremony was a huge battle. I wouldn't have won the war without the help
of <a href="http://twitter.com/moshakis"> John Moshakis</a>. Another thing thats not
supported is <em>Register</em>ing a generic type, or setting a generic .NET type the
property of a Cocoa widget.
</p>
        <p>
That means the ceremony code has to be duplicated every time, for every different
type of object. I actually tried to make a generic version of my <a href="http://www.milkcarton.com/blog/2010/07/05/Databinding+To+An+NSTableView+With+A+MonoMac+App.aspx">Databinding
to an NSTableView</a> blog post, but I was thwarted by an "Invalid IL exception."
Hopefully this is just a defect, and not a limitation when dealing with Cocoa.
</p>
        <p>
I would file a defect on this issue with the mono project, but Novell requires you
to create an account to add a defect to their bug tracker. I can understand why they
want you to do this, but its not a very good way to encourage participation from the
community. But I guess it is a particularly good way to discourage drive-by defect
reports.
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=e31f3ad6-343d-4a2e-98a4-0e38a159b4c5" />
      </body>
      <title>Some thoughts on mono and Cocoa</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,e31f3ad6-343d-4a2e-98a4-0e38a159b4c5.aspx</guid>
      <link>http://www.milkcarton.com/blog/2010/07/05/Some+Thoughts+On+Mono+And+Cocoa.aspx</link>
      <pubDate>Mon, 05 Jul 2010 09:28:36 GMT</pubDate>
      <description>&lt;p&gt;
For the past week or so, I've been developing a couple of sample apps in &lt;a href="http://www.mono-project.com/"&gt;Mono&lt;/a&gt; with
Cocoa on my Mac. In that time, I've struggled quite a bit, and learned quite a bit.
One of the biggest things I've learned is things are much harder when you try and
mix-in paradimes for which things were not designed.
&lt;/p&gt;
&lt;p&gt;
Take for example &lt;a href="http://www.cocoadev.com/index.pl?NSTableViewTutorial"&gt;NSTableView&lt;/a&gt;.
Because &lt;a href="http://en.wikipedia.org/wiki/Objective-C"&gt;Objective-C&lt;/a&gt; is &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;duck
typed&lt;/a&gt;, you set Delegate property of your table to &lt;em&gt;this&lt;/em&gt; (&lt;em&gt;self&lt;/em&gt; in
Objective-C) and implement the selectionDidChange method and you will get notified
when a row is selected.
&lt;/p&gt;
&lt;p&gt;
Because C# is not &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;duck typed&lt;/a&gt;,
you have to &lt;a href="http://www.milkcarton.com/blog/2010/07/05/Databinding+To+An+NSTableView+With+A+MonoMac+App.aspx"&gt;write
a whole lot of ceremony code&lt;/a&gt; to get notified when a row is selected. And figuring
out that ceremony was a huge battle. I wouldn't have won the war without the help
of &lt;a href="http://twitter.com/moshakis"&gt; John Moshakis&lt;/a&gt;. Another thing thats not
supported is &lt;em&gt;Register&lt;/em&gt;ing a generic type, or setting a generic .NET type the
property of a Cocoa widget.
&lt;/p&gt;
&lt;p&gt;
That means the ceremony code has to be duplicated every time, for every different
type of object. I actually tried to make a generic version of my &lt;a href="http://www.milkcarton.com/blog/2010/07/05/Databinding+To+An+NSTableView+With+A+MonoMac+App.aspx"&gt;Databinding
to an NSTableView&lt;/a&gt; blog post, but I was thwarted by an "Invalid IL exception."
Hopefully this is just a defect, and not a limitation when dealing with Cocoa.
&lt;/p&gt;
&lt;p&gt;
I would file a defect on this issue with the mono project, but Novell requires you
to create an account to add a defect to their bug tracker. I can understand why they
want you to do this, but its not a very good way to encourage participation from the
community. But I guess it is a particularly good way to discourage drive-by defect
reports.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=e31f3ad6-343d-4a2e-98a4-0e38a159b4c5" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,e31f3ad6-343d-4a2e-98a4-0e38a159b4c5.aspx</comments>
      <category>.NET</category>
      <category>Mac OS X</category>
      <category>Mono</category>
      <category>MonoMac</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=5dfec1ca-2d74-4999-9c22-6fd7a5b637d4</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,5dfec1ca-2d74-4999-9c22-6fd7a5b637d4.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,5dfec1ca-2d74-4999-9c22-6fd7a5b637d4.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=5dfec1ca-2d74-4999-9c22-6fd7a5b637d4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve followed <a href="http://monodevelop.com/">MonoDevelop</a> for a long time. In
that time, I’ve seen it go from a barely usable product, to now a fairly capable IDE.
Out of the box, it look and acts much like Visual Studio. I do like that that a dedicated
unit testing tab is present as a constant reminder that, “Hey, you know you should
probably write those unit tests you’ve always talked about writing.”
</p>
        <p>
One thing I was somewhat surprised to not see, at least on the Mac edition of MonoDevelop
is a built-in scheme for the VS keybindings. On the down side, I have been able to
crash MonoDevelop when I didn’t have some setup code in the right place and I ended
up with a null ref trying to talk to some Cocoa widgets.
</p>
        <p>
More to come as I spend more time with MonoDevelop.
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=5dfec1ca-2d74-4999-9c22-6fd7a5b637d4" />
      </body>
      <title>Some thoughts on using MonoDevelop</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,5dfec1ca-2d74-4999-9c22-6fd7a5b637d4.aspx</guid>
      <link>http://www.milkcarton.com/blog/2010/07/03/Some+Thoughts+On+Using+MonoDevelop.aspx</link>
      <pubDate>Sat, 03 Jul 2010 16:00:00 GMT</pubDate>
      <description>&lt;p&gt;
I’ve followed &lt;a href="http://monodevelop.com/"&gt;MonoDevelop&lt;/a&gt; for a long time. In
that time, I’ve seen it go from a barely usable product, to now a fairly capable IDE.
Out of the box, it look and acts much like Visual Studio. I do like that that a dedicated
unit testing tab is present as a constant reminder that, “Hey, you know you should
probably write those unit tests you’ve always talked about writing.”
&lt;/p&gt;
&lt;p&gt;
One thing I was somewhat surprised to not see, at least on the Mac edition of MonoDevelop
is a built-in scheme for the VS keybindings. On the down side, I have been able to
crash MonoDevelop when I didn’t have some setup code in the right place and I ended
up with a null ref trying to talk to some Cocoa widgets.
&lt;/p&gt;
&lt;p&gt;
More to come as I spend more time with MonoDevelop.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=5dfec1ca-2d74-4999-9c22-6fd7a5b637d4" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,5dfec1ca-2d74-4999-9c22-6fd7a5b637d4.aspx</comments>
      <category>.NET</category>
      <category>Mono</category>
      <category>MonoMac</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=454b3531-266d-40ee-821d-f86b18758acc</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,454b3531-266d-40ee-821d-f86b18758acc.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,454b3531-266d-40ee-821d-f86b18758acc.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=454b3531-266d-40ee-821d-f86b18758acc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When Miguel De Icaza <a href="http://tirania.org/blog/archive/2010/Apr-19.html">first
announced MonoMac</a> back in April I was pretty excited! Its been my goal for the
past two years to write a half-decent, <strong>native</strong> looking, Mac OSX application
with .NET. I’ve looked at the various Cocoa binding strategies for Mono and always
found them lacking. Some like <a href="http://www.mono-project.com/CocoaSharp">CocoaSharp</a> haven’t
been updated in ages, and the WinForms stuff on Mac looked plain fugly. Like Windows
95 fugly.
</p>
        <p>
I found <a href="http://mjhutchinson.com/journal/2010/06/09/monomac_in_monodevelop">Michael
Hutchinson’s quick-start post</a> on writing a simple .NET app using MonoMac. Because
I had previous experience using Interface Builder, I was able to muddle my way through
building his simple app. But at the end, I wanted something more. “Hello World” is
great to show you the most basic syntax of a language, and maybe how to use the compiler,
but it honestly does nothing for me.
</p>
        <p>
So, I set out to write real, although somewhat contrived image viewing application.
Having an extensive background writing WinForms, ASP.NET and some WPF apps, the hardest
part for me was trying to figure out the Cocoa equivalent to things like PictureBox,
and FolderBrowserDialog. But Google as always was my friend.
</p>
        <p>
I’m not going to dive into how to write the app tonight, but I will post a screen
shot, and the <a href="http://www.milkcarton.com/blog/content/binary/ImageViewer.zip">ImageViewer
source!</a><br /><a href="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/MyfirstMonoMacapplicationanditsnotHelloW_144FC/image_2.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://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/MyfirstMonoMacapplicationanditsnotHelloW_144FC/image_thumb.png" width="458" height="439" /></a></p>
        <h4>Nits
</h4>
        <p>
Yes Cocoa is based on an MVC architecture, and yes I should have put some of the code
into a business class, but I didn’t. 
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=454b3531-266d-40ee-821d-f86b18758acc" />
      </body>
      <title>My first MonoMac application, and its not “Hello World”</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,454b3531-266d-40ee-821d-f86b18758acc.aspx</guid>
      <link>http://www.milkcarton.com/blog/2010/07/02/My+First+MonoMac+Application+And+Its+Not+Hello+World.aspx</link>
      <pubDate>Fri, 02 Jul 2010 15:22:00 GMT</pubDate>
      <description>&lt;p&gt;
When Miguel De Icaza &lt;a href="http://tirania.org/blog/archive/2010/Apr-19.html"&gt;first
announced MonoMac&lt;/a&gt; back in April I was pretty excited! Its been my goal for the
past two years to write a half-decent, &lt;strong&gt;native&lt;/strong&gt; looking, Mac OSX application
with .NET. I’ve looked at the various Cocoa binding strategies for Mono and always
found them lacking. Some like &lt;a href="http://www.mono-project.com/CocoaSharp"&gt;CocoaSharp&lt;/a&gt; haven’t
been updated in ages, and the WinForms stuff on Mac looked plain fugly. Like Windows
95 fugly.
&lt;/p&gt;
&lt;p&gt;
I found &lt;a href="http://mjhutchinson.com/journal/2010/06/09/monomac_in_monodevelop"&gt;Michael
Hutchinson’s quick-start post&lt;/a&gt; on writing a simple .NET app using MonoMac. Because
I had previous experience using Interface Builder, I was able to muddle my way through
building his simple app. But at the end, I wanted something more. “Hello World” is
great to show you the most basic syntax of a language, and maybe how to use the compiler,
but it honestly does nothing for me.
&lt;/p&gt;
&lt;p&gt;
So, I set out to write real, although somewhat contrived image viewing application.
Having an extensive background writing WinForms, ASP.NET and some WPF apps, the hardest
part for me was trying to figure out the Cocoa equivalent to things like PictureBox,
and FolderBrowserDialog. But Google as always was my friend.
&lt;/p&gt;
&lt;p&gt;
I’m not going to dive into how to write the app tonight, but I will post a screen
shot, and the &lt;a href="http://www.milkcarton.com/blog/content/binary/ImageViewer.zip"&gt;ImageViewer
source!&lt;/a&gt; 
&lt;br /&gt;
&lt;a href="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/MyfirstMonoMacapplicationanditsnotHelloW_144FC/image_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" border="0" alt="image" src="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/MyfirstMonoMacapplicationanditsnotHelloW_144FC/image_thumb.png" width="458" height="439" /&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;h4&gt;Nits
&lt;/h4&gt;
&lt;p&gt;
Yes Cocoa is based on an MVC architecture, and yes I should have put some of the code
into a business class, but I didn’t. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=454b3531-266d-40ee-821d-f86b18758acc" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,454b3531-266d-40ee-821d-f86b18758acc.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>Mac OS X</category>
      <category>Mono</category>
      <category>MonoMac</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=52104a75-5e30-4ee5-b966-b44e6cf7840f</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,52104a75-5e30-4ee5-b966-b44e6cf7840f.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,52104a75-5e30-4ee5-b966-b44e6cf7840f.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=52104a75-5e30-4ee5-b966-b44e6cf7840f</wfw:commentRss>
      <title>Sometimes, you have to go back to the pointers</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,52104a75-5e30-4ee5-b966-b44e6cf7840f.aspx</guid>
      <link>http://www.milkcarton.com/blog/2010/06/29/Sometimes+You+Have+To+Go+Back+To+The+Pointers.aspx</link>
      <pubDate>Tue, 29 Jun 2010 14:45:00 GMT</pubDate>
      <description>&lt;p&gt;
A while back, I was tasked with solving a defect in our system. The defect was “Changes
to an image can be reverted only one time.”
&lt;/p&gt;
&lt;p&gt;
As I started to look into the code, I saw something like this:&lt;br&gt;
&lt;/p&gt;
&lt;pre style="font-family: consolas,; font-size: small" class="csharp" #ffffff;? background-color: monospace; courier, New?, Courier&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #0600ff; font-weight: bold"&gt;private&lt;/span&gt; Image
_originalImage&lt;span style="color: #008000"&gt;;&lt;/span&gt;
&lt;/div&gt;
&lt;li style="background-color: #f4f4f4"&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #0600ff; font-weight: bold"&gt;private&lt;/span&gt; Image
_image&lt;span style="color: #008000"&gt;;&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&amp;nbsp;
&lt;/div&gt;
&lt;li style="background-color: #f4f4f4"&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #0600ff; font-weight: bold"&gt;public&lt;/span&gt; &lt;span style="color: #6666cc; font-weight: bold"&gt;void&lt;/span&gt; Show&lt;span style="color: #008000"&gt;(&lt;/span&gt;Image
image&lt;span style="color: #008000"&gt;)&lt;/span&gt; &lt;span style="color: #008000"&gt;{&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;
_image &lt;span style="color: #008000"&gt;=&lt;/span&gt; image&lt;span style="color: #008000"&gt;;&lt;/span&gt;
&lt;/div&gt;
&lt;li style="background-color: #f4f4f4"&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;
_originalImage &lt;span style="color: #008000"&gt;=&lt;/span&gt; &lt;span style="color: #008000"&gt;(&lt;/span&gt;Image&lt;span style="color: #008000"&gt;)&lt;/span&gt; image&lt;span style="color: #008000"&gt;.&lt;/span&gt;&lt;span style="color: #0000ff"&gt;Clone&lt;/span&gt;&lt;span style="color: #008000"&gt;(&lt;/span&gt;&lt;span style="color: #008000"&gt;)&lt;/span&gt;&lt;span style="color: #008000"&gt;;&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;li style="background-color: #f4f4f4"&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&amp;nbsp;
&lt;/div&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #0600ff; font-weight: bold"&gt;private&lt;/span&gt; &lt;span style="color: #6666cc; font-weight: bold"&gt;void&lt;/span&gt; Revert&lt;span style="color: #008000"&gt;(&lt;/span&gt;&lt;span style="color: #008000"&gt;)&lt;/span&gt; &lt;span style="color: #008000"&gt;{&lt;/span&gt;
&lt;/div&gt;
&lt;li style="background-color: #f4f4f4"&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;
_image &lt;span style="color: #008000"&gt;=&lt;/span&gt; _originalImage&lt;span style="color: #008000"&gt;;&lt;/span&gt;
&lt;/div&gt;
&lt;li&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; font: 1em/1.2em monospace; background: none transparent scroll repeat 0% 0%; vertical-align: top; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;}&lt;/span&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px"&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/pre&gt;&amp;nbsp;&gt;
&lt;p&gt;
Looking at the code, I suspected I knew what was wrong, but I wanted to confirm it.
So I ran the app, made modifications to the image, clicked revert, made modifications
to the image again, set a break point and clicked revert again. Once Visual Studio
broke, I popped over to the immediate window and typed this: 
&lt;/p&gt;
&lt;pre style="background-color: rgb(244,244,244)"&gt;&amp;amp;_image
Which returned: 0x1234abd0
&amp;amp;_originalImage
Which also returned: 0x1234abd0&lt;/pre&gt;
&lt;p&gt;
Now I knew what the issue was, the original image was getting clobbered due to a missed
.Clone() on line 10. A simple _image = (Image)_originalImage.Clone(); fixed the issue.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=52104a75-5e30-4ee5-b966-b44e6cf7840f" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,52104a75-5e30-4ee5-b966-b44e6cf7840f.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=bcd01da5-498e-410c-a687-acc721220457</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=bcd01da5-498e-410c-a687-acc721220457</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h3>Background
</h3>
        <p>
For a project I'm doing, I have a task model for the various pieces. In the beginning,
I was manually creating a List&lt;ITask&gt;. As I kept adding tasks to run, I started
thinking about hacking some code together to rifle through my assembly and pull back
all the classes which implement ITask.
</p>
        <p>
Then I remember hearing about Managed Extensibility Framework (MEF). I did some searching,
found the <a href="http://www.codeplex.com/MEF/" target="_blank">MEF home page</a>,
and even read the <a href="http://mef.codeplex.com/Wiki/View.aspx?title=Overview&amp;referringTitle=Home" target="_blank">MEF
overview</a>. But none of that told me what I really wanted to know, what's the fastest
way to get started using MEF as a component loader?
</p>
        <p>
I did some more searching and found the <a href="http://dnrtv.com/" target="_blank">dnrTV</a> episode
"<a href="http://www.dnrtv.com/default.aspx?showNum=130" target="_blank">Glenn Block
on MEF, the Managed Extensibility Framework</a>" and after 20-30 minutes they finally
got down to how to create a plugin for your app.
</p>
        <p>
But what I really wanted, and I bet a lot of others, is a quick start guide for creating
a plugin.
</p>
        <h3>Solution
</h3>
        <p>
          <a href="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22313" target="_blank">Download
the latest version of MEF</a>, as of this writing its Preview 4. Grab the System.ComponentModel.Composition.dll
from the bin folder and stash it somewhere. Make a reference to said dll in your project.
</p>
        <p>
On your plugin class, add Export attribute:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[Export(<span style="color: #0000ff">typeof</span>(IPlugin))] <span style="color: #0000ff">public</span><span style="color: #0000ff">class</span> Foo
: IPlugin { ... }</pre>
        </div>
        <p>
In your plugin consumer, create a property to hold your plugins, and add the Import
attribute:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">[Import(<span style="color: #0000ff">typeof</span>(IPlugin))] <span style="color: #0000ff">internal</span> IList&lt;IPlugin&gt;
_myPlugins { get; set; }</pre>
        </div>
        <p>
Now, tell MEF where to get the plugins at (line 2), and where you want MEF to fulfill
any plugins (line 5):
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <p>
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">void</span> LoadPlugins()
{ var catalog = <span style="color: #0000ff">new</span> AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = <span style="color: #0000ff">new</span> CompositionContainer(catalog);
var batch = <span style="color: #0000ff">new</span> CompositionBatch(); batch.AddPart(<span style="color: #0000ff">this</span>);
container.Compose(batch); } 
</p>
            <p>
 
</p>
          </pre>
        </div>
        <p>
I put my call to the LoadPlugins method in the constructor.
</p>
        <p>
Now, spin through your plugins and do the work:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">Console.WriteLine(<span style="color: #006080">"Found
{0} plugins"</span>, _myPlugins.Count); <span style="color: #0000ff">foreach</span> (var
plugin <span style="color: #0000ff">in</span> _myPlugins) { Console.WriteLine(plugin.Name);
}</pre>
        </div>
        <p>
 
</p>
        <p>
          <a href="/blog/content/binary/5_Minute_MEF_Tutorial.zip" target="_blank">Download
the complete source</a> to this (really, only about 10 extra lines to glue things
together) and have fun!
</p>
        <a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx">
          <img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx" border="0" alt="kick it on DotNetKicks.com" />
        </a>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=bcd01da5-498e-410c-a687-acc721220457" />
      </body>
      <title>5 Minute Tutorial on Managed Extensibility Framework (MEF)</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</guid>
      <link>http://www.milkcarton.com/blog/2009/04/04/5+Minute+Tutorial+On+Managed+Extensibility+Framework+MEF.aspx</link>
      <pubDate>Sat, 04 Apr 2009 05:37:33 GMT</pubDate>
      <description>&lt;h3&gt;Background
&lt;/h3&gt;
&lt;p&gt;
For a project I'm doing, I have a task model for the various pieces. In the beginning,
I was manually creating a List&amp;lt;ITask&amp;gt;. As I kept adding tasks to run, I started
thinking about hacking some code together to rifle through my assembly and pull back
all the classes which implement ITask.
&lt;/p&gt;
&lt;p&gt;
Then I remember hearing about Managed Extensibility Framework (MEF). I did some searching,
found the &lt;a href="http://www.codeplex.com/MEF/" target="_blank"&gt;MEF home page&lt;/a&gt;,
and even read the &lt;a href="http://mef.codeplex.com/Wiki/View.aspx?title=Overview&amp;amp;referringTitle=Home" target="_blank"&gt;MEF
overview&lt;/a&gt;. But none of that told me what I really wanted to know, what's the fastest
way to get started using MEF as a component loader?
&lt;/p&gt;
&lt;p&gt;
I did some more searching and found the &lt;a href="http://dnrtv.com/" target="_blank"&gt;dnrTV&lt;/a&gt; episode
"&lt;a href="http://www.dnrtv.com/default.aspx?showNum=130" target="_blank"&gt;Glenn Block
on MEF, the Managed Extensibility Framework&lt;/a&gt;" and after 20-30 minutes they finally
got down to how to create a plugin for your app.
&lt;/p&gt;
&lt;p&gt;
But what I really wanted, and I bet a lot of others, is a quick start guide for creating
a plugin.
&lt;/p&gt;
&lt;h3&gt;Solution
&lt;/h3&gt;
&lt;p&gt;
&lt;a href="http://mef.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=22313" target="_blank"&gt;Download
the latest version of MEF&lt;/a&gt;, as of this writing its Preview 4. Grab the System.ComponentModel.Composition.dll
from the bin folder and stash it somewhere. Make a reference to said dll in your project.
&lt;/p&gt;
&lt;p&gt;
On your plugin class, add Export attribute:
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Export(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))] &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Foo
: IPlugin { ... }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
In your plugin consumer, create a property to hold your plugins, and add the Import
attribute:
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;[Import(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(IPlugin))] &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; IList&amp;lt;IPlugin&amp;gt;
_myPlugins { get; set; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Now, tell MEF where to get the plugins at (line 2), and where you want MEF to fulfill
any plugins (line 5):
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;
&lt;p&gt;
&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; LoadPlugins()
{ var catalog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AssemblyCatalog(Assembly.GetExecutingAssembly());
var container = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionContainer(catalog);
var batch = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CompositionBatch(); batch.AddPart(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);
container.Compose(batch); } 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
I put my call to the LoadPlugins method in the constructor.
&lt;/p&gt;
&lt;p&gt;
Now, spin through your plugins and do the work:
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;Console.WriteLine(&lt;span style="color: #006080"&gt;"Found
{0} plugins"&lt;/span&gt;, _myPlugins.Count); &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var
plugin &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _myPlugins) { Console.WriteLine(plugin.Name);
}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="/blog/content/binary/5_Minute_MEF_Tutorial.zip" target="_blank"&gt;Download
the complete source&lt;/a&gt; to this (really, only about 10 extra lines to glue things
together) and have fun!
&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f04%2f04%2f5%2bMinute%2bTutorial%2bOn%2bManaged%2bExtensibility%2bFramework%2bMEF.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=bcd01da5-498e-410c-a687-acc721220457" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,bcd01da5-498e-410c-a687-acc721220457.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>HowTo</category>
      <category>MEF</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A long time, and many many moons ago I took wrote some code to interface our build
server with a <a href="http://www.epowerswitch.com/uk/p-4g_guard.htm" target="_blank" rel="nofollow">network
power switch</a> we had laying around the office. We used this to turn on and off
lava lamps to indicate the status of the build. Some might ask why we didn't use the
X10 support that is already in CCNET, and the answer mostly is cost, and the fact
that X10 wouldn't work in our environment.
</p>
        <p>
That was 2.5 years ago. Since then, our team has become more distributed. We have
one guy working in Ann Arbor, MI, and occasionally have others telecommuting. So not
everyone can see the status of the lamps. Also in the 2.5 years since that code was
written, a little thing called <a href="http://twitter.com/" target="_blank">Twitter</a> has
become very popular. I did some research, and found <a href="http://techblog.tomfanning.eu/2008/03/twitter-task-for-nant-sms-notification.html" target="_blank">Tom
Fannings nAnt Twitter task</a> and briefly considered using it.
</p>
        <p>
But in the end, I just couldn't resist adding my own <a href="http://www.codinghorror.com/blog/archives/000150.html" target="_blank">developer
gold plating</a> and thought it would be neat if we could also issue commands to the
build server via tweets. So with that feature in mind, I had to write it myself.
</p>
        <p>
To start out with, I used <a href="http://devblog.yedda.com/index.php/2007/05/16/twitter-c-library/" target="_blank">Yedda's
C# Twitter library</a>. The Yedda library is a pleasure to work with, it makes sending
a tweet as simple as
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">new</span> Twitter().UpdateAsXML(_username,
password, messsage);</pre>
        </div>
        <p>
One thing the Yedda library didn't have, was the ability to query for your Twitter
replies. A quick look through the source, and the <a href="http://apiwiki.twitter.com/" target="_blank">Twitter
API</a> docs and I realized this would be trivial. The details of how I did it aren't
important to this post, but if your curious, you can look at lines 567 - 627 of the
Yedda source included with this post.
</p>
        <p>
I'm not going to dive to much into how the whole project works, but here is a high
level. The software runs as a Windows Service, leverages the CCTrayLib assembly for
Cruise Control.NET to do all the heavy lifting. It polls the Cruise Control.NET server
every 5 seconds, and fires events when things happen. The two events we want are the
Polled and BuildOccurred events.
</p>
        <p>
These events allow us to intern kick off our own events based on the state of the
build. Based on the state, we grab the appropriate actions to run as defined in the
BuildActions.xml file. This maps a build state to a set of actions. In the case of
a "Building" action, we send a Twitter, with a message template of "{PROJECT} is building",
and turn ports 1 on, and 2 off on our ePower switch. Easy enough.
</p>
        <p>
But how do we take in commands? I pondered this for a minute than realized it would
be trivial to leverage the Twitter replies API for this. But what about security,
we can't have just anyone sending commands to our build server. This is where the
Twitter friends API comes in handy. In order to issue commands to our build server,
the account our build server uses has to have you as a friend, not just a follower.
</p>
        <p>
The first action I implemented was the force build command. The idea for the grammar
came from a <a href="http://twitter.com/orand/status/1319154695" target="_blank">joke
reply</a><a href="http://twitter.com/orand" target="_blank">@orand</a> sent our Twitter
bot. After that, I thought it might be nice to be able to get the list of projects,
get a projects status, and ask for help. So that leaves us with a total of 4 commands.
</p>
        <h3>A small bunny trail
</h3>
        <p>
When I first wrote the command parser, it looked something like this:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">if</span> (msg.StartsWith(<span style="color: #006080">"force
build "</span>)) ProcessForceBuildCommand(msg, user); <span style="color: #0000ff">else</span><span style="color: #0000ff">if</span> (msg.StartsWith(<span style="color: #006080">"get
projects"</span>)) ProcessProjectListsCommand(msg, user); ...</pre>
        </div>
        <p>
I thought about it for a while, and thought there had to be an easier way. We are
using .NET 3.5 after all, with all its lamba, LINQ and new and improved delegate goodness.
I did some research and came upon the Action&lt;T&gt; (and Func&lt;T&gt;) delegate
type. And came up with this implementation for registering commands
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var commands = <span style="color: #0000ff">new</span> Dictionary&lt;<span style="color: #0000ff">string</span>,
Action&lt;<span style="color: #0000ff">string</span>, <span style="color: #0000ff">string</span>&gt;&gt;
{ {<span style="color: #006080">"force build "</span>, ProcessForceBuildCommand},
{<span style="color: #006080">"get projects"</span>, ProcessProjectListsCommand},
{<span style="color: #006080">"get project status "</span>, ProcessProjectStatusCommand},
{<span style="color: #006080">"help"</span>, ProcessHelpCommand} };</pre>
        </div>
        <p>
Once we have all the commands registered, we can use some lambda and LINQ magic to
act upon the commands issued
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">var key = _commands.Keys.Where(msg.StartsWith).First();
<span style="color: #0000ff">if</span> (!<span style="color: #0000ff">string</span>.IsNullOrEmpty(key))
_commands[key].Invoke(msg, user); <span style="color: #0000ff">else</span> SendTweet(<span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"@{0}
I'm sorry, I don't understand you. Maybe you should ask for help"</span>, user)); </pre>
        </div>
        <h3>Get to the point, I want to see the source code
</h3>
        <p>
The code overall is fairly well structured (if I do say so myself), although there
is one area where I did violate the separation of concerns rule, the TwitterManager
class knows more about Cruise Control.NET than it should. But, given that this is
a very simple internal project, and not for public consumption, I'm mostly OK with
that :)
</p>
        <p>
I've included the source to our entire build monitor, I hope you find it useful. 
We are using a very old version (1.1) of Cruise Control.NET in our environment. If
your using a more recent version, you will probably need to swap out the Cruise Control
CCTrayLib and Remote assemblies for something more recent, and invert some of the
commented out code in the SetupCruiseControl method of BuildServerMonitor.cs
</p>
        <p>
If you have any questions, or find/fix any bugs, please feel free to leave a comment,
or send me a tweet, my username on Twitter is <a href="http://twitter.com/akcoder" target="_blank">akcoder</a>.
</p>
        <p>
          <a href="http://files.milkcarton.com/Afhcan.BuildMonitor.zip" target="_blank">Download
the Afhcan.BuildMonitor</a>
        </p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a" />
      </body>
      <title>Does your Cruise Control.NET server Twitter?</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</guid>
      <link>http://www.milkcarton.com/blog/2009/03/16/Does+Your+Cruise+ControlNET+Server+Twitter.aspx</link>
      <pubDate>Mon, 16 Mar 2009 04:59:22 GMT</pubDate>
      <description>&lt;p&gt;
A long time, and many many moons ago I took wrote some code to interface our build
server with a &lt;a href="http://www.epowerswitch.com/uk/p-4g_guard.htm" target="_blank" rel="nofollow"&gt;network
power switch&lt;/a&gt; we had laying around the office. We used this to turn on and off
lava lamps to indicate the status of the build. Some might ask why we didn't use the
X10 support that is already in CCNET, and the answer mostly is cost, and the fact
that X10 wouldn't work in our environment.
&lt;/p&gt;
&lt;p&gt;
That was 2.5 years ago. Since then, our team has become more distributed. We have
one guy working in Ann Arbor, MI, and occasionally have others telecommuting. So not
everyone can see the status of the lamps. Also in the 2.5 years since that code was
written, a little thing called &lt;a href="http://twitter.com/" target="_blank"&gt;Twitter&lt;/a&gt; has
become very popular. I did some research, and found &lt;a href="http://techblog.tomfanning.eu/2008/03/twitter-task-for-nant-sms-notification.html" target="_blank"&gt;Tom
Fannings nAnt Twitter task&lt;/a&gt; and briefly considered using it.
&lt;/p&gt;
&lt;p&gt;
But in the end, I just couldn't resist adding my own &lt;a href="http://www.codinghorror.com/blog/archives/000150.html" target="_blank"&gt;developer
gold plating&lt;/a&gt; and thought it would be neat if we could also issue commands to the
build server via tweets. So with that feature in mind, I had to write it myself.
&lt;/p&gt;
&lt;p&gt;
To start out with, I used &lt;a href="http://devblog.yedda.com/index.php/2007/05/16/twitter-c-library/" target="_blank"&gt;Yedda's
C# Twitter library&lt;/a&gt;. The Yedda library is a pleasure to work with, it makes sending
a tweet as simple as
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Twitter().UpdateAsXML(_username,
password, messsage);&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
One thing the Yedda library didn't have, was the ability to query for your Twitter
replies. A quick look through the source, and the &lt;a href="http://apiwiki.twitter.com/" target="_blank"&gt;Twitter
API&lt;/a&gt; docs and I realized this would be trivial. The details of how I did it aren't
important to this post, but if your curious, you can look at lines 567 - 627 of the
Yedda source included with this post.
&lt;/p&gt;
&lt;p&gt;
I'm not going to dive to much into how the whole project works, but here is a high
level. The software runs as a Windows Service, leverages the CCTrayLib assembly for
Cruise Control.NET to do all the heavy lifting. It polls the Cruise Control.NET server
every 5 seconds, and fires events when things happen. The two events we want are the
Polled and BuildOccurred events.
&lt;/p&gt;
&lt;p&gt;
These events allow us to intern kick off our own events based on the state of the
build. Based on the state, we grab the appropriate actions to run as defined in the
BuildActions.xml file. This maps a build state to a set of actions. In the case of
a "Building" action, we send a Twitter, with a message template of "{PROJECT} is building",
and turn ports 1 on, and 2 off on our ePower switch. Easy enough.
&lt;/p&gt;
&lt;p&gt;
But how do we take in commands? I pondered this for a minute than realized it would
be trivial to leverage the Twitter replies API for this. But what about security,
we can't have just anyone sending commands to our build server. This is where the
Twitter friends API comes in handy. In order to issue commands to our build server,
the account our build server uses has to have you as a friend, not just a follower.
&lt;/p&gt;
&lt;p&gt;
The first action I implemented was the force build command. The idea for the grammar
came from a &lt;a href="http://twitter.com/orand/status/1319154695" target="_blank"&gt;joke
reply&lt;/a&gt; &lt;a href="http://twitter.com/orand" target="_blank"&gt;@orand&lt;/a&gt; sent our Twitter
bot. After that, I thought it might be nice to be able to get the list of projects,
get a projects status, and ask for help. So that leaves us with a total of 4 commands.
&lt;/p&gt;
&lt;h3&gt;A small bunny trail
&lt;/h3&gt;
&lt;p&gt;
When I first wrote the command parser, it looked something like this:
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (msg.StartsWith(&lt;span style="color: #006080"&gt;"force
build "&lt;/span&gt;)) ProcessForceBuildCommand(msg, user); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (msg.StartsWith(&lt;span style="color: #006080"&gt;"get
projects"&lt;/span&gt;)) ProcessProjectListsCommand(msg, user); ...&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
I thought about it for a while, and thought there had to be an easier way. We are
using .NET 3.5 after all, with all its lamba, LINQ and new and improved delegate goodness.
I did some research and came upon the Action&amp;lt;T&amp;gt; (and Func&amp;lt;T&amp;gt;) delegate
type. And came up with this implementation for registering commands
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;var commands = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;,
Action&amp;lt;&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;&amp;gt;&amp;gt;
{ {&lt;span style="color: #006080"&gt;"force build "&lt;/span&gt;, ProcessForceBuildCommand},
{&lt;span style="color: #006080"&gt;"get projects"&lt;/span&gt;, ProcessProjectListsCommand},
{&lt;span style="color: #006080"&gt;"get project status "&lt;/span&gt;, ProcessProjectStatusCommand},
{&lt;span style="color: #006080"&gt;"help"&lt;/span&gt;, ProcessHelpCommand} };&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Once we have all the commands registered, we can use some lambda and LINQ magic to
act upon the commands issued
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;var key = _commands.Keys.Where(msg.StartsWith).First();
&lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(key))
_commands[key].Invoke(msg, user); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; SendTweet(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"@{0}
I'm sorry, I don't understand you. Maybe you should ask for help"&lt;/span&gt;, user)); &lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Get to the point, I want to see the source code
&lt;/h3&gt;
&lt;p&gt;
The code overall is fairly well structured (if I do say so myself), although there
is one area where I did violate the separation of concerns rule, the TwitterManager
class knows more about Cruise Control.NET than it should. But, given that this is
a very simple internal project, and not for public consumption, I'm mostly OK with
that :)
&lt;/p&gt;
&lt;p&gt;
I've included the source to our entire build monitor, I hope you find it useful.&amp;nbsp;
We are using a very old version (1.1) of Cruise Control.NET in our environment. If
your using a more recent version, you will probably need to swap out the Cruise Control
CCTrayLib and Remote assemblies for something more recent, and invert some of the
commented out code in the SetupCruiseControl method of BuildServerMonitor.cs
&lt;/p&gt;
&lt;p&gt;
If you have any questions, or find/fix any bugs, please feel free to leave a comment,
or send me a tweet, my username on Twitter is &lt;a href="http://twitter.com/akcoder" target="_blank"&gt;akcoder&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://files.milkcarton.com/Afhcan.BuildMonitor.zip" target="_blank"&gt;Download
the Afhcan.BuildMonitor&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,0f2afcce-d7c6-4d53-93b7-c3d9bf87ab2a.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>HowTo</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=8396d43e-d21d-44fd-b279-b9e8940a3304</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8396d43e-d21d-44fd-b279-b9e8940a3304</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of our applications has a Windows service in it. To make debugging and running
this service easy,we have a winform in the service which can be activated by passing
a command line switch. Simple enough. Our service does all its logging with log4net.
I wanted to be able to put the output of the logging on our development form, but
how?
</p>
        <p>
After looking at various things, I realized what I needed to do was create a log4net
appender, and add the appender to the log4net logger and at regular intervals, grab
the contents of the logger.
</p>
        <h3>Solution
</h3>
        <p>
I created the below appender which uses a StringBuilder as the backing store. It takes
in one bool param in the contructor which allows you to specify if you want the log
to be built up in reverse.  This is useful if you want to display the most recent
event at the top.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">class</span> StringBuilderAppender
: log4net.Appender.AppenderSkeleton { <span style="color: #0000ff">private</span> System.Text.StringBuilder
_builder = <span style="color: #0000ff">new</span> System.Text.StringBuilder(); <span style="color: #0000ff">private</span><span style="color: #0000ff">readonly</span><span style="color: #0000ff">bool</span> _invert; <span style="color: #0000ff">public</span> StringBuilderAppender(<span style="color: #0000ff">bool</span> invert)
{ _invert = invert; } <span style="color: #0000ff">public</span><span style="color: #0000ff">string</span> Text
{ get { <span style="color: #0000ff">return</span> _builder.ToString(); } } <span style="color: #0000ff">protected</span><span style="color: #0000ff">override</span><span style="color: #0000ff">void</span> Append(log4net.Core.LoggingEvent
loggingEvent) { var msg = loggingEvent.RenderedMessage; <span style="color: #0000ff">if</span> (_invert)
_builder = <span style="color: #0000ff">new</span> System.Text.StringBuilder().AppendLine(msg).Append(_builder); <span style="color: #0000ff">else</span> _builder.AppendLine(msg);
} }</pre>
        </div>
        <p>
Now we need to add our new appender to the logger. I found this helper method someone
wrote.
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <span style="color: #0000ff">public</span>
            <span style="color: #0000ff">static</span>
            <span style="color: #0000ff">void</span> AddAppender(<span style="color: #0000ff">string</span> loggerName,
IAppender appender) { log4net.ILog log = log4net.LogManager.GetLogger(loggerName);
log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;
l.AddAppender(appender); }</pre>
        </div>
        <p>
Finally, lets put it all together:
</p>
        <div>
          <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">StringBuilderAppender appender = <span style="color: #0000ff">new</span> StringBuilderAppender(<span style="color: #0000ff">true</span>);
AddAppender(<span style="color: #006080">"MyLogger"</span>, appender); <span style="color: #0000ff">while</span>(<span style="color: #0000ff">true</span>)
{ System.Threading.Thread.Sleep(5000); someControl.Text = appender.Text; }</pre>
        </div>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=8396d43e-d21d-44fd-b279-b9e8940a3304" />
      </body>
      <title>Building a log4net appender</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</guid>
      <link>http://www.milkcarton.com/blog/2009/02/21/Building+A+Log4net+Appender.aspx</link>
      <pubDate>Sat, 21 Feb 2009 07:18:15 GMT</pubDate>
      <description>&lt;p&gt;
One of our applications has a Windows service in it. To make debugging and running
this service easy,we have a winform in the service which can be activated by passing
a command line switch. Simple enough. Our service does all its logging with log4net.
I wanted to be able to put the output of the logging on our development form, but
how?
&lt;/p&gt;
&lt;p&gt;
After looking at various things, I realized what I needed to do was create a log4net
appender, and add the appender to the log4net logger and at regular intervals, grab
the contents of the logger.
&lt;/p&gt;
&lt;h3&gt;Solution
&lt;/h3&gt;
&lt;p&gt;
I created the below appender which uses a StringBuilder as the backing store. It takes
in one bool param in the contructor which allows you to specify if you want the log
to be built up in reverse.&amp;nbsp; This is useful if you want to display the most recent
event at the top.
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; StringBuilderAppender
: log4net.Appender.AppenderSkeleton { &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; System.Text.StringBuilder
_builder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.Text.StringBuilder(); &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; _invert; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; StringBuilderAppender(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; invert)
{ _invert = invert; } &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Text
{ get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _builder.ToString(); } } &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;void&lt;/span&gt; Append(log4net.Core.LoggingEvent
loggingEvent) { var msg = loggingEvent.RenderedMessage; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (_invert)
_builder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.Text.StringBuilder().AppendLine(msg).Append(_builder); &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; _builder.AppendLine(msg);
} }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Now we need to add our new appender to the logger. I found this helper method someone
wrote.
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&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;void&lt;/span&gt; AddAppender(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; loggerName,
IAppender appender) { log4net.ILog log = log4net.LogManager.GetLogger(loggerName);
log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;
l.AddAppender(appender); }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Finally, lets put it all together:
&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;StringBuilderAppender appender = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilderAppender(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);
AddAppender(&lt;span style="color: #006080"&gt;"MyLogger"&lt;/span&gt;, appender); &lt;span style="color: #0000ff"&gt;while&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)
{ System.Threading.Thread.Sleep(5000); someControl.Text = appender.Text; }&lt;/pre&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=8396d43e-d21d-44fd-b279-b9e8940a3304" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,8396d43e-d21d-44fd-b279-b9e8940a3304.aspx</comments>
      <category>.NET</category>
      <category>HowTo</category>
      <category>Logging</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
At our organization, we have to globalize our software. Making sure you've gotten
all the strings globalized can be a real pain. You have to create a new language resource
that looks nothing like your native language, then set the Thread.CurrentThread.CurrentUICulture
to the culture of the new language resource you created.  Such a pain.
</p>
        <p>
While pondering that this afternoon, I came upon something better. The .NET CultureManger
looks for the most specific resource file, then works its way back to the least specific.
For example, given the following resource files:
</p>
        <ul>
          <li>
i18n 
</li>
          <li>
i18n.en 
</li>
          <li>
i18n.en-US</li>
        </ul>
        <p>
If your current culture was en-GB, the CultureManger would use the resource file for
i18n.en, since there is no i18n.en-GB. But, if your current culture was da-DK, it
would use i18n.
</p>
        <p>
In our software, we have i18n, and i18n.da-DK resource files, plus i18n.fr-FR which
is a special, internal resource file. What's so special about the fr-FR resource file
you ask? The fr-FR resource file is really the i18n resource file which as been transformed
to replace all the localized text with dashes.
</p>
        <p>
Why did we do this? Because with all the English text replaced with dashes, it makes
it very easy to see which text in the application hasn't been globalized. The down
side to this, is we have to change the CurrentUICulture (and CurrentCulture) to fr-FR
in order to test this.
</p>
        <h3>Solution
</h3>
        <p>
The solution is actually quite simple, rename the fr-FR resource file to i18n.en-US
(or what ever the ISO code for your culture is).  Now when your testing, the
CultureManager will pick the most specific resource file, and use that. But, don't
forget to remove en-US folder from the final build folder before you deploy your application,
lest users get your debug language resource.
</p>
        <p>
        </p>
        <a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx">
          <img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx" border="0" alt="kick it on DotNetKicks.com" />
        </a>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5" />
      </body>
      <title>A better, easier way to make sure you've globalized everything</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</guid>
      <link>http://www.milkcarton.com/blog/2009/02/10/A+Better+Easier+Way+To+Make+Sure+Youve+Globalized+Everything.aspx</link>
      <pubDate>Tue, 10 Feb 2009 23:11:48 GMT</pubDate>
      <description>&lt;p&gt;
At our organization, we have to globalize our software. Making sure you've gotten
all the strings globalized can be a real pain. You have to create a new language resource
that looks nothing like your native language, then set the Thread.CurrentThread.CurrentUICulture
to the culture of the new language resource you created.&amp;nbsp; Such a pain.
&lt;/p&gt;
&lt;p&gt;
While pondering that this afternoon, I came upon something better. The .NET CultureManger
looks for the most specific resource file, then works its way back to the least specific.
For example, given the following resource files:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
i18n 
&lt;li&gt;
i18n.en 
&lt;li&gt;
i18n.en-US&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If your current culture was en-GB, the CultureManger would use the resource file for
i18n.en, since there is no i18n.en-GB. But, if your current culture was da-DK, it
would use i18n.
&lt;/p&gt;
&lt;p&gt;
In our software, we have i18n, and i18n.da-DK resource files, plus i18n.fr-FR which
is a special, internal resource file. What's so special about the fr-FR resource file
you ask? The fr-FR resource file is really the i18n resource file which as been transformed
to replace all the localized text with dashes.
&lt;/p&gt;
&lt;p&gt;
Why did we do this? Because with all the English text replaced with dashes, it makes
it very easy to see which text in the application hasn't been globalized. The down
side to this, is we have to change the CurrentUICulture (and CurrentCulture) to fr-FR
in order to test this.
&lt;/p&gt;
&lt;h3&gt;Solution
&lt;/h3&gt;
&lt;p&gt;
The solution is actually quite simple, rename the fr-FR resource file to i18n.en-US
(or what ever the ISO code for your culture is).&amp;nbsp; Now when your testing, the
CultureManager will pick the most specific resource file, and use that. But, don't
forget to remove en-US folder from the final build folder before you deploy your application,
lest users get your debug language resource.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.milkcarton.com%2fblog%2f2009%2f02%2f10%2fA%2bBetter%2bEasier%2bWay%2bTo%2bMake%2bSure%2bYouve%2bGlobalized%2bEverything.aspx" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=dc6fd10c-b67e-4771-a7dc-9ee2444d02e5" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,dc6fd10c-b67e-4771-a7dc-9ee2444d02e5.aspx</comments>
      <category>.NET</category>
      <category>Globalization</category>
      <category>HowTo</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=65541c8f-4900-4677-bec2-557da84e1ecb</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,65541c8f-4900-4677-bec2-557da84e1ecb.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,65541c8f-4900-4677-bec2-557da84e1ecb.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=65541c8f-4900-4677-bec2-557da84e1ecb</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h3>The Problem
</h3>
        <p>
For the last few days I've been trying to figure out how to do this SQL in linq:
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 1:</span>
              <span style="color: #0000ff">select</span>
              <span style="color: #0000ff">from</span> customers <span style="color: #0000ff">where</span><span style="color: #0000ff">substring</span>(customers.Name,
1, 1) <span style="color: #0000ff">IN</span> (<span style="color: #006080">'a'</span>, <span style="color: #006080">'b'</span>, <span style="color: #006080">'c'</span>, <span style="color: #006080">'d'</span>);</pre>
          </div>
The problem is the list (a, b, c, d) is variable, on one page I need all the results
where foo.Name starts with a or b, on another it could be b, c, d, e and f. 
This is trivial to do in SQL, you just break out a little dynamic sql and your done. 
But being a noob to LINQ, I'm not so sure how to go about doing this.
</div>
        <p>
I had a lot of failed queries, and failed code, before giving up and just looping
through the letters for that particular page and manually building up what I wanted.
</p>
        <p>
But that's kind of a hack. OK, its not kind of a hack, its a big hack.
</p>
        <h3>The Solution
</h3>
        <p>
This LINQ goodness (using the Customers db in <a href="http://www.linqpad.net/">LINQPad</a>)
will pull back all the customers who's names begin with a t, d, or j (note the .ToList()
on line 4, I'll discuss it next).
</p>
        <div>
          <div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 1:</span>
              <span style="color: #0000ff">string</span>[]
letters = { <span style="color: #006080">"t"</span>, <span style="color: #006080">"d"</span>, <span style="color: #006080">"j"</span> }; </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 2:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 3:</span> var
customers = (from c <span style="color: #0000ff">in</span> Customers</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 4:</span> select
c).ToList(); </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 5:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 6:</span> var
results = from c <span style="color: #0000ff">in</span> customers</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 7:</span> join
letter <span style="color: #0000ff">in</span> letters on c.Name.First().ToString().ToUpper()
equals letter.ToUpper()</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 8:</span> select
c; </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 9:</span>  </pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 10:</span> customers.Dump(<span style="color: #006080">"Customers"</span>);</pre>
            <pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
              <span style="color: #606060"> 11:</span> results.Dump(<span style="color: #006080">"Filtered
by first letter"</span>);</pre>
          </div>
        </div>
        <p>
And LINQPad renders this for us:
</p>
        <p>
          <a href="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/LINQGoodness_E90/image_2.png">
            <img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/LINQGoodness_E90/image_thumb.png" width="176" border="0" />
          </a>
        </p>
        <h3>
Limitations
</h3>
        <p>
LINQ to SQL doesn't support querying a SQL database with if one of your sources is
an in-memory store, except if you use the Contains operator.  So, to work around
that, you have to pull back ALL the results from the db, and then convert it to a
List before you use it in the above query.
</p>
        <p>
I'm my opinion, this is kind of a painful limitation, but for my particular purpose,
I'm willing to live with it because my particular database will only ever have around
100 or so rows, so pulling everything back in memory isn't such a big deal...
</p>
        <p>
P.S. if you are reading this in a feed reader, let me know how it renders, I've updated
my code snippet plugin to try and fix the previous rendering problems.
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=65541c8f-4900-4677-bec2-557da84e1ecb" />
      </body>
      <title>LINQ Goodness</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,65541c8f-4900-4677-bec2-557da84e1ecb.aspx</guid>
      <link>http://www.milkcarton.com/blog/2008/05/09/LINQ+Goodness.aspx</link>
      <pubDate>Fri, 09 May 2008 09:13:08 GMT</pubDate>
      <description>&lt;h3&gt;The Problem
&lt;/h3&gt;
&lt;p&gt;
For the last few days I've been trying to figure out how to do this SQL in linq:
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;from&lt;/span&gt; customers &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; &lt;span style="color: #0000ff"&gt;substring&lt;/span&gt;(customers.Name,
1, 1) &lt;span style="color: #0000ff"&gt;IN&lt;/span&gt; (&lt;span style="color: #006080"&gt;'a'&lt;/span&gt;, &lt;span style="color: #006080"&gt;'b'&lt;/span&gt;, &lt;span style="color: #006080"&gt;'c'&lt;/span&gt;, &lt;span style="color: #006080"&gt;'d'&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
The problem is the list (a, b, c, d) is variable, on one page I need all the results
where foo.Name starts with a or b, on another it could be b, c, d, e and f.&amp;nbsp;
This is trivial to do in SQL, you just break out a little dynamic sql and your done.&amp;nbsp;
But being a noob to LINQ, I'm not so sure how to go about doing this.
&lt;/div&gt;
&lt;p&gt;
I had a lot of failed queries, and failed code, before giving up and just looping
through the letters for that particular page and manually building up what I wanted.
&lt;/p&gt;
&lt;p&gt;
But that's kind of a hack. OK, its not kind of a hack, its a big hack.
&lt;/p&gt;
&lt;h3&gt;The Solution
&lt;/h3&gt;
&lt;p&gt;
This LINQ goodness (using the Customers db in &lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt;)
will pull back all the customers who's names begin with a t, d, or j (note the .ToList()
on line 4, I'll discuss it next).
&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[]
letters = { &lt;span style="color: #006080"&gt;"t"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"d"&lt;/span&gt;, &lt;span style="color: #006080"&gt;"j"&lt;/span&gt; }; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 2:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 3:&lt;/span&gt; var
customers = (from c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; Customers&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 4:&lt;/span&gt; select
c).ToList(); &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 5:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 6:&lt;/span&gt; var
results = from c &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; customers&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 7:&lt;/span&gt; join
letter &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; letters on c.Name.First().ToString().ToUpper()
equals letter.ToUpper()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 8:&lt;/span&gt; select
c; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 9:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 10:&lt;/span&gt; customers.Dump(&lt;span style="color: #006080"&gt;"Customers"&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt; 11:&lt;/span&gt; results.Dump(&lt;span style="color: #006080"&gt;"Filtered
by first letter"&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And LINQPad renders this for us:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/LINQGoodness_E90/image_2.png"&gt;&lt;img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.milkcarton.com/blog/content/binary/WindowsLiveWriter/LINQGoodness_E90/image_thumb.png" width="176" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;
Limitations
&lt;/h3&gt;
&lt;p&gt;
LINQ to SQL doesn't support querying a SQL database with if one of your sources is
an in-memory store, except if you use the Contains operator.&amp;nbsp; So, to work around
that, you have to pull back ALL the results from the db, and then convert it to a
List before you use it in the above query.
&lt;/p&gt;
&lt;p&gt;
I'm my opinion, this is kind of a painful limitation, but for my particular purpose,
I'm willing to live with it because my particular database will only ever have around
100 or so rows, so pulling everything back in memory isn't such a big deal...
&lt;/p&gt;
&lt;p&gt;
P.S. if you are reading this in a feed reader, let me know how it renders, I've updated
my code snippet plugin to try and fix the previous rendering problems.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=65541c8f-4900-4677-bec2-557da84e1ecb" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,65541c8f-4900-4677-bec2-557da84e1ecb.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>LINQ</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=aa751f74-30f0-4d38-aaf7-36e2c75ea382</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,aa751f74-30f0-4d38-aaf7-36e2c75ea382.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,aa751f74-30f0-4d38-aaf7-36e2c75ea382.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=aa751f74-30f0-4d38-aaf7-36e2c75ea382</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <h3>Background Information
</h3>
        <p>
Aspect Oriented Programming has been on my list of things to read up on for almost
a year now.  It likely would have stayed on my list of things to do well into
the future if it hadn't been for a recent <a href="http://www.dotnetrocks.com/">.NET
Rocks</a> episode.  I can't recall if it was the <a href="http://www.dotnetrocks.com/default.aspx?showNum=289">Pablo
Castro on Astoria</a>, or the <a href="http://www.dotnetrocks.com/default.aspx?showNum=290">Tim
Sneath and Ian Ellison</a> show, but one of them off-hand mentioned <a href="http://www.postsharp.org/">PostSharp</a>. 
As I usually do when links are thrown about on the show, I scribbled it on my hand
for later review. <b>Update</b><a href="http://www.dotnetrocks.com/default.aspx?showNum=298">DNR
just released a show with Gael Fraiteur of PostSharp</a> fame!<br /></p>
        <p>
Once I got to the PostSharp site, I found their <a href="http://www.postsharp.org/documentation/simple-trace-aspect-tutorial">sample
video on creating a trace AOP attribute</a>.  They had me hooked.  I wasn't
so much interested in doing a logging or trace attribute, but was more interested
in doing a few validation attributes.  More specifically a NotNullAttribute.
</p>
        <h3>The Problem
</h3>
        <p>
What got me interested in doing the NotNullAttribute was thinking back to how many
times in our code base we would have something like this:
</p>
        <pre>
          <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:412e8b34-6570-4246-b54c-2d1eec69d82e" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false">
            <pre style="overflow: auto; background-color: rgb(255, 255, 128);">
              <div>
                <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
                <span style="color: rgb(0, 128, 128);"> 1</span>
                <span style="color: rgb(0, 0, 255);">public</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">void</span>
                <span style="color: rgb(0, 0, 0);"> AddUser(Organization
org, User user) </span>
                <span style="color: rgb(0, 128, 128);"> 2</span>
                <span style="color: rgb(0, 0, 0);">{ </span>
                <span style="color: rgb(0, 128, 128);"> 3</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">if</span>
                <span style="color: rgb(0, 0, 0);"> (org </span>
                <span style="color: rgb(0, 0, 0);">==</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">null</span>
                <span style="color: rgb(0, 0, 0);">) </span>
                <span style="color: rgb(0, 128, 128);"> 4</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">throw</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">new</span>
                <span style="color: rgb(0, 0, 0);"> ArgumentNullException(</span>
                <span style="color: rgb(128, 0, 0);">"</span>
                <span style="color: rgb(128, 0, 0);">org</span>
                <span style="color: rgb(128, 0, 0);">"</span>
                <span style="color: rgb(0, 0, 0);">); </span>
                <span style="color: rgb(0, 128, 128);"> 5</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">if</span>
                <span style="color: rgb(0, 0, 0);"> (user </span>
                <span style="color: rgb(0, 0, 0);">==</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">null</span>
                <span style="color: rgb(0, 0, 0);">) </span>
                <span style="color: rgb(0, 128, 128);"> 6</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">throw</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 0, 255);">new</span>
                <span style="color: rgb(0, 0, 0);"> ArgumentNullException(</span>
                <span style="color: rgb(128, 0, 0);">"</span>
                <span style="color: rgb(128, 0, 0);">user</span>
                <span style="color: rgb(128, 0, 0);">"</span>
                <span style="color: rgb(0, 0, 0);">); </span>
                <span style="color: rgb(0, 128, 128);"> 7</span>
                <span style="color: rgb(0, 0, 0);">
                </span>
                <span style="color: rgb(0, 128, 128);"> 8</span>
                <span style="color: rgb(0, 0, 0);"> org.AddUser(user); </span>
                <span style="color: rgb(0, 128, 128);"> 9</span>
                <span style="color: rgb(0, 0, 0);"> _ordDal.Save(org); </span>
                <span style="color: rgb(0, 128, 128);">10</span>
                <span style="color: rgb(0, 0, 0);">}</span>
              </div>
            </pre>
            <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
          </div>
        </pre>
        <p>
        </p>
        <p>
Granted this is a somewhat short method, but we have methods which take 6 parameters,
and only 2 actual lines of code.  That's 12 lines of code taken up for argument
checking, and 2 lines of code.  That would put our crap to code ratio at 6/1.
</p>
        <h3>The Solution
</h3>
        <p>
Wouldn't it be much nicer if you could do something like this:
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b14b6321-8fde-41c3-a4c5-e50fc4fd2847" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false">
          <pre style="overflow: auto; background-color: rgb(255, 255, 128);">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: rgb(0, 128, 128);">1</span>
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">void</span>
              <span style="color: rgb(0, 0, 0);"> AddUser([NotNull]
Organization org, [NotNull] User user) </span>
              <span style="color: rgb(0, 128, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">{ </span>
              <span style="color: rgb(0, 128, 128);">3</span>
              <span style="color: rgb(0, 0, 0);"> org.AddUser(user); </span>
              <span style="color: rgb(0, 128, 128);">4</span>
              <span style="color: rgb(0, 0, 0);"> _ordDal.Save(org); </span>
              <span style="color: rgb(0, 128, 128);">5</span>
              <span style="color: rgb(0, 0, 0);">}</span>
            </div>
          </pre>
          <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
        </div>
        <p>
        </p>
        <p>
 
</p>
        <p>
PostSharp is almost there to let you write code just like that.  Currently, there
is no support for an OnParameterAspectBoundaryAttribute in PostSharp, so we have to
do things just slightly differently:
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:497ca957-7091-4b07-84f7-3f49ed150dad" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false">
          <pre style="overflow: auto; background-color: rgb(255, 255, 128);">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: rgb(0, 0, 0);">[NotNullHelper] </span>
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">void</span>
              <span style="color: rgb(0, 0, 0);"> AddUser([NotNull]
Organization org, [NotNull] User user) { org.AddUser(user); _ordDal.Save(org); }</span>
            </div>
          </pre>
          <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
        </div>
        <p>
        </p>
        <p>
We have to have a helper class were all the actual code lives.
</p>
        <h3>How PostSharp Works
</h3>
        <p>
PostSharp works by weaving all your AOP attributes with your source code after the
compiler compiles your code.  This <a href="http://www.codeproject.com/useritems/ps-custom-attributes-2.asp">article
by Gael Fraiteur describes in more detail how the PostSharp process works</a>. 
After the code is post-compiled by PostSharp, you end up with something very ugly
that looks like this:
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ec455986-ad9f-4f97-aeba-2727cc90f106" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false">
          <pre style="overflow: auto; background-color: rgb(255, 255, 128);">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">void</span>
              <span style="color: rgb(0, 0, 0);"> AddUser([NotNull]
Organization org, [NotNull] User user) { MethodExecutionEventArgs </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">; </span>
              <span style="color: rgb(0, 0, 255);">try</span>
              <span style="color: rgb(0, 0, 0);"> { </span>
              <span style="color: rgb(0, 0, 255);">object</span>
              <span style="color: rgb(0, 0, 0);">[] </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">arguments</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">1</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">new</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">object</span>
              <span style="color: rgb(0, 0, 0);">[]
{ org, user }; </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">new</span>
              <span style="color: rgb(0, 0, 0);"> MethodExecutionEventArgs(methodof(OrgManager.AddUser,
OrgManager), </span>
              <span style="color: rgb(0, 0, 255);">this</span>
              <span style="color: rgb(0, 0, 0);">, </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">arguments</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">1</span>
              <span style="color: rgb(0, 0, 0);">); </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">PostSharp</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Laos</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Implementation.NotNullHelperAttribute</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">3</span>
              <span style="color: rgb(0, 0, 0);">.OnEntry(</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">); </span>
              <span style="color: rgb(0, 0, 255);">if</span>
              <span style="color: rgb(0, 0, 0);"> (</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">.FlowBehavior </span>
              <span style="color: rgb(0, 0, 0);">!=</span>
              <span style="color: rgb(0, 0, 0);"> FlowBehavior.Return)
{ org.AddUser(user); _orgDal.Save(org); </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">PostSharp</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Laos</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Implementation.NotNullHelperAttribute</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">3</span>
              <span style="color: rgb(0, 0, 0);">.OnSuccess(</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">);
} } </span>
              <span style="color: rgb(0, 0, 255);">catch</span>
              <span style="color: rgb(0, 0, 0);"> (Exception </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">exception</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">0</span>
              <span style="color: rgb(0, 0, 0);">)
{ </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">.Exception </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">exception</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">0</span>
              <span style="color: rgb(0, 0, 0);">; </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">PostSharp</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Laos</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Implementation.NotNullHelperAttribute</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">3</span>
              <span style="color: rgb(0, 0, 0);">.OnException(</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">); </span>
              <span style="color: rgb(0, 0, 255);">switch</span>
              <span style="color: rgb(0, 0, 0);"> (</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">.FlowBehavior)
{ </span>
              <span style="color: rgb(0, 0, 255);">case</span>
              <span style="color: rgb(0, 0, 0);"> FlowBehavior.Continue: </span>
              <span style="color: rgb(0, 0, 255);">case</span>
              <span style="color: rgb(0, 0, 0);"> FlowBehavior.Return: </span>
              <span style="color: rgb(0, 0, 255);">return</span>
              <span style="color: rgb(0, 0, 0);">;
} </span>
              <span style="color: rgb(0, 0, 255);">throw</span>
              <span style="color: rgb(0, 0, 0);">;
} </span>
              <span style="color: rgb(0, 0, 255);">finally</span>
              <span style="color: rgb(0, 0, 0);"> { </span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">PostSharp</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Laos</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">Implementation.NotNullHelperAttribute</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">3</span>
              <span style="color: rgb(0, 0, 0);">.OnExit(</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(0, 0, 0);">laosEventArgs</span>
              <span style="color: rgb(0, 0, 0);">~</span>
              <span style="color: rgb(128, 0, 128);">2</span>
              <span style="color: rgb(0, 0, 0);">);
} }</span>
            </div>
          </pre>
          <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
        </div>
        <p>
        </p>
        <p>
I don't know about you, but I would have one HELL of a time trying to debug this,
thankfully PostSharp touches up the PDB files, so when your debugging, you only see
and debug the source code you've written, both your attribute, and your business logic.
</p>
        <h3>The Drawbacks
</h3>
        <p>
PostSharp modifies your code! Well, not directly, but it is still modifying your code
(as seen above), but thankfully it touches up the PDB files so all the mess under
the hood is hidden from you.
</p>
        <h3>Conclusion
</h3>
        <p>
This is but one of the many things you can do with AOP and PostSharp.  Next up,
I plan to write some validation attributes.  Look for those in the next few weeks. 
In the mean time, <a href="http://www.milkcarton.com/blog/content/binary/NotNullAttribute.cs.txt">download
the source code for the NotNullAttribute</a>.
</p>
        <p>
I'm sorry if this post looks terrible in your feed reader, I still haven't been able
to figure out why the code looks terrible.  If anyone has any suggestions, let
me know.  I'm using DasBlogCE as my blog engine.
</p>
        <a href="http://www.dotnetkicks.com/kick/?url=http://www.milkcarton.com/blog/2007/11/26/Decrapify+Your+Code+Base+With+AOP+Using+PostSharp.aspx">
          <img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.milkcarton.com/blog/2007/11/26/Decrapify+Your+Code+Base+With+AOP+Using+PostSharp.aspx" border="0" />
        </a>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=aa751f74-30f0-4d38-aaf7-36e2c75ea382" />
      </body>
      <title>De-crapify your code base with AOP using PostSharp</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,aa751f74-30f0-4d38-aaf7-36e2c75ea382.aspx</guid>
      <link>http://www.milkcarton.com/blog/2007/11/26/Decrapify+Your+Code+Base+With+AOP+Using+PostSharp.aspx</link>
      <pubDate>Mon, 26 Nov 2007 05:37:23 GMT</pubDate>
      <description>&lt;h3&gt;Background Information
&lt;/h3&gt;
&lt;p&gt;
Aspect Oriented Programming has been on my list of things to read up on for almost
a year now.&amp;nbsp; It likely would have stayed on my list of things to do well into
the future if it hadn't been for a recent &lt;a href="http://www.dotnetrocks.com/"&gt;.NET
Rocks&lt;/a&gt;&amp;nbsp;episode.&amp;nbsp; I can't recall if it was the &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=289"&gt;Pablo
Castro on Astoria&lt;/a&gt;, or the &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=290"&gt;Tim
Sneath and Ian Ellison&lt;/a&gt;&amp;nbsp;show, but one of them off-hand mentioned &lt;a href="http://www.postsharp.org/"&gt;PostSharp&lt;/a&gt;.&amp;nbsp;
As I usually do when links are thrown about on the show, I scribbled it on my hand
for later review. &lt;b&gt;Update&lt;/b&gt; &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=298"&gt;DNR
just released a show with Gael Fraiteur of PostSharp&lt;/a&gt; fame!&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
Once I got to the PostSharp site, I found their &lt;a href="http://www.postsharp.org/documentation/simple-trace-aspect-tutorial"&gt;sample
video on creating a trace AOP attribute&lt;/a&gt;.&amp;nbsp; They had me hooked.&amp;nbsp; I wasn't
so much interested in doing a logging or trace attribute, but was more interested
in doing a few validation attributes.&amp;nbsp; More specifically a NotNullAttribute.
&lt;/p&gt;
&lt;h3&gt;The Problem
&lt;/h3&gt;
&lt;p&gt;
What got me interested in doing the NotNullAttribute was thinking back to how many
times in our code base we would have something like this:
&lt;/p&gt;
&lt;pre&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:412e8b34-6570-4246-b54c-2d1eec69d82e" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AddUser(Organization
org, User user) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (org &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ArgumentNullException(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;org&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (user &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; ArgumentNullException(&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;user&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; org.AddUser(user); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; _ordDal.Save(org); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Granted this is a somewhat short method, but we have methods which take 6 parameters,
and only 2 actual&amp;nbsp;lines of code.&amp;nbsp; That's 12 lines of code taken up for argument
checking, and 2 lines of code.&amp;nbsp; That would put our crap to code ratio at 6/1.
&lt;/p&gt;
&lt;h3&gt;The Solution
&lt;/h3&gt;
&lt;p&gt;
Wouldn't it be much nicer if you could do something like this:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:b14b6321-8fde-41c3-a4c5-e50fc4fd2847" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AddUser([NotNull]
Organization org, [NotNull] User user) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; org.AddUser(user); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; _ordDal.Save(org); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
PostSharp is almost there to let you write code just like that.&amp;nbsp; Currently, there
is no support for an OnParameterAspectBoundaryAttribute in PostSharp, so we have to
do things just slightly differently:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:497ca957-7091-4b07-84f7-3f49ed150dad" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[NotNullHelper] &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AddUser([NotNull]
Organization org, [NotNull] User user) { org.AddUser(user); _ordDal.Save(org); }&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
We have to have a helper class were all the actual code lives.
&lt;/p&gt;
&lt;h3&gt;How&amp;nbsp;PostSharp Works
&lt;/h3&gt;
&lt;p&gt;
PostSharp works by weaving all your AOP attributes with your source code after the
compiler compiles your code.&amp;nbsp; This &lt;a href="http://www.codeproject.com/useritems/ps-custom-attributes-2.asp"&gt;article
by Gael Fraiteur describes in more detail how the PostSharp process works&lt;/a&gt;.&amp;nbsp;
After the code is post-compiled by PostSharp, you end up with something very ugly
that looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:ec455986-ad9f-4f97-aeba-2727cc90f106" style="margin: 0px; padding: 0px; display: inline; float: none;" contenteditable="false"&gt;&lt;pre style="overflow: auto; background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; AddUser([NotNull]
Organization org, [NotNull] User user) { MethodExecutionEventArgs &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;try&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;arguments&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[]
{ org, user }; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; MethodExecutionEventArgs(methodof(OrgManager.AddUser,
OrgManager), &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;arguments&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;PostSharp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Laos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Implementation.NotNullHelperAttribute&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OnEntry(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.FlowBehavior &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;!=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FlowBehavior.Return)
{ org.AddUser(user); _orgDal.Save(org); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;PostSharp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Laos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Implementation.NotNullHelperAttribute&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OnSuccess(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
} } &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;catch&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (Exception &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;exception&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)
{ &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Exception &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;exception&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;PostSharp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Laos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Implementation.NotNullHelperAttribute&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OnException(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;switch&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.FlowBehavior)
{ &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;case&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FlowBehavior.Continue: &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;case&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FlowBehavior.Return: &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
} &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
} &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;finally&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;PostSharp&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Laos&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Implementation.NotNullHelperAttribute&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;3&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.OnExit(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;laosEventArgs&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;~&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;2&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;);
} }&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I don't know about you, but I would have&amp;nbsp;one HELL of a time trying to debug this,
thankfully PostSharp touches up the PDB files, so when your debugging, you only see
and debug the source code you've written, both your attribute, and your business logic.
&lt;/p&gt;
&lt;h3&gt;The Drawbacks
&lt;/h3&gt;
&lt;p&gt;
PostSharp modifies your code! Well, not directly, but it is still modifying your code
(as seen above), but thankfully it touches up the PDB files so all the mess under
the hood is hidden from you.
&lt;/p&gt;
&lt;h3&gt;Conclusion
&lt;/h3&gt;
&lt;p&gt;
This is but one of the many things you can do with AOP and PostSharp.&amp;nbsp; Next up,
I plan to write some validation attributes.&amp;nbsp; Look for those in the next few weeks.&amp;nbsp;
In the mean time, &lt;a href="http://www.milkcarton.com/blog/content/binary/NotNullAttribute.cs.txt"&gt;download
the source code for the NotNullAttribute&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
I'm sorry if this post looks terrible in your feed reader, I still haven't been able
to figure out why the code looks terrible.&amp;nbsp; If anyone has any suggestions, let
me know.&amp;nbsp; I'm using DasBlogCE as my blog engine.
&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http://www.milkcarton.com/blog/2007/11/26/Decrapify+Your+Code+Base+With+AOP+Using+PostSharp.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.milkcarton.com/blog/2007/11/26/Decrapify+Your+Code+Base+With+AOP+Using+PostSharp.aspx" border="0"&gt;&lt;/a&gt;&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=aa751f74-30f0-4d38-aaf7-36e2c75ea382" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,aa751f74-30f0-4d38-aaf7-36e2c75ea382.aspx</comments>
      <category>.NET</category>
      <category>AOP</category>
      <category>C#</category>
      <category>PostSharp</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=9fe3849a-f364-43ea-acb4-b100e991e1cc</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,9fe3849a-f364-43ea-acb4-b100e991e1cc.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,9fe3849a-f364-43ea-acb4-b100e991e1cc.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9fe3849a-f364-43ea-acb4-b100e991e1cc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Usually I post solutions I've discovered or created to problems I've encountered. 
Now, I've run into a problem with the XmlSerializer and I need your help solving it.  Scroll
to the bottom for an update.
</p>
        <h3>The Problem
</h3>
        <p>
I have a class called Foobar.  Foobar inherits from List&lt;string&gt;, and contains
one member Title.  When I use the XmlSerializer to serialize and deserialize
Foobar, all the items in the List are make it through safely, but the member Title
does not.
</p>
        <h3>The Code
</h3>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cd057b70-45a7-4b72-a7db-655bf0456e1b" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <pre style="background-color:#FFFF80;">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: #0000FF; ">using</span>
              <span style="color: #000000; "> System; </span>
              <span style="color: #0000FF; ">using</span>
              <span style="color: #000000; "> System.Collections.Generic; </span>
              <span style="color: #0000FF; ">using</span>
              <span style="color: #000000; "> System.IO; </span>
              <span style="color: #0000FF; ">using</span>
              <span style="color: #000000; "> System.Xml.Serialization; </span>
              <span style="color: #0000FF; ">internal</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">class</span>
              <span style="color: #000000; "> Program
{ </span>
              <span style="color: #0000FF; ">private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">static</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">void</span>
              <span style="color: #000000; "> Main()
{ Foobar f </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">new</span>
              <span style="color: #000000; "> Foobar();
f.Add(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">1</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">);
f.Add(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">2</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">);
f.Title </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">Title</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">;
MemoryStream mem </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">new</span>
              <span style="color: #000000; "> MemoryStream();
XmlSerializer xs </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">new</span>
              <span style="color: #000000; "> XmlSerializer(</span>
              <span style="color: #0000FF; ">typeof</span>
              <span style="color: #000000; ">(Foobar));
xs.Serialize(mem, f); mem.Seek(</span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">);
mem.Seek(</span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">);
Foobar deser </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> (Foobar)xs.Deserialize(mem);
Console.WriteLine(deser); } } [Serializable] </span>
              <span style="color: #0000FF; ">public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">class</span>
              <span style="color: #000000; "> Foobar
: List</span>
              <span style="color: #000000; ">&lt;</span>
              <span style="color: #0000FF; ">string</span>
              <span style="color: #000000; ">&gt;</span>
              <span style="color: #000000; "> { </span>
              <span style="color: #0000FF; ">public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">string</span>
              <span style="color: #000000; "> Title;
}</span>
            </div>
          </pre>
        </div>
        <h3>The Solution
</h3>
        <p>
One way I came up with to solve this problem is make Foobar not inherit from List&lt;string&gt;,
and make a member called Items that is a List&lt;string&gt;, but that's kind of hokey. 
I've searched Google and can't find a solution.  So I'm appealing to my dear
readers for a better solution.
</p>
        <h3>Update
</h3>
        <p>
Looks like I was being way to specific in my Google search, searching on "XmlSerializer
List" gives us this <a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;SiteID=1" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;SiteID=1">http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;SiteID=1</a> as
the first item.  In the post, 
</p>
        <p>
Elena Kharitidi says "XmlSerializer does not serialize any members if a collection.
Only collection items get serialized. This is by design, basically a decision was
made to handle collections as arrays not as classes with multiple properties, so collections
should look like arrays on the wire, therefore they do not have any members other
then collection items, and can be “flattened” by adding the [XmlElement] to the member
of the ICollection type." 
</p>
        <p>
Long and short, I need to use the hokey solution I came up with (or something like
it), or write my own serializer.
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=9fe3849a-f364-43ea-acb4-b100e991e1cc" />
      </body>
      <title>Problems serializing class which inherits from a generic list</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,9fe3849a-f364-43ea-acb4-b100e991e1cc.aspx</guid>
      <link>http://www.milkcarton.com/blog/2007/09/13/Problems+Serializing+Class+Which+Inherits+From+A+Generic+List.aspx</link>
      <pubDate>Thu, 13 Sep 2007 15:22:29 GMT</pubDate>
      <description>&lt;p&gt;
Usually I post solutions I've discovered or created to problems I've encountered.&amp;nbsp;
Now, I've run into a problem with the XmlSerializer and I need your help solving it.&amp;nbsp;&amp;nbsp;Scroll
to the bottom&amp;nbsp;for an update.
&lt;/p&gt;
&lt;h3&gt;The Problem
&lt;/h3&gt;
&lt;p&gt;
I have a class called Foobar.&amp;nbsp; Foobar inherits from List&amp;lt;string&amp;gt;, and contains
one member Title.&amp;nbsp; When I use the XmlSerializer to serialize and deserialize
Foobar, all the items in the List are make it through safely, but the member Title
does not.
&lt;/p&gt;
&lt;h3&gt;The Code
&lt;/h3&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:cd057b70-45a7-4b72-a7db-655bf0456e1b" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:#FFFF80;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;using&lt;/span&gt;&lt;span style="color: #000000; "&gt; System; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;using&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.Collections.Generic; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;using&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.IO; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;using&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.Xml.Serialization; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;internal&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; Program
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;static&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; Main()
{ Foobar f &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Foobar();
f.Add(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
f.Add(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;2&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
f.Title &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;Title&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
MemoryStream mem &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; MemoryStream();
XmlSerializer xs &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlSerializer(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(Foobar));
xs.Serialize(mem, f); mem.Seek(&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
mem.Seek(&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;);
Foobar deser &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Foobar)xs.Deserialize(mem);
Console.WriteLine(deser); } } [Serializable] &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; Foobar
: List&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; Title;
}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&gt;
&lt;h3&gt;The Solution
&lt;/h3&gt;
&lt;p&gt;
One way I came up with to solve this problem is make Foobar not inherit from List&amp;lt;string&amp;gt;,
and make a member called Items that is a List&amp;lt;string&amp;gt;, but that's kind of hokey.&amp;nbsp;
I've searched Google and can't find a solution.&amp;nbsp; So I'm appealing to my dear
readers for a better solution.
&lt;/p&gt;
&lt;h3&gt;Update
&lt;/h3&gt;
&lt;p&gt;
Looks like I was being way to specific in my Google search, searching on "XmlSerializer
List" gives us this &lt;a title="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;amp;SiteID=1" href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;amp;SiteID=1"&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=566175&amp;amp;SiteID=1&lt;/a&gt;&amp;nbsp;as
the first item.&amp;nbsp; In the post, 
&lt;/p&gt;
&lt;p&gt;
Elena Kharitidi says "XmlSerializer does not serialize any members if a collection.
Only collection items get serialized. This is by design, basically a decision was
made to handle collections as arrays not as classes with multiple properties, so collections
should look like arrays on the wire, therefore they do not have any members other
then collection items, and can be “flattened” by adding the [XmlElement] to the member
of the ICollection type." 
&lt;p&gt;
Long and short, I need to use the hokey solution I came up with (or something like
it), or write my own serializer.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=9fe3849a-f364-43ea-acb4-b100e991e1cc" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,9fe3849a-f364-43ea-acb4-b100e991e1cc.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>XmlSerializer</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=1e707a99-6d90-4d04-984d-988d378137b3</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,1e707a99-6d90-4d04-984d-988d378137b3.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,1e707a99-6d90-4d04-984d-988d378137b3.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1e707a99-6d90-4d04-984d-988d378137b3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I downloaded the very excellent Resource Refactoring Tool (<a title="http://www.codeplex.com/ResourceRefactoring" href="http://www.codeplex.com/ResourceRefactoring">http://www.codeplex.com/ResourceRefactoring</a>)
the other day.  It works great in code files, but I found that it didn't work
at all for ASPX/HTML pages.  Seeing this as a challenge, I decided to hack something
up in VBA to automatically extract the selected text, create a resx name for the text,
add it to the resource file, and insert the ASP.NET literal control.
</p>
        <h3>How to use it
</h3>
        <p>
This is split up into two different macro modules, one named Utilities, and the other
named what ever you want.  Then add them to your Visual Studio tool bar so you
have something convenient you can click on (Right click the tool bar, click Customize,
click Commands, then Macros under categories, find what you named the macro and then
drag it up to your tool bar.  You can either drag it to an existing tool strip,
or create your own.  Finally right click on the item while still in customize
mode and add an image).
</p>
        <p>
 
</p>
        <p>
Caller:
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:1329ba2c-a1eb-4272-be95-d8be9e1e94a7" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <pre style="background-color:#FFFF80;">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> System </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> EnvDTE </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> EnvDTE80 </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> System.Diagnostics </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Module</span>
              <span style="color: #000000; "> MoreMacros </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Sub</span>
              <span style="color: #000000; "> AspTextLiteral() </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> resx </span>
              <span style="color: #0000FF; ">as</span>
              <span style="color: #000000; "> ProjectItem </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> DTE.ActiveWindow.Object.GetItem(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">solution\project\folder\ResourceFile.resx</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">)
Utilities.AspTextLiteral(resx) </span>
              <span style="color: #0000FF; ">End Sub</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Sub</span>
              <span style="color: #000000; "> InQuoteLiteral()
DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate() </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> resx </span>
              <span style="color: #0000FF; ">as</span>
              <span style="color: #000000; "> ProjectItem </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> DTE.ActiveWindow.Object.GetItem(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">solution\project\folder\ResourceFile.resx</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">)
Utilities.InQuoteLiteral(resx) </span>
              <span style="color: #0000FF; ">End Sub</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">End
Module</span>
              <span style="color: #000000; ">
              </span>
            </div>
          </pre>
        </div>
        <p>
Utilities: 
</p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7d5c45be-dc14-4893-a3ac-dcbe121d224d" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <pre style="background-color:#FFFF80;">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> System </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> EnvDTE </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> EnvDTE80 </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> System.Diagnostics </span>
              <span style="color: #0000FF; ">Imports</span>
              <span style="color: #000000; "> System.Xml </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Module</span>
              <span style="color: #000000; "> Utilities </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Sub</span>
              <span style="color: #000000; "> AspTextLiteral(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> resourceFile </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> ProjectItem) </span>
              <span style="color: #0000FF; ">Const</span>
              <span style="color: #000000; "> literalFormat </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">&lt;asp:Literal
runat=""server"" Text=""&lt;%$ Resources:{0},{1}%&gt;""
/&gt;</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Const</span>
              <span style="color: #000000; "> inQuotesFormat </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">&lt;%$
Resources:{0},{1}%&gt;</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; "> LiteralReplacer(resourceFile,
literalFormat, </span>
              <span style="color: #000000; ">4</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">End
Sub</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Sub</span>
              <span style="color: #000000; "> InQuoteLiteral(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> resourceFile </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> ProjectItem) </span>
              <span style="color: #0000FF; ">Const</span>
              <span style="color: #000000; "> inQuotesFormat </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">&lt;%$
Resources:{0},{1}%&gt;</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; "> LiteralReplacer(resourceFile,
inQuotesFormat, </span>
              <span style="color: #000000; ">3</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">End
Sub</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Sub</span>
              <span style="color: #000000; "> LiteralReplacer(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> resourceFile </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> ProjectItem, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> template </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> delete </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> Int16) </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> ts </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> TextSelection </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> DTE.ActiveDocument.Selection </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> StripNonAllowedChars(ts.Text).Trim.ToLower </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> value </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> ts.Text </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> path </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> resourceFile.Properties.Item(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">LocalPath</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">).Value </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> resName </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> System.IO.Path.GetFileNameWithoutExtension(resourceFile.Name)
name </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> AddResourceEntry(path,
name, value) ts.Text </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">.Format(template,
resName, name) DTE.ActiveDocument.Selection.Delete(delete) </span>
              <span style="color: #0000FF; ">End
Sub</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #008000; ">'</span>
              <span style="color: #008000; ">Returns
the value of the name used</span>
              <span style="color: #008000; ">
              </span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Public</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> AddResourceEntry(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> resourceFilePath </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> value </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> doc </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlDocument </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">New</span>
              <span style="color: #000000; "> XmlDocument
doc.Load(resourceFilePath) </span>
              <span style="color: #008000; ">'</span>
              <span style="color: #008000; ">See
if it exists first</span>
              <span style="color: #008000; ">
              </span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> root </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> doc.DocumentElement </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> e </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> root.SelectSingleNode(</span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">.Format(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">data[@name=""{0}""]</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">,
name)) </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; "> e </span>
              <span style="color: #0000FF; ">Is</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Nothing</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> CreateUniqueName(root,
name) </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> elem </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> CreateResourceFileElement(doc,
name, value) root.AppendChild(elem) </span>
              <span style="color: #0000FF; ">Else</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; "> e.SelectSingleNode(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">value</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">).InnerText.ToLower </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> value.ToLower </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">Else</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> CreateUniqueName(root,
name) </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> elem </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> CreateResourceFileElement(doc,
name, value) root.AppendChild(elem) </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; "> doc.Save(resourceFilePath) </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> CreateUniqueName(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> root </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">IsNumeric</span>
              <span style="color: #000000; ">(name.Substring(</span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #000000; ">1</span>
              <span style="color: #000000; ">)) </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">n</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">&amp;</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #008000; ">'</span>
              <span style="color: #008000; ">Name
doesn't exist, use it</span>
              <span style="color: #008000; ">
              </span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Not</span>
              <span style="color: #000000; "> CheckNameExists(root,
name) </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> result </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #008000; ">'</span>
              <span style="color: #008000; ">Build
a unique name</span>
              <span style="color: #008000; ">
              </span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">For</span>
              <span style="color: #000000; "> I </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> Int16 </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">1</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">To</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">100</span>
              <span style="color: #000000; "> result </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #000000; ">&amp;</span>
              <span style="color: #000000; "> I </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Not</span>
              <span style="color: #000000; "> CheckNameExists(root,
result) </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> result </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Next</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #000000; ">&amp;</span>
              <span style="color: #000000; "> Guid.NewGuid.ToString </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> CheckNameExists(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> root </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Boolean</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> e </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> root.SelectSingleNode(</span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">.Format(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">data[@name=""{0}""]</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">,
name)) </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Not</span>
              <span style="color: #000000; "> (e </span>
              <span style="color: #0000FF; ">Is</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Nothing</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> CreateResourceFileElement(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> doc </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlDocument, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> name </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> value </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> result </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> doc.CreateElement(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">data</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">)
SetAttribute(result, </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">name</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">,
name) SetAttribute(result, </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">xml:space</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">preserve</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> valueElem </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> doc.CreateElement(</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">value</span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">)
valueElem.InnerText </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> value
result.AppendChild(valueElem) </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> result </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> SetAttribute(</span>
              <span style="color: #0000FF; ">ByRef</span>
              <span style="color: #000000; "> element </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> attr </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">, </span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> value </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlElement </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; "> element.Attributes.GetNamedItem(attr) </span>
              <span style="color: #0000FF; ">Is</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Nothing</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Then</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Dim</span>
              <span style="color: #000000; "> attrib </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; "> XmlAttribute </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> element.OwnerDocument.CreateAttribute(attr)
attrib.Value </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> value
element.Attributes.Append(attrib) </span>
              <span style="color: #0000FF; ">Else</span>
              <span style="color: #000000; "> element.Attributes.Item(attr).Value </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> value </span>
              <span style="color: #0000FF; ">End</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">If</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> element </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Private</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Function</span>
              <span style="color: #000000; "> StripNonAllowedChars(</span>
              <span style="color: #0000FF; ">ByVal</span>
              <span style="color: #000000; "> text </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">String</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Const</span>
              <span style="color: #000000; "> non_allowed </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">""';:,&lt;.&gt;/?\|`~!@#$%^&amp;*()-=+[{]} </span>
              <span style="color: #000000; ">"</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">For</span>
              <span style="color: #000000; "> I </span>
              <span style="color: #0000FF; ">As</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Integer</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">0</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">To</span>
              <span style="color: #000000; "> non_allowed.Length </span>
              <span style="color: #000000; ">-</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #000000; ">1</span>
              <span style="color: #000000; "> text </span>
              <span style="color: #000000; ">=</span>
              <span style="color: #000000; "> text.Replace(non_allowed(I).ToString, </span>
              <span style="color: #000000; ">""</span>
              <span style="color: #000000; ">) </span>
              <span style="color: #0000FF; ">Next</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">Return</span>
              <span style="color: #000000; "> text </span>
              <span style="color: #0000FF; ">End
Function</span>
              <span style="color: #000000; ">
              </span>
              <span style="color: #0000FF; ">End
Module</span>
              <span style="color: #000000; ">
              </span>
            </div>
          </pre>
        </div>
        <p>
 
</p>
        <div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:6c21f677-e872-405e-8840-6e23bfe78fbd" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">del.icio.us
Tags: <a href="http://del.icio.us/popular/VisualStudio" rel="tag">VisualStudio</a>, <a href="http://del.icio.us/popular/.NET" rel="tag">.NET</a>, <a href="http://del.icio.us/popular/Macros" rel="tag">Macros</a>, <a href="http://del.icio.us/popular/ASP.NET" rel="tag">ASP.NET</a></div>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=1e707a99-6d90-4d04-984d-988d378137b3" />
      </body>
      <title>ASP.NET Resource Refactoring</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,1e707a99-6d90-4d04-984d-988d378137b3.aspx</guid>
      <link>http://www.milkcarton.com/blog/2007/08/27/ASPNET+Resource+Refactoring.aspx</link>
      <pubDate>Mon, 27 Aug 2007 04:56:04 GMT</pubDate>
      <description>&lt;p&gt;
I&amp;nbsp;downloaded the very excellent Resource Refactoring Tool (&lt;a title="http://www.codeplex.com/ResourceRefactoring" href="http://www.codeplex.com/ResourceRefactoring"&gt;http://www.codeplex.com/ResourceRefactoring&lt;/a&gt;)
the other day.&amp;nbsp; It works great in code files, but I found that it didn't work
at all for ASPX/HTML pages.&amp;nbsp; Seeing this as a challenge, I decided to hack something
up in VBA to automatically extract the selected text, create a resx name for the text,
add it to the resource file, and insert the ASP.NET literal control.
&lt;/p&gt;
&lt;h3&gt;How to use it
&lt;/h3&gt;
&lt;p&gt;
This is split up into two different macro modules, one named Utilities, and the other
named what ever you want.&amp;nbsp; Then add them to your Visual Studio tool bar so you
have something convenient you can click on (Right click the tool bar, click Customize,
click Commands, then Macros under categories, find what you named the macro and then
drag it up to your tool bar.&amp;nbsp; You can either drag it to an existing tool strip,
or create your own.&amp;nbsp; Finally right click on the item while still in customize
mode and add an image).
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Caller:
&lt;/p&gt;
&lt;p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:1329ba2c-a1eb-4272-be95-d8be9e1e94a7" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:#FFFF80;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; System &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; EnvDTE &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; EnvDTE80 &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.Diagnostics &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Module&lt;/span&gt;&lt;span style="color: #000000; "&gt; MoreMacros &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; AspTextLiteral() &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; resx &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;as&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProjectItem &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; DTE.ActiveWindow.Object.GetItem(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;solution\project\folder\ResourceFile.resx&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
Utilities.AspTextLiteral(resx) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; InQuoteLiteral()
DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate() &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; resx &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;as&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProjectItem &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; DTE.ActiveWindow.Object.GetItem(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;solution\project\folder\ResourceFile.resx&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
Utilities.InQuoteLiteral(resx) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Module&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&gt;
&lt;p&gt;
Utilities: 
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7d5c45be-dc14-4893-a3ac-dcbe121d224d" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:#FFFF80;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; System &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; EnvDTE &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; EnvDTE80 &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.Diagnostics &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Imports&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.Xml &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Module&lt;/span&gt;&lt;span style="color: #000000; "&gt; Utilities &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; AspTextLiteral(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; resourceFile &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProjectItem) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Const&lt;/span&gt;&lt;span style="color: #000000; "&gt; literalFormat &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;asp:Literal
runat=&amp;quot;&amp;quot;server&amp;quot;&amp;quot; Text=&amp;quot;&amp;quot;&amp;lt;%$ Resources:{0},{1}%&amp;gt;&amp;quot;&amp;quot;
/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Const&lt;/span&gt;&lt;span style="color: #000000; "&gt; inQuotesFormat &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;%$
Resources:{0},{1}%&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt; LiteralReplacer(resourceFile,
literalFormat, &lt;/span&gt;&lt;span style="color: #000000; "&gt;4&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; InQuoteLiteral(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; resourceFile &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProjectItem) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Const&lt;/span&gt;&lt;span style="color: #000000; "&gt; inQuotesFormat &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;lt;%$
Resources:{0},{1}%&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt; LiteralReplacer(resourceFile,
inQuotesFormat, &lt;/span&gt;&lt;span style="color: #000000; "&gt;3&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; LiteralReplacer(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; resourceFile &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; ProjectItem, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; template &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; delete &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; Int16) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; ts &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; TextSelection &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; DTE.ActiveDocument.Selection &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; StripNonAllowedChars(ts.Text).Trim.ToLower &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; ts.Text &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; path &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; resourceFile.Properties.Item(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;LocalPath&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;).Value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; resName &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; System.IO.Path.GetFileNameWithoutExtension(resourceFile.Name)
name &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; AddResourceEntry(path,
name, value) ts.Text &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Format(template,
resName, name) DTE.ActiveDocument.Selection.Delete(delete) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Sub&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #008000; "&gt;'&lt;/span&gt;&lt;span style="color: #008000; "&gt;Returns
the value of the name used&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; AddResourceEntry(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; resourceFilePath &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlDocument &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;New&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlDocument
doc.Load(resourceFilePath) &lt;/span&gt;&lt;span style="color: #008000; "&gt;'&lt;/span&gt;&lt;span style="color: #008000; "&gt;See
if it exists first&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; root &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc.DocumentElement &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; e &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; root.SelectSingleNode(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Format(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;data[@name=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;]&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;,
name)) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; e &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Is&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Nothing&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateUniqueName(root,
name) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; elem &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateResourceFileElement(doc,
name, value) root.AppendChild(elem) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Else&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; e.SelectSingleNode(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;value&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;).InnerText.ToLower &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; value.ToLower &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Else&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateUniqueName(root,
name) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; elem &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateResourceFileElement(doc,
name, value) root.AppendChild(elem) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc.Save(resourceFilePath) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateUniqueName(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; root &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;IsNumeric&lt;/span&gt;&lt;span style="color: #000000; "&gt;(name.Substring(&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;)) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;n&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #008000; "&gt;'&lt;/span&gt;&lt;span style="color: #008000; "&gt;Name
doesn't exist, use it&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Not&lt;/span&gt;&lt;span style="color: #000000; "&gt; CheckNameExists(root,
name) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; result &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #008000; "&gt;'&lt;/span&gt;&lt;span style="color: #008000; "&gt;Build
a unique name&lt;/span&gt;&lt;span style="color: #008000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;For&lt;/span&gt;&lt;span style="color: #000000; "&gt; I &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; Int16 &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;To&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;100&lt;/span&gt;&lt;span style="color: #000000; "&gt; result &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000; "&gt; I &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Not&lt;/span&gt;&lt;span style="color: #000000; "&gt; CheckNameExists(root,
result) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; result &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Next&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000; "&gt; Guid.NewGuid.ToString &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; CheckNameExists(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; root &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Boolean&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; e &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; root.SelectSingleNode(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Format(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;data[@name=&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot;]&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;,
name)) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Not&lt;/span&gt;&lt;span style="color: #000000; "&gt; (e &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Is&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Nothing&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; CreateResourceFileElement(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlDocument, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; name &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; result &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc.CreateElement(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;data&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
SetAttribute(result, &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;name&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;,
name) SetAttribute(result, &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;xml:space&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;preserve&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; valueElem &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; doc.CreateElement(&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;value&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
valueElem.InnerText &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; value
result.AppendChild(valueElem) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; result &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; SetAttribute(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByRef&lt;/span&gt;&lt;span style="color: #000000; "&gt; element &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; attr &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlElement &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; element.Attributes.GetNamedItem(attr) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Is&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Nothing&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Then&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Dim&lt;/span&gt;&lt;span style="color: #000000; "&gt; attrib &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; XmlAttribute &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; element.OwnerDocument.CreateAttribute(attr)
attrib.Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; value
element.Attributes.Append(attrib) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Else&lt;/span&gt;&lt;span style="color: #000000; "&gt; element.Attributes.Item(attr).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; value &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;If&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; element &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Private&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; StripNonAllowedChars(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;ByVal&lt;/span&gt;&lt;span style="color: #000000; "&gt; text &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;String&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Const&lt;/span&gt;&lt;span style="color: #000000; "&gt; non_allowed &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&amp;quot;';:,&amp;lt;.&amp;gt;/?\|`~!@#$%^&amp;amp;*()-=+[{]} &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;For&lt;/span&gt;&lt;span style="color: #000000; "&gt; I &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;As&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Integer&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;To&lt;/span&gt;&lt;span style="color: #000000; "&gt; non_allowed.Length &lt;/span&gt;&lt;span style="color: #000000; "&gt;-&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt; text &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; text.Replace(non_allowed(I).ToString, &lt;/span&gt;&lt;span style="color: #000000; "&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Next&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;Return&lt;/span&gt;&lt;span style="color: #000000; "&gt; text &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Function&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;End
Module&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:6c21f677-e872-405e-8840-6e23bfe78fbd" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;del.icio.us
Tags: &lt;a href="http://del.icio.us/popular/VisualStudio" rel="tag"&gt;VisualStudio&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/.NET" rel="tag"&gt;.NET&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/Macros" rel="tag"&gt;Macros&lt;/a&gt;, &lt;a href="http://del.icio.us/popular/ASP.NET" rel="tag"&gt;ASP.NET&lt;/a&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=1e707a99-6d90-4d04-984d-988d378137b3" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,1e707a99-6d90-4d04-984d-988d378137b3.aspx</comments>
      <category>.NET</category>
      <category>ASP.NET</category>
      <category>Macros</category>
      <category>VisualStudio</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=2eb48fa4-804c-4fca-8e50-ec9716611167</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,2eb48fa4-804c-4fca-8e50-ec9716611167.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,2eb48fa4-804c-4fca-8e50-ec9716611167.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=2eb48fa4-804c-4fca-8e50-ec9716611167</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've started work on the search piece of our application.  Searching (no pun
intended) for some inspiration on how users might want to search within our application,
I brought up the current WinForms version, and then the ASP.NET version.
</p>
        <p>
I realized that we need to make searching easier in WinForms client, currently when
searching for a patient in our WinForms client, you are presented with a separate
text box for first name, last name, SSN, date of birth, and health record number. 
Our ASP.NET client presents just one text box to search all of those fields.
</p>
        <h3>Tying the Domain Model to the Data Access Layer
</h3>
        <p>
So I started thinking about all the pieces in our domain model that we might want
to allow the user to search.  Then I realized that to allow searching across
all the fields in an entity would tie the data access layer (DAL) to 
the domain model ala something like this:
</p>
        <a href="http://11011.net/software/vspaste">
        </a>
        <p>
        </p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:78967905-c7a2-4f28-8968-c140689ab9b7" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;">
          <pre style="background-color: rgb(255, 255, 128);">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: rgb(0, 0, 255);">public</span>
              <span style="color: rgb(0, 0, 0);"> IList</span>
              <span style="color: rgb(0, 0, 0);">&lt;</span>
              <span style="color: rgb(0, 0, 0);">Patient</span>
              <span style="color: rgb(0, 0, 0);">&gt;</span>
              <span style="color: rgb(0, 0, 0);"> Search(</span>
              <span style="color: rgb(0, 0, 255);">string</span>
              <span style="color: rgb(0, 0, 0);"> text)
{ ICriteria criteria </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);"> session.CreateCriteria(</span>
              <span style="color: rgb(0, 0, 255);">typeof</span>
              <span style="color: rgb(0, 0, 0);">(Patient));
Disjunction or </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);"> Expression.Disjunction();
text </span>
              <span style="color: rgb(0, 0, 0);">=</span>
              <span style="color: rgb(0, 0, 0);">
              </span>
              <span style="color: rgb(0, 0, 255);">string</span>
              <span style="color: rgb(0, 0, 0);">.Format(</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">%{0}%</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">,
text); or.Add(Expression.Like(</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">FirstName</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">,
text)); or.Add(Expression.Like(</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">MiddleName</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">,
text)); or.Add(Expression.Like(</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">LastName</span>
              <span style="color: rgb(0, 0, 0);">"</span>
              <span style="color: rgb(0, 0, 0);">,
text)); crit.Add(or); </span>
              <span style="color: rgb(0, 0, 255);">return</span>
              <span style="color: rgb(0, 0, 0);"> criteria.List</span>
              <span style="color: rgb(0, 0, 0);">&lt;</span>
              <span style="color: rgb(0, 0, 0);">Patient</span>
              <span style="color: rgb(0, 0, 0);">&gt;</span>
              <span style="color: rgb(0, 0, 0);">();
} </span>
            </div>
          </pre>
        </div>
        <br />
Variations of this code would have to be repeated for every data access class
in our DAL.  You could create a string list of the properties on the entity to
search and pass them to a method that would build your criteria; but at the end of
the day, your still tying your domain model to your data access layer. 
<p></p><h3>Custom Attributes
</h3><p></p><p>
I started doing some thinking about how unit testing frameworks such as <a href="http://www.mbunit.com/" rel="tag">MbUnit</a> work
and realized I could use .NET custom attributes and some reflection to solve the problem.
</p><p>
I came up with an attribute called Search, currently it takes in one boolean parameter
called Enabled.
</p><p></p><div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5bc9a7f1-386c-4823-a314-bb79f545167d" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"><pre style="background-color: rgb(255, 255, 128);"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: rgb(0, 128, 128);"> 1</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System; </span><span style="color: rgb(0, 128, 128);"> 2</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Reflection; </span><span style="color: rgb(0, 128, 128);"> 3</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);"> 4</span><span style="color: rgb(0, 0, 0);">[AttributeUsage(AttributeTargets.Property,
AllowMultiple </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">)] </span><span style="color: rgb(0, 128, 128);"> 5</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> SearchAttribute
: System.Attribute </span><span style="color: rgb(0, 128, 128);"> 6</span><span style="color: rgb(0, 0, 0);">{ </span><span style="color: rgb(0, 128, 128);"> 7</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> Enabled; </span><span style="color: rgb(0, 128, 128);"> 8</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);"> 9</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(128, 128, 128);">&lt;summary&gt;&lt;/summary&gt;</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 128);">10</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(128, 128, 128);">&lt;/summary&gt;</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 128);">11</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(128, 128, 128);">///</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(128, 128, 128);">&lt;param
name="Enabled"&gt;</span><span style="color: rgb(0, 128, 0);">if true, property will
be included in object-level searches</span><span style="color: rgb(128, 128, 128);">&lt;/param&gt;</span><span style="color: rgb(128, 128, 128);"></span><span style="color: rgb(0, 128, 128);">12</span><span style="color: rgb(128, 128, 128);"></span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> SearchAttribute(</span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> Enabled) </span><span style="color: rgb(0, 128, 128);">13</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 128, 128);">14</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">this</span><span style="color: rgb(0, 0, 0);">.Enabled </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Enabled; </span><span style="color: rgb(0, 128, 128);">15</span><span style="color: rgb(0, 0, 0);"> } </span><span style="color: rgb(0, 128, 128);">16</span><span style="color: rgb(0, 0, 0);">}</span></div></pre></div><p></p><p>
I could have written it as:
</p><p></p><div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5d4b8c1f-de81-4b94-b37f-5f65f59228d4" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"><pre style="background-color: rgb(255, 255, 128);"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: rgb(0, 128, 128);">1</span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System; </span><span style="color: rgb(0, 128, 128);">2</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Reflection; </span><span style="color: rgb(0, 128, 128);">3</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);">4</span><span style="color: rgb(0, 0, 0);">[AttributeUsage(AttributeTargets.Property,
AllowMultiple </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">)] </span><span style="color: rgb(0, 128, 128);">5</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> SearchAttribute
: System.Attribute { }</span></div></pre></div><p></p><p>
But I wanted the flexability of adding named parameters in the future.  Who knows,
maybe this is a lame reason, and I should just refactor the code if I want to add
parameters to it in the future.
</p><h3>Adding the Attribute to Your Domain Model
</h3><p>
The interesting thing about a custom attribute, is if it ends in Attribute (i.e.
SearchAttribute), its name gets changed to Search by the C# compiler(?), although
you could still use SearchAttribute as the name when you add it to your properties. 
If you look at the IL, its still called SearchAttribute:
</p><p>
.custom instance void MyNamespace.SearchAttribute::.ctor(bool) = ( bool(true) )
</p><p>
But if you change the attribute name to SearchAttrib, or SearchAttributes, then you
have to use the full name when decorating the properties in your class.  This
really isn't germane to the topic at hand, I just thought it was neat! :)
</p><p>
Example:
</p><div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6d718b68-0d85-408d-851d-6e6460000af1" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"><pre style="background-color: rgb(255, 255, 128);"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: rgb(0, 128, 128);"> 1</span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Patient </span><span style="color: rgb(0, 128, 128);"> 2</span><span style="color: rgb(0, 0, 0);">{ </span><span style="color: rgb(0, 128, 128);"> 3</span><span style="color: rgb(0, 0, 0);"> [Search(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">)] </span><span style="color: rgb(0, 128, 128);"> 4</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> FirstName </span><span style="color: rgb(0, 128, 128);"> 5</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 128, 128);"> 6</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">get</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> _firstName;
} </span><span style="color: rgb(0, 128, 128);"> 7</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">set</span><span style="color: rgb(0, 0, 0);"> {
_firstName </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">value</span><span style="color: rgb(0, 0, 0);">;
} </span><span style="color: rgb(0, 128, 128);"> 8</span><span style="color: rgb(0, 0, 0);"> } </span><span style="color: rgb(0, 128, 128);"> 9</span><span style="color: rgb(0, 0, 0);">... </span><span style="color: rgb(0, 128, 128);">10</span><span style="color: rgb(0, 0, 0);">}</span></div></pre></div><h3>Pulling it All Together
</h3><p>
The custom attribute is great and all, but it doesn't inherently buy us anything. 
We need to add a little bit more <a title="The word technology means magic!" href="http://www.homestarrunner.com/sbemail143.html" target="_blank" rel="tag">magic</a> to
make all this work.  This is a simplified version of what I ended up putting
in my DAL base class:
</p><p></p><div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9dae2aa7-48bc-4817-b207-3316ee795e41" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"><pre style="background-color: rgb(255, 255, 128);"><div><!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><span style="color: rgb(0, 128, 128);"> 1</span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> IList</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">Patient</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"> Search(</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> text) </span><span style="color: rgb(0, 128, 128);"> 2</span><span style="color: rgb(0, 0, 0);">{ </span><span style="color: rgb(0, 128, 128);"> 3</span><span style="color: rgb(0, 0, 0);"> Type
type </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">typeof</span><span style="color: rgb(0, 0, 0);">(Patient); </span><span style="color: rgb(0, 128, 128);"> 4</span><span style="color: rgb(0, 0, 0);"> ICriteria
criteria </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> _session.CreateCriteria(type); </span><span style="color: rgb(0, 128, 128);"> 5</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);"> 6</span><span style="color: rgb(0, 0, 0);"> Disjunction
or </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Expression.Disjunction(); </span><span style="color: rgb(0, 128, 128);"> 7</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">foreach</span><span style="color: rgb(0, 0, 0);"> (PropertyInfo
propInfo </span><span style="color: rgb(0, 0, 255);">in</span><span style="color: rgb(0, 0, 0);"> type.GetProperties()) </span><span style="color: rgb(0, 128, 128);"> 8</span><span style="color: rgb(0, 0, 0);"> { </span><span style="color: rgb(0, 128, 128);"> 9</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">SearchableAttribute
is AllowMultiple = false, so we only need the first item</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 128, 128);">10</span><span style="color: rgb(0, 128, 0);"></span><span style="color: rgb(0, 0, 0);"> Attribute[]
attribs </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Attribute.GetCustomAttributes(propInfo, </span><span style="color: rgb(0, 0, 255);">typeof</span><span style="color: rgb(0, 0, 0);">(SearchAttribute)); </span><span style="color: rgb(0, 128, 128);">11</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (attribs.Length </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">) </span><span style="color: rgb(0, 128, 128);">12</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">continue</span><span style="color: rgb(0, 0, 0);">; </span><span style="color: rgb(0, 128, 128);">13</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 128, 128);">14</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (((SearchAttribute)attribs[</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">]).Enabled) </span><span style="color: rgb(0, 128, 128);">15</span><span style="color: rgb(0, 0, 0);"> or.Add(Expression.InsensitiveLike(propInfo.Name, </span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">.Format(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">%{0}%</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">,
text))); </span><span style="color: rgb(0, 128, 128);">16</span><span style="color: rgb(0, 0, 0);"> } </span><span style="color: rgb(0, 128, 128);">17</span><span style="color: rgb(0, 0, 0);"> criteria.Add(or); </span><span style="color: rgb(0, 128, 128);">18</span><span style="color: rgb(0, 0, 0);"></span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> criteria.List</span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">T</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);">(); </span><span style="color: rgb(0, 128, 128);">19</span><span style="color: rgb(0, 0, 0);">} </span><span style="color: rgb(0, 128, 128);">20</span><span style="color: rgb(0, 0, 0);"></span></div></pre></div><p></p><p>
Again, this is a simplified version of what's in our DAL base class, the actual signature
looks more like this: private IList&lt;T&gt; Search&lt;T&gt;(string text) so that
I don't have to write a version of this for each class in our domain model I want
to enable searching for.
</p><p>
Everything above should be pretty self-explanatory unless you aren't familiar with
the NHibernate Criteria API; in which case the Expression.Disjunction bit on line
6 is how you do an OR (a OR b OR c)when searching.  You can also do Expression.Conjunction
if you want AND searching (a AND b AND c).
</p><p>
The original version of this code had a second foreach loop which spun through all
the attributes on each property looking for the SearchAttribute.  I thought to
myself that their had to be a better way and did a little bit of poking around, and
discovered much to my delight that the static method Attribute.GetCustomAttributes
allows you to specify what kind of attribute you are searching for!
</p><h3>Limitations
</h3><p>
In the code above, you'll get an Exception if you try to search against non-text columns
in your database so you will need to that into account when putting the Search
attribute in your Domain Model; or add some more smarts to the Search method to take
into account different data types.
</p><h3>Comments
</h3><p>
If you've read down this far, then I'd love to get a comment from you.  Is there
anything you think I could do a better job of explaining, am I an awesome guy? 
Or do I suck, either way, I'd like to know, so please leave me a comment!
</p><p>
If you like my article, please kick it at .NET Kicks (I have no idea why the kick
counter says I have zero kicks btw)!
</p><p><a href="http://www.dotnetkicks.com/kick?url=http://www.milkcarton.com/blog/2007/01/23/Using+Custom+Attributes+To+Enable+Quick+Searching+Of+Your+Domain+Entities+With+NHibernate.aspx"><img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.milkcarton.com/blog/2007/01/23/Using+Custom+Attributes+To+Enable+Quick+Searching+Of+Your+Domain+Entities+With+NHibernate.aspx" border="0" /></a></p><img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=2eb48fa4-804c-4fca-8e50-ec9716611167" /></body>
      <title>Using Custom Attributes to Enable Quick Searching of Your Domain Entities With NHibernate</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,2eb48fa4-804c-4fca-8e50-ec9716611167.aspx</guid>
      <link>http://www.milkcarton.com/blog/2007/01/23/Using+Custom+Attributes+To+Enable+Quick+Searching+Of+Your+Domain+Entities+With+NHibernate.aspx</link>
      <pubDate>Tue, 23 Jan 2007 20:02:42 GMT</pubDate>
      <description>&lt;p&gt;
I've started work on the search piece of our application.&amp;nbsp; Searching (no pun
intended) for some inspiration on how users might want to search within our application,
I brought up the current WinForms version, and then&amp;nbsp;the ASP.NET version.
&lt;/p&gt;
&lt;p&gt;
I realized that we need to make searching easier in WinForms client, currently when
searching for a patient in our WinForms client, you are presented with a separate
text box for first name, last name, SSN, date of birth, and health record number.&amp;nbsp;
Our ASP.NET client presents just one text box to search all of those fields.
&lt;/p&gt;
&lt;h3&gt;Tying the Domain Model to the Data Access Layer
&lt;/h3&gt;
&lt;p&gt;
So I started thinking about all the pieces in our domain model that we might want
to allow the user to search.&amp;nbsp; Then I realized that to allow searching across
all the fields in an entity would tie&amp;nbsp;the data access layer (DAL)&amp;nbsp;to&amp;nbsp;
the domain model ala something like this:
&lt;/p&gt;
&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt; 
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:78967905-c7a2-4f28-8968-c140689ab9b7" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Patient&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Search(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; text)
{ ICriteria criteria &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; session.CreateCriteria(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(Patient));
Disjunction or &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Expression.Disjunction();
text &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Format(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;%{0}%&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
text); or.Add(Expression.Like(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;FirstName&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
text)); or.Add(Expression.Like(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;MiddleName&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
text)); or.Add(Expression.Like(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;LastName&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
text)); crit.Add(or); &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; criteria.List&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Patient&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;();
} &lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;br&gt;
Variations of this code would have to be repeated for every&amp;nbsp;data access class
in our DAL.&amp;nbsp; You could create a string list of the properties on the entity to
search and pass them to a method that would build your criteria; but at the end of
the day, your still tying your domain model to your data access layer. 
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Custom Attributes
&lt;/h3&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I started doing some thinking about how unit testing frameworks such as &lt;a href="http://www.mbunit.com/" rel="tag"&gt;MbUnit&lt;/a&gt;&amp;nbsp;work
and realized I could use .NET custom attributes and some reflection to solve the problem.
&lt;/p&gt;
&lt;p&gt;
I came up with an attribute called Search, currently it takes in one boolean parameter
called Enabled.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5bc9a7f1-386c-4823-a314-bb79f545167d" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Reflection; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;[AttributeUsage(AttributeTargets.Property,
AllowMultiple &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)] &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; SearchAttribute
: System.Attribute &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enabled; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;summary&amp;gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;11&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;///&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;param
name="Enabled"&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;if true, property will
be included in object-level searches&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(128, 128, 128);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;12&lt;/span&gt; &lt;span style="color: rgb(128, 128, 128);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; SearchAttribute(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enabled) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;13&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;14&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Enabled &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Enabled; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;15&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; } &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;16&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I could have written it as:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:5d4b8c1f-de81-4b94-b37f-5f65f59228d4" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; System.Reflection; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;[AttributeUsage(AttributeTargets.Property,
AllowMultiple &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)] &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; SearchAttribute
: System.Attribute { }&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
But I wanted the flexability of adding named parameters in the future.&amp;nbsp; Who knows,
maybe this is a lame reason, and I should just refactor the code if I want to add
parameters to it in the future.
&lt;/p&gt;
&lt;h3&gt;Adding&amp;nbsp;the Attribute to Your Domain Model
&lt;/h3&gt;
&lt;p&gt;
The interesting thing about a custom&amp;nbsp;attribute, is if it ends in Attribute (i.e.
SearchAttribute), its name gets changed to Search by the C# compiler(?), although
you could still use SearchAttribute as the name when you add it to your properties.&amp;nbsp;
If you look at the IL, its still called SearchAttribute:
&lt;/p&gt;
&lt;p&gt;
.custom instance void MyNamespace.SearchAttribute::.ctor(bool) = ( bool(true) )
&lt;/p&gt;
&lt;p&gt;
But if you change the attribute name to SearchAttrib, or SearchAttributes, then you
have to use the full name when decorating the properties in your class.&amp;nbsp; This
really isn't germane to the topic at hand, I just thought it was neat! :)
&lt;/p&gt;
&lt;p&gt;
Example:
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:6d718b68-0d85-408d-851d-6e6460000af1" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Patient &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; [Search(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)] &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; FirstName &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;get&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _firstName;
} &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;set&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; {
_firstName &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;
} &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; } &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;... &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;h3&gt;Pulling it All Together
&lt;/h3&gt;
&lt;p&gt;
The custom attribute is great and all, but it doesn't inherently buy us anything.&amp;nbsp;
We need to add a little bit more &lt;a title="The word technology means magic!" href="http://www.homestarrunner.com/sbemail143.html" target="_blank" rel="tag"&gt;magic&lt;/a&gt; to
make all this work.&amp;nbsp; This is a simplified version of what I ended up putting
in my DAL base class:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9dae2aa7-48bc-4817-b207-3316ee795e41" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;pre style="background-color: rgb(255, 255, 128);"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 1&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; IList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Patient&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Search(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; text) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 2&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;{ &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 3&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; Type
type &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(Patient); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 4&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; ICriteria
criteria &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; _session.CreateCriteria(type); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 5&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 6&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; Disjunction
or &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Expression.Disjunction(); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 7&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (PropertyInfo
propInfo &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; type.GetProperties()) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 8&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; { &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt; 9&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;//&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;SearchableAttribute
is AllowMultiple = false, so we only need the first item&lt;/span&gt;&lt;span style="color: rgb(0, 128, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;10&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Attribute[]
attribs &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; Attribute.GetCustomAttributes(propInfo, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(SearchAttribute)); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;11&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (attribs.Length &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;==&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;12&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;continue&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;13&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;14&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; (((SearchAttribute)attribs[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;]).Enabled) &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;15&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; or.Add(Expression.InsensitiveLike(propInfo.Name, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.Format(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;%{0}%&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;,
text))); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;16&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; } &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;17&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; criteria.Add(or); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;18&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt; criteria.List&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;T&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(); &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;19&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;} &lt;/span&gt;&lt;span style="color: rgb(0, 128, 128);"&gt;20&lt;/span&gt; &lt;span style="color: rgb(0, 0, 0);"&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Again, this is a simplified version of what's in our DAL base class, the actual signature
looks more like this: private IList&amp;lt;T&amp;gt; Search&amp;lt;T&amp;gt;(string text) so that
I don't have to write a version of this for each class in our domain model I want
to enable searching for.
&lt;/p&gt;
&lt;p&gt;
Everything above should be pretty self-explanatory unless you aren't familiar with
the NHibernate Criteria API; in which case the Expression.Disjunction bit on line
6 is how you do an OR (a OR b OR c)when searching.&amp;nbsp; You can also do Expression.Conjunction
if you want&amp;nbsp;AND searching (a AND b AND c).
&lt;/p&gt;
&lt;p&gt;
The original version of this code had a second foreach loop which spun through all
the attributes on each property looking for the SearchAttribute.&amp;nbsp; I thought to
myself that their had to be a better way and did a little bit of poking around, and
discovered much to my delight that the static method Attribute.GetCustomAttributes
allows you to specify what kind of attribute you are searching for!
&lt;/p&gt;
&lt;h3&gt;Limitations
&lt;/h3&gt;
&lt;p&gt;
In the code above, you'll get an Exception if you try to search against non-text columns
in your database&amp;nbsp;so you will need to that into account when putting the Search
attribute in your Domain Model; or add some more smarts to the Search method to take
into account different data types.
&lt;/p&gt;
&lt;h3&gt;Comments
&lt;/h3&gt;
&lt;p&gt;
If you've read down this far, then I'd love to get a comment from you.&amp;nbsp; Is there
anything you think I could do a better job of explaining, am I an awesome guy?&amp;nbsp;
Or do I suck, either way, I'd like to know, so please leave me a comment!
&lt;/p&gt;
&lt;p&gt;
If you like my article, please kick it at .NET Kicks (I have no idea why the kick
counter says I have zero kicks btw)!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.dotnetkicks.com/kick?url=http://www.milkcarton.com/blog/2007/01/23/Using+Custom+Attributes+To+Enable+Quick+Searching+Of+Your+Domain+Entities+With+NHibernate.aspx"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http://www.milkcarton.com/blog/2007/01/23/Using+Custom+Attributes+To+Enable+Quick+Searching+Of+Your+Domain+Entities+With+NHibernate.aspx" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=2eb48fa4-804c-4fca-8e50-ec9716611167" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,2eb48fa4-804c-4fca-8e50-ec9716611167.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>NHibernate</category>
      <category>ORM</category>
      <category>Searching</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=faa5611c-38bb-4b97-b461-4b730286ec99</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,faa5611c-38bb-4b97-b461-4b730286ec99.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,faa5611c-38bb-4b97-b461-4b730286ec99.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=faa5611c-38bb-4b97-b461-4b730286ec99</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We are in the midst of doing a total rewrite of our Software, and one of the things
that has come up is date and time.  How do we do it, how do we store it, and
how do we ensure that we can compare DateTime from one timezone to DateTime in another
timezone.  After a lot of research, we settled on using UTC (or UCT depending
on your preference).  FxCop will take care of ensuring we use UTC (for the most
part).
</p>
        <p>
That solves the problem, or so we thought.  Turns out, when you create a DateTime
object either through the constructor, or through DateTime.Parse, its Kind defaults
to DateTimeKind.Unspecified.  We need a way to ensure that all DateTime objects
are always set to UTC.
</p>
        <h2>What are our options?
</h2>
        <p>
Because we are using NHibernate, we have a few options.  The three NHibernate
specific ones that immediately come to mind are using an Interceptor, a custom UserType
with a SQL datetime column, and a custom UserType with a SQL varchar column; and the
non-NHibernate specific one is creating our own DateTime container.  What are
the pros and cons of each of these?
</p>
        <h3>NHibernate Interceptor
</h3>
        <p>
Pro: very cross-cutting, can touch every object as it comes in and goes out to the
database; if there are other data types we need to monkey with, we already have
a framework in place.
</p>
        <p>
Con: Very cross-cutting, can be expensive because it's touching every property
on every entity as the entities are loaded and persisted
</p>
        <h3>UserType with SQL datetime column
</h3>
        <p>
Pro: Only touching the DateTime objects that we want it to
</p>
        <p>
Con: The type has to be specified for <strong>every</strong> DateTime object in every
mapping file; no meta-data along with the date to stamp in the timezone it was created
in
</p>
        <h3>UserType with SQL varchar column
</h3>
        <p>
Pro: Only touching the DateTime objects that we want it to; can store the timezone
and offset along with the date in the db
</p>
        <p>
Con: Same as above UserType; abusing SQL data types; datetimes created at the same
(relative) time in two different timezones won't be sorted correctly
</p>
        <h3>Custom DateTime container
</h3>
        <p>
Pro: We can do anything we want
</p>
        <p>
Con: Yuck! - I could write a whole paragraph on why this is yucky, but I'll leave
that to your imagination
</p>
        <p>
 
</p>
        <h4>
        </h4>
        <p>
After some thought, I decided on the Interceptor!  Here is the class I came up
with (you can also <a href="http://www.milkcarton.com/blog/content/binary/UtcDateTimeInterceptor.cs.txt">download
the complete UtcDateTimeInterceptor class</a>):
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9f99d007-4145-4f43-81ec-aa3402facafe" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <pre style="background-color:#FFFFDD;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: #008080;"> 1</span>
              <span style="color: #0000FF;">class</span>
              <span style="color: #000000;"> UtcDateTimeInterceptor
: IInterceptor </span>
              <span style="color: #008080;"> 2</span>
              <span style="color: #000000;">{ </span>
              <span style="color: #008080;"> 3</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">public</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">bool</span>
              <span style="color: #000000;"> OnLoad(</span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> entity, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> id, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
state, </span>
              <span style="color: #0000FF;">string</span>
              <span style="color: #000000;">[]
propertyNames, IType[] types) </span>
              <span style="color: #008080;"> 4</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;"> 5</span>
              <span style="color: #000000;"> ConvertDatabaseDateTimeToUtc(state,
types); </span>
              <span style="color: #008080;"> 6</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">return</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">true</span>
              <span style="color: #000000;">; </span>
              <span style="color: #008080;"> 7</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;"> 8</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;"> 9</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">public</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">bool</span>
              <span style="color: #000000;"> OnSave(</span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> entity, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> id, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
state, </span>
              <span style="color: #0000FF;">string</span>
              <span style="color: #000000;">[]
propertyNames, IType[] types) </span>
              <span style="color: #008080;">10</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">11</span>
              <span style="color: #000000;"> ConvertLocalDateToUtc(state,
types); </span>
              <span style="color: #008080;">12</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">return</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">true</span>
              <span style="color: #000000;">; </span>
              <span style="color: #008080;">13</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">14</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;">15</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">public</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">bool</span>
              <span style="color: #000000;"> OnFlushDirty(</span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> entity, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;"> id, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
currentState, </span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
previousState, </span>
              <span style="color: #0000FF;">string</span>
              <span style="color: #000000;">[]
propertyNames, </span>
              <span style="color: #008080;">16</span>
              <span style="color: #000000;"> IType[]
types) </span>
              <span style="color: #008080;">17</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">18</span>
              <span style="color: #000000;"> ConvertLocalDateToUtc(currentState,
types); </span>
              <span style="color: #008080;">19</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">return</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">true</span>
              <span style="color: #000000;">; </span>
              <span style="color: #008080;">20</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">21</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;">22</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">private</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">void</span>
              <span style="color: #000000;"> ConvertLocalDateToUtc(</span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
state, IType[] types) </span>
              <span style="color: #008080;">23</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">24</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">int</span>
              <span style="color: #000000;"> index </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #800080;">0</span>
              <span style="color: #000000;">; </span>
              <span style="color: #008080;">25</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">foreach</span>
              <span style="color: #000000;"> (IType
type </span>
              <span style="color: #0000FF;">in</span>
              <span style="color: #000000;"> types) </span>
              <span style="color: #008080;">26</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">27</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">if</span>
              <span style="color: #000000;"> ((type.ReturnedClass </span>
              <span style="color: #000000;">==</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">typeof</span>
              <span style="color: #000000;">(DateTime)) </span>
              <span style="color: #000000;">&amp;&amp;</span>
              <span style="color: #000000;"> state[index] </span>
              <span style="color: #000000;">!=</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">null</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #000000;">&amp;&amp;</span>
              <span style="color: #000000;"> (((DateTime)state[index]).Kind </span>
              <span style="color: #000000;">==</span>
              <span style="color: #000000;"> DateTimeKind.Utc)) </span>
              <span style="color: #008080;">28</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">29</span>
              <span style="color: #000000;"> state[index] </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;"> ((DateTime)state[index]).ToUniversalTime(); </span>
              <span style="color: #008080;">30</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">31</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;">32</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #000000;">++</span>
              <span style="color: #000000;">index; </span>
              <span style="color: #008080;">33</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">34</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">35</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;">36</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">private</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">void</span>
              <span style="color: #000000;"> ConvertDatabaseDateTimeToUtc(</span>
              <span style="color: #0000FF;">object</span>
              <span style="color: #000000;">[]
state, IType[] types) </span>
              <span style="color: #008080;">37</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">38</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">int</span>
              <span style="color: #000000;"> index </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #800080;">0</span>
              <span style="color: #000000;">; </span>
              <span style="color: #008080;">39</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">foreach</span>
              <span style="color: #000000;"> (IType
type </span>
              <span style="color: #0000FF;">in</span>
              <span style="color: #000000;"> types) </span>
              <span style="color: #008080;">40</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">41</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">if</span>
              <span style="color: #000000;"> ((type.ReturnedClass </span>
              <span style="color: #000000;">==</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">typeof</span>
              <span style="color: #000000;">(DateTime)) </span>
              <span style="color: #000000;">&amp;&amp;</span>
              <span style="color: #000000;"> state[index] </span>
              <span style="color: #000000;">!=</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #0000FF;">null</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #000000;">&amp;&amp;</span>
              <span style="color: #000000;"> (((DateTime)state[index]).Kind </span>
              <span style="color: #000000;">==</span>
              <span style="color: #000000;"> DateTimeKind.Unspecified)) </span>
              <span style="color: #008080;">42</span>
              <span style="color: #000000;"> { </span>
              <span style="color: #008080;">43</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008000;">//</span>
              <span style="color: #008000;">Create
a new date and assume the value stored in the database is Utc</span>
              <span style="color: #008000;">
              </span>
              <span style="color: #008080;">44</span>
              <span style="color: #008000;">
              </span>
              <span style="color: #000000;"> DateTime
cur </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;"> (DateTime)state[index]; </span>
              <span style="color: #008080;">45</span>
              <span style="color: #000000;"> DateTime
result </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;"> DateTime.SpecifyKind(cur,
DateTimeKind.Local); </span>
              <span style="color: #008080;">46</span>
              <span style="color: #000000;"> state[index] </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;"> result; </span>
              <span style="color: #008080;">47</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">48</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #008080;">49</span>
              <span style="color: #000000;">
              </span>
              <span style="color: #000000;">++</span>
              <span style="color: #000000;">index; </span>
              <span style="color: #008080;">50</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">51</span>
              <span style="color: #000000;"> } </span>
              <span style="color: #008080;">52</span>
              <span style="color: #000000;">}</span>
            </div>
          </pre>
          <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
        </div>
        <p>
        </p>
        <h3>Loading The Entities
</h3>
        <p>
For the sake of brevity, I'm going to exclude the bits of the Interceptor interface
that aren't relevant to my posting.  With that said, the OnLoad event (line 3)
gets fired every time an entity is loaded from the database.  We can count on
the fact that all dates are stored as UTC in the database because of stuff we'll do
later, so we need to convert the DateTime that NHibernate generates (which has a DateTimeKind
of Unspecified) to a UTC date (line 36 - 48).  The types array holds the
CLR data type of each property in the entity, and each type in the array contains
both the internal NHibernate type, and the CLR type. But we don't really care about
how NHibernate maps the data types internally, so we are only interested in type.ReturnedClass.
</p>
        <p>
The first thing we need to do is see if the ReturnedClass is of type DateTime (line
41), if its a DateTime, then we need to see if its null, and finally double check
that the Kind on the DateTime object coming back from the database is Unspecified. 
This last check is a sanity check, in case this behavior changes in the future.
</p>
        <p>
After all these checks are passed, we need to create a new DateTime object from the
old one, and set its Kind to Utc (lines 44 and 45).  Thankfully, DateTime has
the built-in method SpecifyKind which will take care of building a DateTime of the
specified kind for us. And finally replace the existing DateTime object with our new
one (line 46).  Shampoo, rinse, repeat for all the DateTime values in the entity.
</p>
        <h3>Persisting The Entities
</h3>
        <p>
Now we can move on to the save and update NHibernate events (line 9, and 15 respectively). 
In these, we want to make sure the values being persisted to the datastore are UTC,
and that no Local times have slipped through the cracks.  If one were so inclined,
they could throw an error instead of converting the DateTime to UTC...
</p>
        <p>
The basic code for converting Local DateTime's to Utc (line 22- 34) is much the same
as above, but with a few exceptions.  When we do all our checks (line 27), this
time we make sure the DateTimeKind is Local before we perform a conversion operation
on it.  It is pointless to check if the Kind is Unspecified, because there is
no conversion operation we can really perform on it.  On line 29, we can use
the built in DateTime method ToUniversalTime() to convert a LocalTime to UTC.
</p>
        <h3>Finishing Up
</h3>
        <p>
How do we wire this all up?  When you open a session on your session factory,
you can pass in an Interceptor, this is where you would pass in the UtcDateTimeInterceptor. 
eg:
</p>
        <p>
        </p>
        <div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c90243f1-a329-41f3-9467-b846d16c84de" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">
          <pre style="background-color:#FFFFE1;;overflow: auto;">
            <div>
              <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
              <span style="color: #000000;">ISession
openSession </span>
              <span style="color: #000000;">=</span>
              <span style="color: #000000;"> ourSessionFactory.OpenSession(</span>
              <span style="color: #0000FF;">new</span>
              <span style="color: #000000;"> UtcDateTimeInterceptor());</span>
            </div>
          </pre>
          <!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com -->
        </div>
        <p>
        </p>
        <p>
I want to give credit where credit is due, I got the actual idea of using an Interceptor
from <a href="http://www.ayende.com/Blog/2006/08/31/HandlingNullableDatetimeInNHibernateTheInterceptor.aspx" rel="tag">a
blog post by Ayende</a> where he grappled with DateTime, null, messages and web services. 
If anyone using NHibernate doesn't read <a href="http://www.ayende.com/Blog/" rel="tag">Ayende
Rahiens' blog</a>, I would highly encourage you to.  He is a very, very sharp
fellow; and prolific blogger.
</p>
        <img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=faa5611c-38bb-4b97-b461-4b730286ec99" />
      </body>
      <title>NHibernate, DateTime and UTC</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,faa5611c-38bb-4b97-b461-4b730286ec99.aspx</guid>
      <link>http://www.milkcarton.com/blog/2007/01/19/NHibernate+DateTime+And+UTC.aspx</link>
      <pubDate>Fri, 19 Jan 2007 00:36:52 GMT</pubDate>
      <description>&lt;p&gt;
We are in the midst of doing a total rewrite of our Software, and one of the things
that has come up is date and time.&amp;nbsp; How do we do it, how do we store it, and
how do we ensure that we can compare DateTime from one timezone to DateTime in another
timezone.&amp;nbsp; After a lot of research, we settled on using UTC (or UCT depending
on your preference).&amp;nbsp; FxCop will take care of ensuring we use UTC (for the most
part).
&lt;/p&gt;
&lt;p&gt;
That solves the problem, or so we thought.&amp;nbsp; Turns out, when you create a DateTime
object either through the constructor, or through DateTime.Parse, its Kind&amp;nbsp;defaults
to DateTimeKind.Unspecified.&amp;nbsp; We need a way to ensure that all DateTime objects
are always set to UTC.
&lt;/p&gt;
&lt;h2&gt;What are our options?
&lt;/h2&gt;
&lt;p&gt;
Because we are using NHibernate, we have a few options.&amp;nbsp; The&amp;nbsp;three NHibernate
specific ones that immediately come to mind are using an Interceptor, a custom UserType
with a SQL datetime column, and a custom UserType with a SQL varchar column; and the
non-NHibernate specific one is creating our own DateTime container.&amp;nbsp; What are
the pros and cons of each of these?
&lt;/p&gt;
&lt;h3&gt;NHibernate Interceptor
&lt;/h3&gt;
&lt;p&gt;
Pro: very cross-cutting, can touch every object as it comes in and goes out to the
database; if there are other data types we need to monkey with, we already&amp;nbsp;have
a framework in place.
&lt;/p&gt;
&lt;p&gt;
Con: Very cross-cutting, can be expensive because it's touching every&amp;nbsp;property
on every entity as the entities are loaded and persisted
&lt;/p&gt;
&lt;h3&gt;UserType with SQL datetime column
&lt;/h3&gt;
&lt;p&gt;
Pro: Only touching the DateTime objects that we want it to
&lt;/p&gt;
&lt;p&gt;
Con: The type has to be specified for &lt;strong&gt;every&lt;/strong&gt; DateTime object in&amp;nbsp;every
mapping file; no meta-data along with the date to stamp in the timezone it was created
in
&lt;/p&gt;
&lt;h3&gt;UserType with SQL varchar column
&lt;/h3&gt;
&lt;p&gt;
Pro: Only touching the DateTime objects that we want it to; can store the timezone
and offset along with the date in the db
&lt;/p&gt;
&lt;p&gt;
Con: Same as above UserType; abusing SQL data types; datetimes created at the same
(relative) time in two different timezones won't be sorted correctly
&lt;/p&gt;
&lt;h3&gt;Custom DateTime container
&lt;/h3&gt;
&lt;p&gt;
Pro: We can do anything we want
&lt;/p&gt;
&lt;p&gt;
Con: Yuck! - I could write a whole paragraph on why this is yucky, but I'll leave
that to your imagination
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;h4&gt;
&lt;/h4&gt;
&lt;p&gt;
After some thought, I decided on the Interceptor!&amp;nbsp; Here is the class I came up
with (you can also &lt;a href="http://www.milkcarton.com/blog/content/binary/UtcDateTimeInterceptor.cs.txt"&gt;download
the complete UtcDateTimeInterceptor class&lt;/a&gt;):
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:9f99d007-4145-4f43-81ec-aa3402facafe" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:#FFFFDD;white-space:-moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; word-wrap: break-word;;overflow: auto;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; UtcDateTimeInterceptor
: IInterceptor &lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;{ &lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnLoad(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; entity, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; id, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
state, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
propertyNames, IType[] types) &lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt; ConvertDatabaseDateTimeToUtc(state,
types); &lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnSave(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; entity, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; id, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
state, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
propertyNames, IType[] types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt; ConvertLocalDateToUtc(state,
types); &lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;bool&lt;/span&gt;&lt;span style="color: #000000;"&gt; OnFlushDirty(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; entity, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; id, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
currentState, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
previousState, &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
propertyNames, &lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt; IType[]
types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt; ConvertLocalDateToUtc(currentState,
types); &lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ConvertLocalDateToUtc(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
state, IType[] types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; index &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IType
type &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((type.ReturnedClass &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(DateTime)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; state[index] &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (((DateTime)state[index]).Kind &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTimeKind.Utc)) &lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #000000;"&gt; state[index] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((DateTime)state[index]).ToUniversalTime(); &lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;index; &lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;void&lt;/span&gt;&lt;span style="color: #000000;"&gt; ConvertDatabaseDateTimeToUtc(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt;[]
state, IType[] types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;int&lt;/span&gt;&lt;span style="color: #000000;"&gt; index &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (IType
type &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;in&lt;/span&gt;&lt;span style="color: #000000;"&gt; types) &lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; ((type.ReturnedClass &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;typeof&lt;/span&gt;&lt;span style="color: #000000;"&gt;(DateTime)) &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; state[index] &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="color: #000000;"&gt; (((DateTime)state[index]).Kind &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTimeKind.Unspecified)) &lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #000000;"&gt; { &lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Create
a new date and assume the value stored in the database is Utc&lt;/span&gt;&lt;span style="color: #008000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime
cur &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (DateTime)state[index]; &lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;span style="color: #000000;"&gt; DateTime
result &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; DateTime.SpecifyKind(cur,
DateTimeKind.Local); &lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;span style="color: #000000;"&gt; state[index] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; result; &lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;++&lt;/span&gt;&lt;span style="color: #000000;"&gt;index; &lt;/span&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;span style="color: #000000;"&gt; } &lt;/span&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;h3&gt;Loading The Entities
&lt;/h3&gt;
&lt;p&gt;
For the sake of brevity, I'm going to exclude the bits of the&amp;nbsp;Interceptor interface
that aren't relevant to my posting.&amp;nbsp; With that said, the OnLoad event (line 3)
gets fired every time an entity is loaded from the database.&amp;nbsp; We can count on
the fact that all dates are stored as UTC in the database because of stuff we'll do
later, so we need to convert the DateTime that NHibernate generates (which has a DateTimeKind
of Unspecified) to a UTC date (line&amp;nbsp;36 - 48).&amp;nbsp; The types array holds the
CLR data type&amp;nbsp;of each property in the entity, and each type in the array contains
both the internal NHibernate type, and the CLR type. But we don't really care about
how NHibernate maps the data types internally, so we are only interested in type.ReturnedClass.
&lt;/p&gt;
&lt;p&gt;
The first thing we need to do is see if the ReturnedClass is of type DateTime (line
41), if its a DateTime, then we need to see if its null, and finally double check
that the Kind on the DateTime object coming back from the database is Unspecified.&amp;nbsp;
This last check is a sanity check, in case this behavior changes in the future.
&lt;/p&gt;
&lt;p&gt;
After all these checks are passed, we need to create a new DateTime object from the
old one, and set its Kind to Utc (lines 44 and 45).&amp;nbsp; Thankfully, DateTime has
the built-in method SpecifyKind which will take care of building a DateTime of the
specified kind for us. And finally replace the existing DateTime object with our new
one (line 46).&amp;nbsp; Shampoo, rinse, repeat for all the DateTime values in the entity.
&lt;/p&gt;
&lt;h3&gt;Persisting The Entities
&lt;/h3&gt;
&lt;p&gt;
Now we can move on to the save and update NHibernate events (line 9, and 15 respectively).&amp;nbsp;
In these, we want to make sure the values being persisted to the datastore are UTC,
and that no Local times have slipped through the cracks.&amp;nbsp; If one were so inclined,
they could throw an error instead of converting the DateTime to UTC...
&lt;/p&gt;
&lt;p&gt;
The basic code for converting Local DateTime's to Utc (line 22- 34) is much the same
as above, but with a few exceptions.&amp;nbsp; When we do all our checks (line 27), this
time we make sure the DateTimeKind is Local before we perform a conversion operation
on it.&amp;nbsp; It is pointless to check if the Kind is Unspecified, because there is
no conversion operation we can really perform on it.&amp;nbsp; On line 29, we can use
the built in DateTime method ToUniversalTime() to convert a LocalTime to UTC.
&lt;/p&gt;
&lt;h3&gt;Finishing Up
&lt;/h3&gt;
&lt;p&gt;
How do we wire this all up?&amp;nbsp; When you open a session on your session factory,
you can pass in an Interceptor, this is where you would pass in the UtcDateTimeInterceptor.&amp;nbsp;
eg:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:c90243f1-a329-41f3-9467-b846d16c84de" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:#FFFFE1;;overflow: auto;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #000000;"&gt;ISession
openSession &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; ourSessionFactory.OpenSession(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; UtcDateTimeInterceptor());&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
I want to give credit where credit is due, I got the actual idea of using an Interceptor
from&amp;nbsp;&lt;a href="http://www.ayende.com/Blog/2006/08/31/HandlingNullableDatetimeInNHibernateTheInterceptor.aspx" rel="tag"&gt;a
blog post by Ayende&lt;/a&gt; where he grappled with DateTime, null, messages and web services.&amp;nbsp;
If anyone using NHibernate&amp;nbsp;doesn't read &lt;a href="http://www.ayende.com/Blog/" rel="tag"&gt;Ayende
Rahiens' blog&lt;/a&gt;, I would highly encourage you to.&amp;nbsp; He is a very, very sharp
fellow; and prolific blogger.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=faa5611c-38bb-4b97-b461-4b730286ec99" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,faa5611c-38bb-4b97-b461-4b730286ec99.aspx</comments>
      <category>.NET</category>
      <category>C#</category>
      <category>NHibernate</category>
      <category>ORM</category>
    </item>
    <item>
      <trackback:ping>http://www.milkcarton.com/blog/Trackback.aspx?guid=a1540b66-7859-4d60-ab5d-1ff9351408f2</trackback:ping>
      <pingback:server>http://www.milkcarton.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.milkcarton.com/blog/PermaLink,guid,a1540b66-7859-4d60-ab5d-1ff9351408f2.aspx</pingback:target>
      <dc:creator>Dan Morphis</dc:creator>
      <wfw:comment>http://www.milkcarton.com/blog/CommentView,guid,a1540b66-7859-4d60-ab5d-1ff9351408f2.aspx</wfw:comment>
      <wfw:commentRss>http://www.milkcarton.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a1540b66-7859-4d60-ab5d-1ff9351408f2</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>CompositeUserTypes in NHibernate</title>
      <guid isPermaLink="false">http://www.milkcarton.com/blog/PermaLink,guid,a1540b66-7859-4d60-ab5d-1ff9351408f2.aspx</guid>
      <link>http://www.milkcarton.com/blog/2006/12/31/CompositeUserTypes+In+NHibernate.aspx</link>
      <pubDate>Sun, 31 Dec 2006 08:58:24 GMT</pubDate>
      <description>&lt;p class="MsoNormal"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;Often times when
you're developing an application, there is a one-to-one mapping between your domain
model (object model) and your database schema.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Doing it this way
often times makes it easier to wrap your head around everything going on in your app.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;But this isn’t
always the right way to do things.&lt;span&gt;&amp;nbsp; &lt;/span&gt;For example, take the highlighted
columns in the UserCredential table:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;img src="http://www.milkcarton.com/blog/content/binary/123106_0746_CompositeUs1.png"&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;In the UserCredential
class, do you really want to have HashedPassword, HashType, and PasswordSalt properties?&lt;span&gt;&amp;nbsp; &lt;/span&gt;Probably
not...&lt;span&gt;&amp;nbsp; &lt;/span&gt;So, how can we still do our mapping with NHibernate and
avoid creating a clunky UserCredential class?&lt;span&gt;&amp;nbsp; &lt;/span&gt;Enter NHibernates
CompositeUserTypes!&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;First, let’s create
our domain objects:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;img src="http://www.milkcarton.com/blog/content/binary/123106_0746_CompositeUs2.png"&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;Notice that the
UserCredential class contains a property called Password, which maps to the class
Password.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;Now, let’s create
our CompositeUserType, in our case, we’ll call it PasswordCompositeUserType, and this
class will implement the NHibernate.IUserType interface:&lt;/span&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:7b8f081d-b8cc-4e06-b076-3a68f1ceaeaa" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;class&lt;/span&gt;&lt;span style="color: #000000; "&gt; PasswordCompositeUserType
: IUserType { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; Equals(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; x, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; y)
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (x &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; y) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;true&lt;/span&gt;&lt;span style="color: #000000; "&gt;; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (x &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;||&lt;/span&gt;&lt;span style="color: #000000; "&gt; y &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;false&lt;/span&gt;&lt;span style="color: #000000; "&gt;; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.Equals(y);
} &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; DeepCopy(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; value)
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (value &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;else&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; ((Password)value).Copy();
} &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; GetHashCode(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; x)
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; x.GetHashCode();
} &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;bool&lt;/span&gt;&lt;span style="color: #000000; "&gt; IsMutable
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;false&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
} } &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; NullSafeGet(System.Data.IDataReader
rs, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt;[]
names, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; owner)
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (rs.IsDBNull(rs.GetOrdinal(names[&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;])) &lt;/span&gt;&lt;span style="color: #000000; "&gt;||&lt;/span&gt;&lt;span style="color: #000000; "&gt; rs.GetOrdinal(names[&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;]) &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt;.Empty) &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt; hashedPassword &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt;)rs[names[&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;]]; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;long&lt;/span&gt;&lt;span style="color: #000000; "&gt; salt &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;long&lt;/span&gt;&lt;span style="color: #000000; "&gt;)rs[names[&lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;]];
HashType hashType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (HashType)Enum.Parse(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(HashType),
(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;string&lt;/span&gt;&lt;span style="color: #000000; "&gt;)rs[names[&lt;/span&gt;&lt;span style="color: #000000; "&gt;2&lt;/span&gt;&lt;span style="color: #000000; "&gt;]]);
Password result &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; Password();
result.HashedPassword &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; hashedPassword;
result.Salt &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; salt;
result.HashType &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (HashType)Enum.Parse(&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(HashType),
hashType); &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; result;
} &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;void&lt;/span&gt;&lt;span style="color: #000000; "&gt; NullSafeSet(System.Data.IDbCommand
cmd, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;object&lt;/span&gt;&lt;span style="color: #000000; "&gt; value, &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;int&lt;/span&gt;&lt;span style="color: #000000; "&gt; index)
{ &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;if&lt;/span&gt;&lt;span style="color: #000000; "&gt; (value &lt;/span&gt;&lt;span style="color: #000000; "&gt;==&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;)
{ ((IDataParameter)cmd.Parameters[index]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
((IDataParameter)cmd.Parameters[index &lt;/span&gt;&lt;span style="color: #000000; "&gt;+&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
((IDataParameter)cmd.Parameters[index &lt;/span&gt;&lt;span style="color: #000000; "&gt;+&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;2&lt;/span&gt;&lt;span style="color: #000000; "&gt;]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;null&lt;/span&gt;&lt;span style="color: #000000; "&gt;;
} &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;else&lt;/span&gt;&lt;span style="color: #000000; "&gt; {
Password pass &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; (Password)value;
((IDataParameter)cmd.Parameters[index]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; pass.HashedPassword;
((IDataParameter)cmd.Parameters[index &lt;/span&gt;&lt;span style="color: #000000; "&gt;+&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; pass.Salt;
((IDataParameter)cmd.Parameters[index &lt;/span&gt;&lt;span style="color: #000000; "&gt;+&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #000000; "&gt;2&lt;/span&gt;&lt;span style="color: #000000; "&gt;]).Value &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; pass.HashType;
} } &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; Type
ReturnedType { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;typeof&lt;/span&gt;&lt;span style="color: #000000; "&gt;(Password);
} } &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;public&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType[]
SqlTypes { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;get&lt;/span&gt;&lt;span style="color: #000000; "&gt; { &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType[]
types &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType[&lt;/span&gt;&lt;span style="color: #000000; "&gt;3&lt;/span&gt;&lt;span style="color: #000000; "&gt;];
types[&lt;/span&gt;&lt;span style="color: #000000; "&gt;0&lt;/span&gt;&lt;span style="color: #000000; "&gt;] &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType(DbType.String);
types[&lt;/span&gt;&lt;span style="color: #000000; "&gt;1&lt;/span&gt;&lt;span style="color: #000000; "&gt;] &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType(DbType.Int64);
types[&lt;/span&gt;&lt;span style="color: #000000; "&gt;2&lt;/span&gt;&lt;span style="color: #000000; "&gt;] &lt;/span&gt;&lt;span style="color: #000000; "&gt;=&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;new&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;global&lt;/span&gt;&lt;span style="color: #000000; "&gt;::NHibernate.SqlTypes.SqlType(DbType.String); &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;return&lt;/span&gt;&lt;span style="color: #000000; "&gt; types;
} } }&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;&lt;font face="ver"&gt;Looks
complicated, but it’s not.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Let’s break it down method by method.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; &lt;span style="color: black"&gt;Equals&lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;x&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;y&lt;/span&gt;)
– &lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;Returns whether object
x and y are equal.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Why does it matter?&lt;span&gt;&amp;nbsp; &lt;/span&gt;In our
case, it really doesn’t (that I’m aware of); but NHibernate uses this to figure out
the relationship between objects in your domain model.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;DeepCopy&lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;value&lt;/span&gt;)
– &lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;Creates a deep copy, I’m
not sure why NHibernate needs this.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Note, in my implimentation
of Password, I created a Copy method.&lt;span&gt;&amp;nbsp; &lt;/span&gt;You could also create a new
Password object, set the properties of that new object, and return that as well.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Something
like this:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: teal; font-family: monaco"&gt;Password&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: black"&gt;p&lt;/span&gt; =
(&lt;span style="color: teal"&gt;Password&lt;/span&gt;)&lt;span style="color: black"&gt;value&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: teal; font-family: monaco"&gt;Password&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: black"&gt;result&lt;/span&gt; = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;Password&lt;/span&gt;();&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: black; font-family: monaco"&gt;result&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt;.&lt;span style="color: black"&gt;HashedPassword&lt;/span&gt; = &lt;span style="color: black"&gt;p&lt;/span&gt;.&lt;span style="color: black"&gt;HashedPassword&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: black; font-family: monaco"&gt;result&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt;.&lt;span style="color: black"&gt;HashType&lt;/span&gt; = &lt;span style="color: black"&gt;p&lt;/span&gt;.&lt;span style="color: black"&gt;HashType&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: black; font-family: monaco"&gt;result&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt;.&lt;span style="color: black"&gt;Salt&lt;/span&gt; = &lt;span style="color: black"&gt;p&lt;/span&gt;.&lt;span style="color: black"&gt;Salt&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal" style="margin-bottom: 0pt"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;return&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: black"&gt;result&lt;/span&gt;;&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;
&lt;font face="ver"&gt;&amp;nbsp;
&lt;/o:p&gt;
&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: verdana"&gt;&lt;font face="ver"&gt;I don’t know
about you, but I prefer to encapsulate all this into the object itself :).&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;int&lt;/span&gt; &lt;span style="color: black"&gt;GetHashCode&lt;/span&gt;(&lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;x&lt;/span&gt;)
- &lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;Returns the hashcode for
the object.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;bool&lt;/span&gt; &lt;span style="color: black"&gt;IsMutable
– &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 12pt; color: black; font-family: monaco"&gt;Is
this object mutable?&lt;span&gt;&amp;nbsp; &lt;/span&gt;In our case, it doesn’t matter so we return
false.&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font color="#000000"&gt;&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;NullSafeGet&lt;/span&gt;(&lt;span style="color: black"&gt;System&lt;/span&gt;.&lt;span style="color: black"&gt;Data&lt;/span&gt;.&lt;span style="color: teal"&gt;IDataReader&lt;/span&gt; &lt;span style="color: black"&gt;rs&lt;/span&gt;, &lt;span style="color: blue"&gt;string&lt;/span&gt;[] &lt;span style="color: black"&gt;names&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;owner&lt;/span&gt;)
– &lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;This is where a lot of
the magic happens :)&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;First
thing to do is check if the value from the database is null or empty, if it is, then
we can return null and be done.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Second step, grab all the values
from the data reader.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; font-family: verdana"&gt;&lt;font face="ver"&gt;This is one of
the things I don’t like about NHibernate, you have to get the values out by ordinal
value.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Not only by the ordinal value, by in the same order they
are mapped in the NHibernate mapping file (more on this later).&lt;span&gt;&amp;nbsp; &lt;/span&gt;And
finally, build and return a Password object.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;void&lt;/span&gt; &lt;span style="color: black"&gt;NullSafeSet&lt;/span&gt;(&lt;span style="color: black"&gt;System&lt;/span&gt;.&lt;span style="color: black"&gt;Data&lt;/span&gt;.&lt;span style="color: teal"&gt;IDbCommand&lt;/span&gt; &lt;span style="color: black"&gt;cmd&lt;/span&gt;, &lt;span style="color: blue"&gt;object&lt;/span&gt; &lt;span style="color: black"&gt;value&lt;/span&gt;, &lt;span style="color: blue"&gt;int&lt;/span&gt; &lt;span style="color: black"&gt;index&lt;/span&gt;)
– &lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;This is the other half
of the magic&amp;nbsp;:)&lt;/span&gt;&lt;span style="font-size: 12pt; font-family: monaco"&gt;&lt;span&gt; &lt;/span&gt;This
code is fairly straight forward so I won’t bother to explain it.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: teal"&gt;Type&lt;/span&gt; &lt;span style="color: black"&gt;ReturnedType
– &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 12pt; color: black; font-family: monaco"&gt;Tells
NHibernate what type of object will be returned by this CompositeUserType.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;font size="3"&gt;&lt;font face="ver"&gt;&lt;span style="font-size: 10pt; color: blue; font-family: monaco"&gt;public&lt;/span&gt;&lt;span style="font-size: 10pt; font-family: monaco"&gt; &lt;span style="color: blue"&gt;global&lt;/span&gt;::&lt;span style="color: black"&gt;NHibernate&lt;/span&gt;.&lt;span style="color: black"&gt;SqlTypes&lt;/span&gt;.&lt;span style="color: teal"&gt;SqlType&lt;/span&gt;[] &lt;span style="color: black"&gt;SqlTypes
– &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;Tells
NHibernate what data types of each column is.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Again, the the columns
are in ordinal order.&lt;span&gt;&amp;nbsp; &lt;/span&gt;Why “the global::” you might ask?&lt;span&gt;&amp;nbsp; &lt;/span&gt;Well,
we have a class called NHibernate in our DataAccessLayer, so the global:: bit tells
the C# compiler to backup and look in the global NHibernate namespace.&lt;span&gt;&amp;nbsp; &lt;/span&gt;If
you don’t have this issue, you can get rid of the global:: part.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;
&lt;font face="ver"&gt;&amp;nbsp;
&lt;/o:p&gt;
&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;&lt;font face="ver"&gt;Now,
onto the Hibernate mapping file:&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;div class="wlWriterSmartContent" id="57F11A72-B0E5-49c7-9094-E3A15BD5B5E7:937a1ce0-6b48-45ec-8065-ad2e27708770" contenteditable="false" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre style="background-color:White;"&gt;
&lt;div&gt;
&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #FF00FF; "&gt;xml
version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;hibernate-mapping &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;xmlns&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;urn:nhibernate-mapping-2.2&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;class &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;MyNamespace.DomainModel.UserCredential,
MyNamespace.DomainModel&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; table&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;UserCredential&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; lazy&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;id &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; column&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;ID&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; type&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Guid&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;generator &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;class&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;guid.comb&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;id&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; ... &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;property &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Password&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; type&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;MyNamespace.DataAccess.PasswordCompositeUserType,
MyNamespace.DataAccess&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;column &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;HashedPassword&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;column &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;Salt&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;column &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;HashType&amp;quot;&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;property&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000; "&gt;property &lt;/span&gt;&lt;span style="color: #FF0000; "&gt;name&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;=&amp;quot;IsActive&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;class&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000; "&gt; &lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000; "&gt;hibernate-mapping&lt;/span&gt;&lt;span style="color: #0000FF; "&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;Notice
that the column order in the mapping file for our CompositeUserType in our mapping
file is in the exact same order as in our PasswordCompositeUserType class.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;I
know this post was very long, but hopefully you found it useful and can adapt it to
meet your specific needs!&lt;span&gt;&amp;nbsp; &lt;/span&gt;Next up, using a NHibernate UserType
to map the .NET IPAddress class to/from your database.&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;
&lt;br&gt;
&lt;font face="Verdana" size="3"&gt;&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;
&lt;span style="font-size: 12pt; color: black; font-family: 'Verdana','sans-serif'"&gt;Questions,
comments, please feel free to leave a comment.&amp;nbsp; This is my first article and
I'd like as much feedback as possible!&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.milkcarton.com/blog/aggbug.ashx?id=a1540b66-7859-4d60-ab5d-1ff9351408f2" /&gt;</description>
      <comments>http://www.milkcarton.com/blog/CommentView,guid,a1540b66-7859-4d60-ab5d-1ff9351408f2.aspx</comments>
      <category>.NET</category>
      <category>NHibernate</category>
    </item>
  </channel>
</rss>