<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>net-35 &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/net-35/</link>
	<description>Feed of posts on WordPress.com tagged "net-35"</description>
	<pubDate>Sun, 29 Nov 2009 15:33:46 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Visual Studio 2008 and .NET Framework 3.5 Training Kit]]></title>
<link>http://esersahin.wordpress.com/2009/11/21/visual-studio-2008-and-net-framework-3-5-training-kit/</link>
<pubDate>Sat, 21 Nov 2009 07:40:55 +0000</pubDate>
<dc:creator>esersahin</dc:creator>
<guid>http://esersahin.wordpress.com/2009/11/21/visual-studio-2008-and-net-framework-3-5-training-kit/</guid>
<description><![CDATA[http://www.microsoft.com/downloads/details.aspx?FamilyID=8BDAA836-0BBA-4393-94DB-6C3C4A0C98A1&amp;di]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>http://www.microsoft.com/downloads/details.aspx?FamilyID=8BDAA836-0BBA-4393-94DB-6C3C4A0C98A1&#38;displaylang=en</p>
<p>The Visual Studio 2008 and .NET Framework 3.5 Training Kit includes presentations, hands-on labs, and demos. This content is designed to help you learn how to utilize the Visual Studio 2008 features and a variety of framework technologies including: LINQ, C# 3.0, Visual Basic 9, WCF, WF, WPF, ASP.NET AJAX, VSTO, CardSpace, SilverLight, Mobile and Application Lifecycle Management.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Break out of WebForm_DoPostBackWithOptions Hell]]></title>
<link>http://computermutt.wordpress.com/2009/10/28/break-out-of-webform_dopostbackwithoptions-hell/</link>
<pubDate>Wed, 28 Oct 2009 22:35:31 +0000</pubDate>
<dc:creator>Mike Malter</dc:creator>
<guid>http://computermutt.wordpress.com/2009/10/28/break-out-of-webform_dopostbackwithoptions-hell/</guid>
<description><![CDATA[I have been going nuts all day trying to get a link button to fire its command event and cause a pos]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I have been going nuts all day trying to get a link button to fire its command event and cause a postback in a GridView control.  On this particular page, whenever I click on the link, I get a WebForm_DoPostBackWithOptions instead of __doPostback, and of course I never hit the grid&#8217;s command event in my page behind.</p>
<p>The solution?  Set <span style="color:#ff0000;font-size:x-small;"><span style="color:#ff0000;font-size:x-small;">causesvalidation</span></span><span style="color:#0000ff;font-size:x-small;"><span style="color:#0000ff;font-size:x-small;">=&#8221;false&#8221; <span style="color:#000000;">in the link button and the command event will fire.   Why, I don&#8217;t know, this just works and hopefully you&#8217;ll find this post before having to spend too many hours trying to figure it out.</span></span></span></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ASP.NET 4 and Visual Studio 2010 Released]]></title>
<link>http://vijaymodi.wordpress.com/2009/10/22/asp-net-4-beta-2-and-visual-studio-2010-beta-2-released/</link>
<pubDate>Thu, 22 Oct 2009 08:00:17 +0000</pubDate>
<dc:creator>Vijay Modi</dc:creator>
<guid>http://vijaymodi.wordpress.com/2009/10/22/asp-net-4-beta-2-and-visual-studio-2010-beta-2-released/</guid>
<description><![CDATA[Today, I just visited http://ASP.Net and found that Microsoft has released ASP.Net 4 Beta 2 and Visu]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Today, I just visited http://ASP.Net and found that Microsoft has released ASP.Net 4 Beta 2 and Visual Studio 2010 Beta 2. You can find some of the exciting changes on the following URL:</p>
<p>http://www.asp.net/learn/whitepapers/aspnet4/#_TOC1_1</p>
<p>And you can find Breaking changes on the following URL:</p>
<p>http://www.asp.net/learn/whitepapers/aspnet4/breaking-changes/</p>
<p>Some new features are really amazing. Lets start with this new one instead of using old.</p>
<p>Cheers with ASP.Net 4 Beta 2 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
Vijay Modi</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Validation on User Registration]]></title>
<link>http://vijaymodi.wordpress.com/2009/10/11/validation-on-user-registration/</link>
<pubDate>Sun, 11 Oct 2009 13:20:52 +0000</pubDate>
<dc:creator>Vijay Modi</dc:creator>
<guid>http://vijaymodi.wordpress.com/2009/10/11/validation-on-user-registration/</guid>
<description><![CDATA[Article moved on the following URL: http://mysoftskill.blogspot.com/2009/11/validation-on-user-regis]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Article moved on the following URL:</p>
<p><a title="http://mysoftskill.blogspot.com/2009/11/validation-on-user-registration.html" href="http://mysoftskill.blogspot.com/2009/11/validation-on-user-registration.html">http://mysoftskill.blogspot.com/2009/11/validation-on-user-registration.html</a></p>
<p>Thanks &#38; Regards,<br />
Vijay Modi</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Solve new page flicker in AJAX]]></title>
<link>http://computermutt.wordpress.com/2009/10/09/solve-new-page-flicker-in-ajax/</link>
<pubDate>Sat, 10 Oct 2009 00:15:35 +0000</pubDate>
<dc:creator>Mike Malter</dc:creator>
<guid>http://computermutt.wordpress.com/2009/10/09/solve-new-page-flicker-in-ajax/</guid>
<description><![CDATA[Want to stop flickering when going from one page to another in AJAX? Put the following code in your ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Want to stop flickering when going from one page to another in AJAX?</p>
<p>Put the following code in your head section:</p>
<pre class="brush: xml;">

&#60;head runat=&#34;server&#34;&#62;
        &#60;meta http-equiv=&#34;Page-Enter&#34; content=&#34;BlendTrans(Duration=.05)&#34; /&#62;
        &#60;meta http-equiv=&#34;Page-Exit&#34; content=&#34;BlendTrans(Duration=.05,Translation=0)&#34; /&#62;
&#60;/head&#62;
</pre>
<p>For more details about these meta settings, go to <a href="http://www.aim-higher.net/meta-transitions.asp">http://www.aim-higher.net/meta-transitions.asp</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ASP.NET User Control events tamed through Page_PreRenderComplete ]]></title>
<link>http://computermutt.wordpress.com/2009/10/09/asp-net-user-control-events-tamed-through-page_prerendercomplete/</link>
<pubDate>Fri, 09 Oct 2009 20:36:38 +0000</pubDate>
<dc:creator>Mike Malter</dc:creator>
<guid>http://computermutt.wordpress.com/2009/10/09/asp-net-user-control-events-tamed-through-page_prerendercomplete/</guid>
<description><![CDATA[Something that has been bothering me for a really long time is now under control thanks to a blog po]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Something that has been bothering me for a really long time is now under control thanks to a blog post in the .NET Geek&#8217;s Blog entry on <a href="http://kiransalke.wordpress.com/2009/06/27/understanding-the-page-life-cycle-in-asp-net/">Understanding the Page Life Cycle in ASP.NET</a>.  In a nutshell, here is the issue.  I prefer to create user controls that wrap standard .NET controls and then put role enabled and other code into the controls.  That code determines if the control makes it self visible or disabled along with some other nice to haves.</p>
<p>The problem is that when a page first draws and fires off its events, the user control events follow, and if I come into the page wanting a button to be disabled in certian instances, the user controls resolve their states after the page.  So if I have a button in a user control and expose its Enabled property through a get/set variable, I can never make it stick when the page first draws.</p>
<p>In the source code below, I am using the Page_PreRenderComplete event to test for page state and call an appropriate method.  In this case the PrepUIforAdd is called and it disables a number of buttons as well other things.  If I called PrepUIforAdd in the Page_PreRender event, the buttons would never stay disabled.  But calling it in the Page_PreRenderComplete event will result in the outcome I want when the page displays.</p>
<pre class="brush: csharp;">
		/// &#60;summary&#62;
		/// PreRender is complete
		/// &#60;/summary&#62;
		/// &#60;param name=&#34;sender&#34;&#62;&#60;/param&#62;
		/// &#60;param name=&#34;e&#34;&#62;&#60;/param&#62;
		protected void Page_PreRenderComplete( object sender, EventArgs e )
		{
			if ( !Page.IsPostBack )
			{
				ucErrorMessage.Clear();

				switch ( this.CurrentPageState )
				{
					case PageState.Add:
						{
							PrepUIforAdd();
							break;
						}
					case PageState.Edit:
						{
							PopulatePersonInfo();
							PopulateLinkedRoles();
							PopulateUnlinkedRoles();
							break;
						}
				}

				this.ManagePersonTabContainer.ActiveTabIndex = 0;
			}
		}

		/// &#60;summary&#62;
		/// Preps UI for adding a person
		/// &#60;/summary&#62;
		private void PrepUIforAdd()
		{
			this.txtPersonID.Text = (PersonIDConstant.Everybody.ToInt()).ToString();

			this.txtLastName.Text = string.Empty;
			this.txtFirstName.Text = string.Empty;
			this.txtLogin.Text = string.Empty;
			this.txtPassword.Text = string.Empty;
			this.txtInceptionDate.Text = string.Empty;
			this.txtLastModifiedDate.Text = string.Empty;
			this.txtLastModifiedByPersonName.Text = string.Empty;
			this.ddActive.YesNoID = 1;
			this.ddDeleted.YesNoID = 0;

			lbRolesAvailable.Clear();
			lbRolesSelected.Clear();

			this.bDelete.Enabled = false;
			this.bNew.Enabled = false;
			this.bResetPassword.Enabled = false;
			this.bRoleLink.Enabled = false;
			this.bRoleUnlink.Enabled = false;

			ddEmailType.Clear();
			List&#60;EmailCollection&#62; dt = GetCachedEmailList();
			if ( this.ErrorLevel == Status.Success )
			{
				ddEmailType.DataSource = dt;
				ddEmailType.DataTextField = &#34;EmailTypeName&#34;;
				ddEmailType.DataValueField = &#34;EmailTypeID&#34;;
				ddEmailType.DataBind();
			}

			this.txtEmail.Text = GetCachedEmailAddress( PersonIDConstant.Everybody.ToInt(), ddEmailType );
		}
</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Populating Select Lists in ASP.NET MVC and jQuery]]></title>
<link>http://tiredblogger.wordpress.com/2009/09/25/populating-select-lists-in-asp-net-mvc-and-jquery/</link>
<pubDate>Fri, 25 Sep 2009 15:50:26 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/09/25/populating-select-lists-in-asp-net-mvc-and-jquery/</guid>
<description><![CDATA[I&rsquo;ve been working the last bit to find the best way to create/populate select (option) lists u]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been working the last bit to find the best way to create/populate select (option) lists using a mixture of ASP.NET MVC and jQuery.&#160; What I&#8217;ve run into is that the &#8220;key&#8221; and &#8220;value&#8221; tags are not passed along when using <strong>Json(data)</strong>.</p>
<p>Here&#8217;s what I&#8217;m trying to pull off in jQuery: building&#160;a simple select drop down list.</p>
<blockquote>
<p>var dd_activities = &#8220;&#60;select id=&#8217;dd_activities&#8217;&#62;&#8221;;<br />var count = data.length;<br />for (var i = 0; i &#60; count; i++) {<br />&#160;dd_activities += &#8220;&#60;option value=&#8217;&#8221; + data[i].Key + &#8220;&#8216;&#62;&#8221; + data[i].Value + &#8220;&#60;/option&#62;&#8221;;<br />}<br />dd_activities += &#8220;&#60;/select&#62;&#8221;;</p>
<p>$(&#8220;#activities&#8221;).before(dd_activities);</p>
</blockquote>
<p>Using some very basic key/value data:</p>
<blockquote>
<p>[ <br />&#160;{"3","Text Value"},<br />&#160;{"4","Another Text Value"},<br />&#160;{"1","More boring values..."},<br />&#160;{"2","Running out of values"},<br />&#160;{"5","Last value..."}<br />]</p>
</blockquote>
<div class="netInfoResponseText netInfoText ">Without any sort of name, I was at a loss on how to access the information, how to get it&#8217;s length, or anything.&#160; FireBug was happy to order it up&#8230; but that didn&#8217;t help.</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">My first attempt was to use a custom object, but that just felt dirty&#8212;creating NEW objects simply to return Json data.</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">My second attempt matched the mentality of newing new anonymous Json objects and seemed to work like a champ:</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<p style="margin:0;">[<span style="color:#cae682;">Authorize</span>]</p>
<p style="margin:0;">[<span style="color:#cae682;">CacheFilter</span>(Duration = <span style="color:#e5786d;">20</span>)]</p>
<p style="margin:0;"><span style="color:#8ac6f2;">public</span> <span style="color:#cae682;">ActionResult</span> GetActivitiesList()</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:#8ac6f2;">try</span></p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; <span style="color:#8ac6f2;">var</span> results = </p>
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; _activityRepository</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; .GetAll()</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; .OrderBy(x =&#62; x.Target.Name).OrderBy(x =&#62; x.Name)</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; .Select(x =&#62; <span style="color:#8ac6f2;">new</span></p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; Key = x.Id.ToString(), </p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; Value = <span style="color:#8ac6f2;">string</span>.Format(<span style="color:#e5786d;">&#8220;[{0}] {1}&#8221;</span>, x.Target.Name, x.Name)</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; })</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; .ToList();</p>
</div>
<p><!--EndFragment--><!--EndFragment--></div>
</div>
<p><!--EndFragment--></p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; <span style="color:#8ac6f2;">return</span> Json(results);</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:#8ac6f2;">catch</span> (<span style="color:#cae682;">Exception</span> ex)</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; <span style="color:#8ac6f2;">return</span> Json(ex.Message);</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">Well, not beautiful, but returns a sexy Key/Value list that Json expects&#8212;and that populates our select list.</div>
<blockquote>
<div class="netInfoResponseText netInfoText ">[<br />&#160;{"Key":"3","Value":"Text Value"},<br />&#160;{"Key":"4","Value":"Another Text Value"},<br />&#160;{"Key":"1","Value":"More boring values..."},<br />&#160;{"Key":"2","Value":"Running out of values"},<br />&#160;{"Key":"5","Value":"Last value..."}<br />]</div>
</blockquote>
<div class="netInfoResponseText netInfoText ">The next step was to get that out of the controller and into the data repository&#8230; pushing some of that logic back down to the database.</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;"><span style="color:#8ac6f2;"></p>
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;"><span style="color:#8ac6f2;"></p>
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<p style="margin:0;"><span style="color:#8ac6f2;">var</span> criteria =</p>
<p style="margin:0;">&#160;&#160;&#160; Session.CreateCriteria&#60;<span style="color:#cae682;">Activity</span>&#62;()</p>
<p style="margin:0;">&#160;&#160;&#160; .CreateAlias(<span style="color:#e5786d;">&#8220;Target&#8221;</span>, <span style="color:#e5786d;">&#8220;Target&#8221;</span>)</p>
<p style="margin:0;">&#160;&#160;&#160; .Add(<span style="color:#cae682;">Restrictions</span>.Eq(<span style="color:#e5786d;">&#8220;IsValid&#8221;</span>, <span style="color:#8ac6f2;">true</span>))</p>
<p style="margin:0;">&#160;&#160;&#160; .AddOrder(<span style="color:#cae682;">Order</span>.Asc(<span style="color:#e5786d;">&#8220;Target.Name&#8221;</span>))</p>
<p style="margin:0;">&#160;&#160;&#160; .AddOrder(<span style="color:#cae682;">Order</span>.Asc(<span style="color:#e5786d;">&#8220;Name&#8221;</span>))</p>
<p style="margin:0;">&#160;&#160;&#160; .SetMaxResults(<span style="color:#e5786d;">100</span>);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;"><span style="color:#8ac6f2;">var</span> data = criteria.List&#60;<span style="color:#cae682;">Activity</span>&#62;();</p>
<p style="margin:0;"><span style="color:#8ac6f2;">var</span> result =</p>
<p style="margin:0;">&#160;&#160;&#160; data</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; .Select(x =&#62; <span style="color:#8ac6f2;">new</span></p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; Key = x.Id.ToString(), </p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; Value = <span style="color:#8ac6f2;">string</span>.Format(<span style="color:#e5786d;">&#8220;[{0}] {1}&#8221;</span>, x.Target.Name, x.Name)</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; })</p>
<p style="margin:0;">&#160;&#160;&#160; &#160;&#160;&#160; .ToList();</p>
<p style="margin:0;">tx.Commit();</p>
<p style="margin:0;"><span style="color:#8ac6f2;">return</span> result;</p>
</div>
<p><!--EndFragment--></span></div>
<p><!--EndFragment--></span><!--EndFragment--></div>
</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">A bit of formatting, restrictions, push the ordering back to the database, and a tidy SQL statement is created.</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">The last touch is the return type.&#160; Since we&#8217;re returning a &#8220;List&#8221; of anonymous types, the return type of GetActivitiesList() must be an <strong>IList.</strong></div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">That shrinks down my ActionResult to a single call.</div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">
<div style="font-family:Envy Code R, Consolas, Arial;background:#242424;color:#e8f3f6;font-size:10pt;">
<p style="margin:0;"><span style="color:#8ac6f2;">try</span></p>
<p style="margin:0;">&#160;{</p>
<p style="margin:0;">&#160;&#160;&#160;&#160; <span style="color:#8ac6f2;">return</span> Json(_activityRepository.GetActivitiesList());</p>
<p style="margin:0;">&#160;}</p>
<p style="margin:0;">&#160;<span style="color:#8ac6f2;">catch</span> (<span style="color:#cae682;">Exception</span> ex)</p>
<p style="margin:0;">&#160;{</p>
<p style="margin:0;">&#160;&#160;&#160;&#160; <span style="color:#8ac6f2;">return</span> Json(ex.Message);</p>
<p style="margin:0;">&#160;}</p>
</div>
<p><!--EndFragment--></div>
<div class="netInfoResponseText netInfoText ">&#160;</div>
<div class="netInfoResponseText netInfoText ">That works&#8230; and will work for now.&#160; Though, I&#8217;ve marked it as a HACK in my code.&#160; Why?&#160; I&#8217;m honestly not sure yet.&#160; Just a feeling.</div>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/asp.net+mvc">asp.net+mvc</a>, <a rel="tag" href="http://technorati.com/tag/jquery">jquery</a>, <a rel="tag" href="http://technorati.com/tag/nhibernate">nhibernate</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Calling SSIS from .Net]]></title>
<link>http://arcanecode.com/2009/09/24/calling-ssis-from-net/</link>
<pubDate>Thu, 24 Sep 2009 22:43:39 +0000</pubDate>
<dc:creator>arcanecode</dc:creator>
<guid>http://arcanecode.com/2009/09/24/calling-ssis-from-net/</guid>
<description><![CDATA[In a recent DotNetRocks show, episode 483, Kent Tegels was discussing SQL Server Integration Service]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In a recent DotNetRocks show, <a href="http://www.dotnetrocks.com/default.aspx?showNum=483" target="_blank">episode 483</a>, Kent Tegels was discussing SQL Server Integration Services and how it can be useful to both the BI Developer as well as the traditional application developer. While today I am a SQL Server BI guy, I come from a long developer background and could not agree more. SSIS is a very powerful tool that could benefit many developers even those not on Business Intelligence projects. It was a great episode, and I high encourage everyone to listen. </p>
<p>There is one point though that was not made very clear, but I think is tremendously important. It is indeed possible to invoke an SSIS package from a .Net application if that SSIS package has been deployed to the SQL Server itself. This article will give an overview of how to do just that. All of the sample code here will also be made available in download form from the companion Code Gallery site, <a href="http://code.msdn.microsoft.com/ssisfromnet" target="_blank">http://code.msdn.microsoft.com/ssisfromnet</a> . </p>
<p>In this article, I do assume a few prerequisites. First, you have a SQL Server with SSIS installed, even if it’s just your local development box with SQL Server Developer Edition installed. Second, I don’t get into much detail on how SSIS works, the package is very easy to understand. However you may wish to have a reference handy. You may also need the assistance of your friendly neighborhood DBA in setting up the SQL job used in the process. </p>
<p><b>Summary</b></p>
<p>While the technique is straightforward, there are a fair number of detailed steps involved. For those of you just wanting the overview, we need to start with some tables (or other data) we want to work with. After that we’ll write the SSIS package to manipulate that data. </p>
<p>Once the package is created it must be deployed to the SQL Server so it will know about it. This deploy can be to the file system or to SQL Server. </p>
<p>Once deployed, a SQL Server Job must be created that executes the deployed SSIS package. </p>
<p>Finally, you can execute the job from your .Net application via ADO.NET and a call to the sp_start_job stored procedure built into the msdb system database. </p>
<p>OK, let’s get to coding!</p>
<p><b>Setup the Tables</b></p>
<p>First we need some data to work with. What better than a listing of previous Dot Net Rocks episodes? I simply went to the <a href="http://www.dotnetrocks.com/archives.aspx" target="_blank">Previous Shows</a> page, highlighted the three columns of show number, show name, and date, and saved them to a text file. (Available on the <a href="http://code.msdn.microsoft.com/ssisfromnet" target="_blank">Code Gallery</a> site.)</p>
<p>Next we need a place to hold data so SSIS can work with it. I created a database and named it ArcaneCode, however any database should work. Next we’ll create a table to hold “staging” DNR Show data. </p>
<p>CREATE TABLE [dbo].[staging_DNRShows](    <br />&#160; [ShowData] [varchar](250) NOT NULL     <br />) ON [PRIMARY]</p>
<p>This table will hold the raw data from the text file, each line in the text file becoming one row here. Next we want a table to hold the final results.</p>
<p>CREATE TABLE [dbo].[DNRShows](    <br />&#160; [ShowNumber] [int] NOT NULL,     <br />&#160; [ShowName] [varchar](250) NULL,     <br />&#160; [ShowDate] [datetime] NULL,     <br />&#160; CONSTRAINT [PK_DNRShows] PRIMARY KEY CLUSTERED     <br />&#160; (     <br />&#160; [ShowNumber] ASC     <br />&#160; )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]     <br />&#160; ) ON [PRIMARY]     </p>
<p>The job of the SSIS package will be to read each row in the staging table and split it into 3 columns, the show’s number, name, and date, then place those three columns into the DNRShows table above.</p>
<p><b>The SSIS Package</b></p>
<p>The next step is to create the SSIS package itself. Opening up Visual Studio / BIDS, create a new Business Intelligence SQL Server Integration Services project. First let’s setup a shared Data Source to the local server, using the ArcaneCode database as our source. </p>
<p>The default package name of “Package.dtsx” isn’t very informative, so let’s rename it ”LoadDNRShows.dtsx”. Start by adding a reference to the shared data source in the Connection Managers area, taking the default. Then in the Control Flow surface add 3 tasks, as seen here:</p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image001.jpg"><img style="display:inline;border-width:0;" title="clip_image001" border="0" alt="clip_image001" src="http://arcanecode.files.wordpress.com/2009/09/clip_image001_thumb.jpg?w=339&#038;h=270" width="339" height="270" /></a></p>
<p>The first task is an Execute SQL Task that simply runs a “DELETE FROM dbo.DNRShows” command to wipe out what was already there. Of course in a true application we’d be checking for existing records in the data flow and doing updates or inserts, but for simplicity in this example we’ll just wipe and reload each time.</p>
<p>The final task is also an Execute SQL Task, after we have processed the data we no longer need it in the staging table, so we’ll issue a “DELETE FROM dbo.staging_DNRShows” to remove it. </p>
<p>The middle item is our Data Flow Task. This is what does the heavy lifting of moving the staging data to the main table. Here is a snapshot of what it looks like:</p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image002.jpg"><img style="display:inline;border-width:0;" title="clip_image002" border="0" alt="clip_image002" src="http://arcanecode.files.wordpress.com/2009/09/clip_image002_thumb.jpg?w=239&#038;h=231" width="239" height="231" /></a></p>
<p>The first task is our OLEDB Source, it references the staging_DNRShows table. Next is what’s called a Derived Column Transformation. This will allow you to add new calculated columns to the flow, or add columns from variables. In this case we want to add three new columns, based on the single column coming from the staging table. </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image003.jpg"><img style="display:inline;border-width:0;" title="clip_image003" border="0" alt="clip_image003" src="http://arcanecode.files.wordpress.com/2009/09/clip_image003_thumb.jpg?w=656&#038;h=544" width="656" height="544" /></a></p>
<p>As you can see in under Columns in the upper left, we have one column in our source, ShowData. In the lower half we need to add three new columns, ShowNumber, ShowDate, and ShowName. Here are the expressions for each:</p>
<p>ShowNumber   <br />&#160;&#160;&#160; (DT_I4)SUBSTRING(ShowData,1,FINDSTRING(ShowData,&#34;\t&#34;,1))</p>
<p>ShowDate   <br />&#160;&#160;&#160; (DT_DBDATE)SUBSTRING(ShowData,FINDSTRING(ShowData,&#34;\t&#34;,2) + 1,LEN(ShowData) &#8211; FINDSTRING(ShowData,&#34;\t&#34;,2))</p>
<p>ShowName   <br />&#160;&#160;&#160; (DT_STR,250,1252)SUBSTRING(ShowData,FINDSTRING(ShowData,&#34;\t&#34;,1) + 1,FINDSTRING(ShowData,&#34;\t&#34;,2) &#8211; FINDSTRING(ShowData,&#34;\t&#34;,1) &#8211; 1)</p>
<p>The syntax is an odd blend of VB and C#. Each one starts with a “(DT_”, these are type casts, converting the result of the rest of the expression to what we need. For example, (DT_I4) converts to a four byte integer, which we need because in our database the ShowNumber column was defined as an integer. You will see SUBSTRING and LEN which work like their VB counterparts. FINDSTRING works like the old POS statement, it finds the location of the text and returns that number. The “\t” represents the tab character, here the C# fans win out as the Expression editor uses C# like escapes for special characters. \t for tab, \b for backspace, etc. </p>
<p>Finally we need to write out the data. For this simply add an OLEDB Destination and set it to the target table of dbo.DNRShows. On the mappings tab make sure our three new columns map correctly to the columns in our target table. </p>
<p><b>Deploy the Package</b></p>
<p>This completes the coding for the package, but there is one final step we need to do. First, in the solution explorer right click on the project (not the solution, the project as highlighted below) and pick properties. </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image004.jpg"><img style="display:inline;border-width:0;" title="clip_image004" border="0" alt="clip_image004" src="http://arcanecode.files.wordpress.com/2009/09/clip_image004_thumb.jpg?w=311&#038;h=333" width="311" height="333" /></a></p>
<p>In the properties dialog, change the “CreateDeploymentUtility” option from false (the default) to True.</p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image006.jpg"><img style="display:inline;border-width:0;" title="clip_image006" border="0" alt="clip_image006" src="http://arcanecode.files.wordpress.com/2009/09/clip_image006_thumb.jpg?w=628&#038;h=383" width="628" height="383" /></a></p>
<p>Now click the Build, Build Solution menu item. If all went well you should see the build was successful. It’s now time to deploy the package to the server. Navigate to the folder where your project is stored, under it you will find a bin folder, and in it a Deployment folder. In there you should find a file with a “.SSISDeploymentManifest” extension. Double click on this file to launch the Package Installation Wizard.</p>
<p>When the wizard appears there are two choices, File system deployment and SQL Server deployment. For our purposes we can use either one, there are pros and cons to each and many companies generally pick one or the other. In this example we’ll pick SQL Server deployment, but again know that I’ve tested this both ways and either method will work. </p>
<p>Once you pick SQL Server deployment, just click Next. Now it asks you for the server name, I’ve left it at (local) since I’m working with this on a development box; likewise I’ve left “Use Windows Authentication”. Finally I need the package path, I can select this by clicking the ellipse (the …) to the right of the text box. This brings up a dialog where I can select where to install. </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image007.jpg"><img style="display:inline;border-width:0;" title="clip_image007" border="0" alt="clip_image007" src="http://arcanecode.files.wordpress.com/2009/09/clip_image007_thumb.jpg?w=350&#038;h=304" width="350" height="304" /></a></p>
<p>In a real world production scenario we’d likely have branches created for each of our projects, but for this simple demo we’ll just leave it in the root and click OK. </p>
<p>Once your form is filled out as below, click Next. </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image008.jpg"><img style="display:inline;border-width:0;" title="clip_image008" border="0" alt="clip_image008" src="http://arcanecode.files.wordpress.com/2009/09/clip_image008_thumb.jpg?w=505&#038;h=457" width="505" height="457" /></a></p>
<p>We are next queried to what our installation folder should be. This is where SSIS will cache package dependencies. Your DBA may have a special spot setup for these, if not just click next to continue.</p>
<p>Finally we are asked to confirm we know what we are doing. Just click Next. If all went well, the install wizard shows us it’s happy with a report, and we can click Finish to exit. </p>
<p><b>Setup the SQL Server Job</b></p>
<p>We’ve come a long way and we’re almost to the finish line, just one last major step. We will need to setup a SQL Server Job which will launch the SSIS package for us. In SQL Server Management Studio, navigate to the “SQL Server Agent” in your Object Explorer. If it’s not running, right click and pick “Start”. Once it’s started, navigate to the Jobs branch. Right click and pick “New Job”. </p>
<p>When the dialog opens, start by giving your job a name. As you can see below I used LoadDNRShows. I also entered a description. </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image010.jpg"><img style="display:inline;border-width:0;" title="clip_image010" border="0" alt="clip_image010" src="http://arcanecode.files.wordpress.com/2009/09/clip_image010_thumb.jpg?w=628&#038;h=564" width="628" height="564" /></a></p>
<p>Now click on the Jobs page over on the left “Select a page” menu. At the bottom click “New” to add a new job step. </p>
<p>In the job step properties dialog, let’s begin by naming the step “Run the SSIS package”. Change the Type to “SQL Server Integration Services Package”. When you do, the dialog will update to give options for SSIS. Note the Run As drop down, this specifies the account to run under. For this demo we’ll leave it as the SQL Server Agent Service Account, check with your DBA as he or she may have other instructions. </p>
<p>In the tabbed area the General tab first allows us to pick the package source. Since we deployed to SQL Server we’ll leave it at the default, however if you had deployed to the file system this is where you’d need to change it to pick your package. </p>
<p>At the bottom we can use the ellipse to pick our package from a list. That done your screen should look something like:</p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image011.jpg"><img style="display:inline;border-width:0;" title="clip_image011" border="0" alt="clip_image011" src="http://arcanecode.files.wordpress.com/2009/09/clip_image011_thumb.jpg?w=491&#038;h=497" width="491" height="497" /></a></p>
<p>For this demo that’s all we need to set, I do want to take a second to encourage you to browse through the other tabs. Through these tabs you can set many options related to the package. For example you could alter the data sources, allowing you to use one package with multiple databases. </p>
<p>Click OK to close the job step, then OK again to close the Job Properties window. Your job is now setup!</p>
<p><b>Calling from .Net</b></p>
<p>The finish line is in sight! Our last step is to call the job from .Net. To make it a useful example, I also wanted the .Net application to upload the data the SSIS package will manipulate. For simplicity I created a WinForms app, but this could easily be done in any environment. I also went with C#, again the VB.Net code is almost identical. </p>
<p>I started by creating a simple WinForm with two buttons and one label. (Again the full project will be on the <a href="http://code.msdn.microsoft.com/ssisfromnet" target="_blank">Code Gallery</a> site). </p>
<p><a href="http://arcanecode.files.wordpress.com/2009/09/clip_image012.jpg"><img style="display:inline;border-width:0;" title="clip_image012" border="0" alt="clip_image012" src="http://arcanecode.files.wordpress.com/2009/09/clip_image012_thumb.jpg?w=352&#038;h=165" width="352" height="165" /></a></p>
<p>In the code, first be sure to add two using statements to the standard list:</p>
<p>using System.Data.SqlClient;</p>
<p>using System.IO;</p>
<p>Behind the top button we’ll put the code to copy the data from the text file we created from the DNR website to the staging table. </p>
<div style="font-family:consolas;background:white;color:black;font-size:10pt;">
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> btnLoadToStaging_Click(<span style="color:blue;">object</span> sender, <span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">/* This method takes the data in the DNRShows.txt file and uploads them to a staging table */</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">/* The routine is nothing magical, standard stuff to read as Text file and upload it to a&#160; */</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">/* table via ADO.NET&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; */</span></p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// Note, be sure to change to your correct path</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> filename = <span style="color:#a31515;">@&#34;D:\Presentations\SQL Server\Calling SSIS From Stored Proc\DNRShows.txt&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> line;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// If you used a different db than ArcaneCode be sure to set it here</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> connect = <span style="color:#a31515;">&#34;server=localhost;Initial Catalog=ArcaneCode;Integrated Security=SSPI;&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">SqlConnection</span> connection = <span style="color:blue;">new</span> <span style="color:#2b91af;">SqlConnection</span>(connect);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; connection.Open();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">SqlCommand</span> cmd = connection.CreateCommand();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// Wipe out previous data in case of a crash</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> sql = <span style="color:#a31515;">&#34;DELETE FROM dbo.staging_DNRShows&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.CommandText = sql;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.ExecuteNonQuery();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// Now setup for new inserts</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; sql = <span style="color:#a31515;">&#34;INSERT INTO dbo.staging_DNRShows (ShowData) VALUES (@myShowData)&#34;</span>;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.CommandText = sql;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.Parameters.Add(<span style="color:#a31515;">&#34;@myShowData&#34;</span>, <span style="color:#2b91af;">SqlDbType</span>.VarChar, 255);</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">StreamReader</span> sr = <span style="color:blue;">null</span>;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// Loop thru text file, insert each line to staging table</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">try</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; sr = <span style="color:blue;">new</span> <span style="color:#2b91af;">StreamReader</span>(filename);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; line = sr.ReadLine();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">while</span> (line != <span style="color:blue;">null</span>)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cmd.Parameters[<span style="color:#a31515;">&#34;@myShowData&#34;</span>].Value = line;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; cmd.ExecuteNonQuery();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; lblProgress.Text = line;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; line = sr.ReadLine();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">finally</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">if</span> (sr != <span style="color:blue;">null</span>)</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; sr.Close();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; connection.Close();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160;&#160;&#160; lblProgress.Text = <span style="color:#a31515;">&#34;Data has been loaded&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; }</p>
<p style="margin:0;">&#160;</p>
</p></div>
<p>Before you ask, yes I could have used any number of data access technologies, such as LINQ. I went with ADO.NET for simplicity and believing most developers are familiar with it due to its longevity. Do be sure and update the database name and path to the file in both this and the next example when you run the code. </p>
<p>This code really does nothing special, just loops through the text file and uploads each line as a row in the staging table. It does however serve as a realistic example of something you’d do in this scenario, upload some data, then let SSIS manipulate it on the server. </p>
<p>Once the data is there, it’s finally time for the grand finale. The code behind the second button, Execute SSIS, does just what it says; it calls the job, which invokes our SSIS package. </p>
<div style="font-family:consolas;background:white;color:black;font-size:10pt;">
<p style="margin:0;">&#160;&#160;&#160; <span style="color:blue;">private</span> <span style="color:blue;">void</span> btnRunSSIS_Click(<span style="color:blue;">object</span> sender, <span style="color:#2b91af;">EventArgs</span> e)</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> connect = <span style="color:#a31515;">&#34;server=localhost;Initial Catalog=ArcaneCode;Integrated Security=SSPI;&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">SqlConnection</span> connection = <span style="color:blue;">new</span> <span style="color:#2b91af;">SqlConnection</span>(connect);</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; connection.Open();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:#2b91af;">SqlCommand</span> cmd = connection.CreateCommand();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:green;">// Wipe out previous data in case of a crash</span></p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; <span style="color:blue;">string</span> sql = <span style="color:#a31515;">&#34;exec msdb.dbo.sp_start_job N&#8217;LoadDNRShows&#8217;&#34;</span>;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.CommandText = sql;</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; cmd.ExecuteNonQuery();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; connection.Close();</p>
<p style="margin:0;">&#160;&#160;&#160;&#160;&#160; lblProgress.Text = <span style="color:#a31515;">&#34;SSIS Package has been executed&#34;</span>;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
</p></div>
<p>The key is this sql command:</p>
<p>exec msdb.dbo.sp_start_job N’LoadDNRShows’</p>
<p>“exec” is the T-SQL command to execute a stored procedure. “sp_start_job” is the stored procedure that ships with SQL Server in the MSDB system database. This stored procedure will invoke any job stored on the server. In this case, it invokes the job “LoadDNRShows”, which as we setup will run an SSIS package. </p>
<p>Launch the application, and click the first button. Now jump over to SQL Server Management Studio and run this query:</p>
<p>select * from dbo.staging_DNRShows;</p>
<p>select * from dbo.DNRShows;</p>
<p>You should see the first query bring back rows, while the second has nothing. Now return to the app and click the “Execute SSIS” button. If all went well running the query again should now show no rows in our first query, but many nicely processed rows in the second. Success!</p>
<p><b>A few thoughts about xp_cmdshell</b></p>
<p>In researching this article I saw many references suggesting writing a stored procedure that uses xp_cmdshell to invoke dtexec. DTEXEC is the command line utility that you can use to launch SSIS Packages. Through it you can override many settings in the package, such as connection strings or variables. </p>
<p>xp_cmdshell is a utility built into SQL Server. Through it you can invoke any “DOS” command. Thus you could dynamically generate a dtexec command, and invoke it via xp_cmdshell. </p>
<p>The problem with xp_cmdshell is you can use it to invoke ANY “DOS” command. Any of them. Such as oh let’s say “DEL *.*” ? xp_cmdshell can be a security hole, for that reason it is turned off by default on SQL Server, and many DBA’s leave it turned off and are not likely to turn it on. </p>
<p>The techniques I’ve demonstrated here do not rely on xp_cmdshell. In fact, all of my testing has been done on my server with the xp_cmdshell turned off. Even though it can be a bit of extra work, setting up the job, etc., I still advise it over the xp_cmdshell method for security and the ability to use it on any server regardless of its setting. </p>
<p><b>In Closing</b></p>
<p>That seemed like a lot of effort, but can lead to some very powerful solutions. SSIS is a very powerful tool designed for processing large amounts of data and transforming it. In addition developing under SSIS can be very fast due to its declarative nature. The sample package from this article took the author less than fifteen minutes to code and test. </p>
<p>When faced with a similar task, consider allowing SSIS to handle the bulk work and just having your .Net application invoke your SSIS package. Once you do, there are no ends to the uses you’ll find for SQL Server Integration Services. </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Html.Grid Rendering as Plain Text?]]></title>
<link>http://tiredblogger.wordpress.com/2009/09/23/html-grid-rendering-as-plain-text/</link>
<pubDate>Thu, 24 Sep 2009 03:22:43 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/09/23/html-grid-rendering-as-plain-text/</guid>
<description><![CDATA[Notice: Stupid, stupid moment described ahead.&nbsp; Proceed with caution. I spent a good half hour ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong>Notice: Stupid, stupid moment described ahead.&#160; Proceed with caution.</strong></p>
<p>I spent a good half hour trying to figure out why my MVCContrib Html.Grid&#60;T&#62; wasn&#8217;t rendering.&#160; It wasn&#8217;t throwing an error, it was simply returning the HTML code as Plain Text.</p>
<ul>
<li>The AutoMapper code looked good,</li>
<li>The Html.Grid&#60;T&#62; code looked good (it&#8217;d be templated off another page anyway and that page was working),</li>
<li>The view model code looked good.</li>
</ul>
<p>So why was I being greeted with garble junk?</p>
<blockquote>
<p>${Html.Grid(Model.Details) .Attributes(Id =&#62; &#8220;RoutineDetails&#8221;) .Columns(column =&#62; { column.For(c =&#62; this.Button(&#8220;EditDetail&#8221;).Value(&#8220;Edit&#8221;).Id(string.Format(&#8220;edit_{0}&#8221;, c.Id))).DoNotEncode(); column.For(c =&#62; c.Activity.Target.Name).Named(&#8220;Target Area&#8221;); column.For(c =&#62; c.Activity.Name).Named(&#8220;Activity&#8221;); column.For(c =&#62; c.Sets); column.For(c =&#62; c.Weight); column.For(c =&#62; c.Repetitions); column.For(c =&#62; c.Duration); })}</p>
</blockquote>
<p>Html.Grid that is not&#8230; well, at least not properly.</p>
<p>Encoding issue? Maybe. Data issue? Perhaps.</p>
<p>No, the issue was typing too quick and not paying attention.</p>
<div style="font-family:Consolas, Tahoma, Helvetica;background:#242424;color:#e8f3f6;font-size:10pt;">
<p style="margin:0;"><span style="color:#8ac6f2;">public</span> <span style="color:#cae682;">ActionResult</span> New()</p>
<p style="margin:0;">&#160;{</p>
<p style="margin:0;">&#160;&#160; &#160; <span style="color:#8ac6f2;">var</span> viewModel = BuildRoutineNewViewModel(<span style="color:#8ac6f2;">new</span> <span style="color:#cae682;">Routine</span>());</p>
<p style="margin:0;">&#160;&#160; &#160; <span style="color:#8ac6f2;">return</span> View();</p>
<p style="margin:0;">&#160;}</p>
</div>
<p><!--EndFragment--></p>
<p>Yeah, that&#8217;s the problem&#8230; right there.&#160; I&#8217;d forgotten to pass the view model into the View.&#160; Apparently the Html.Grid&#60;T&#62; helper simply panics if the model you&#8217;re reading from is empty or null&#8212;rather than throwing an error.</p>
<p>Oddly enough, this is one of those times I&#8217;d wish the screen would have lit up red.&#160; Lessons learned.</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/mvccontrib">mvccontrib</a>, <a rel="tag" href="http://technorati.com/tag/spark+view+engine">spark+view+engine</a>, <a rel="tag" href="http://technorati.com/tag/asp.net+mvc">asp.net+mvc</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ASP.NET Development Server From 'Here' in PowerShell]]></title>
<link>http://tiredblogger.wordpress.com/2009/09/09/asp-net-development-server-from-here-in-powershell/</link>
<pubDate>Wed, 09 Sep 2009 16:52:21 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/09/09/asp-net-development-server-from-here-in-powershell/</guid>
<description><![CDATA[Long title&hellip; almost longer than the code. I used to have an old registry setting that started ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Long title&#8230; almost longer than the code.</p>
<p>I used to have an old registry setting that started up the ASP.NET Development Server from the current path; however, since I rarely open up Explorer&#8212;and then opening up FireFox was even more painful&#8212;I needed a script.</p>
<p><strong>What does it do?</strong></p>
<p>The script starts up the ASP.NET Development server with a random port (so you can run multiples&#8230;) at your current location.&#160; It then activates your machine&#8217;s <strong><u>DEFAULT BROWSER</u></strong> and browses to the site.&#160; FireFox user?&#160; No problem.&#160; Works like a champ!</p>
<p><strong>The Script (<a href="http://codepaste.net/feftuu" target="_blank">Full Code</a>)</strong></p>
<blockquote>
<p>$path = resolve-path .<br />$rand = New-Object system.random<br />$port = $rand.next(2048,10240)<br />$path_to_devserver = &#8220;C:\\Program Files (x86)\\Common Files\\microsoft shared\\DevServer\\9.0\\Webdev.WebServer.exe&#8221;</p>
<p>&#38; $path_to_devserver /port:$port /path:$path<br />(new-object -com shell.application).ShellExecute(&#8220;http:\\localhost:$port&#8221;)</p>
</blockquote>
<p>The $path_to_devserver can be updated&#8212;depending on 64&#8211;bit vs. 32&#8211;bit machines.&#160; Simple, easy, and to the point.&#160; Now, no more fumbling around to launch a quick web application!</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/powershell">powershell</a>, <a rel="tag" href="http://technorati.com/tag/asp.net">asp.net</a>, <a rel="tag" href="http://technorati.com/tag/scripts">scripts</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Ramping up with PSake]]></title>
<link>http://tiredblogger.wordpress.com/2009/09/08/ramping-up-with-psake/</link>
<pubDate>Tue, 08 Sep 2009 18:15:24 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/09/08/ramping-up-with-psake/</guid>
<description><![CDATA[I&rsquo;ve been tetering back and forth with PSake and my trusty NAnt scripts for quite a while now.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been tetering back and forth with PSake and my trusty NAnt scripts for quite a while now.&#160; For those not familiar with PSake, it&#8217;s build automation that makes you drunk&#8212;but in a good way. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> &#160; You can read James Kovacs&#8217; <a href="http://codebetter.com/blogs/james.kovacs/archive/2008/06/27/introducing-psake.aspx" target="_blank">original post here</a> or check out the <a href="http://code.google.com/p/psake/" target="_blank">repository here</a> for the latest bits.</p>
<p>I originally looked at rake scripts (after exposure working with Fluent NHibernate) as PowerShell is loathed in our organization&#8212;or was.&#160; That mindset is slowly changing (being able to show people how to crank out what was originally scoped at a week in two lines of PowerShell script helps out); so I&#8217;m using PSake as further motivation.</p>
<p>My prior PSake scripts were a bit tame.&#160; Launch msbuild, copy a few files.&#160; With the latest release of xUnit 1.5 hitting the wires over the weekend (and a much needed x86 version for my poor, cranky Oracle libraries), I decided to bite the bullet and dig in to PSake.</p>
<p>I had two goals:</p>
<ol>
<li>Build a reliable framework &#8220;default.ps1&#8221; file that I could drop into almost any project and configure with little or no effort.</li>
<li>Compile, test, and rollout updates from a single PSake command task.</li>
</ol>
<p>I borrowed the basic layout from <a href="http://ayende.com/Blog/archive/2009/08/30/on-psake.aspx" target="_blank">Ayende&#8217;s Rhino Mocks PSake</a>; however, I couldn&#8217;t get msbuild to run correctly simply by calling it. </p>
<p>Here&#8217;s what I ended up with for our internal core library.&#160; The core library, isn&#8217;t so much a &#8220;utilities&#8221; container, but just as it sounds&#8212;the framework all of our applications are built on to keep connections to our various applications (HR, student systems, data warehouses, etc) consistant as well as hold our base FNH conventions.</p>
<p><strong>CODE: </strong><a href="http://codepaste.net/qyerqm" target="_blank"><strong>Full code available on CodePaste.NET</strong></a></p>
<h3>Properties</h3>
<p>The properties area holds all of the configuration for the PSake script.&#160; For me, it&#8217;s common to configure $solution_name, $libraries_to_merge, and $libraries_to_copy.&#160; With our naming standards, the $test_library should be left unchanged.&#160; I also added in the tester information so we could change from XUnit to MBUnit (if Hell froze over or something)).</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">properties { </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span># ****************<span>&#160; </span>CONFIGURE **************** </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$solution_name = <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;Framework&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$test_library = <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;$solution_name.Test.dll&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$libraries_to_merge = <span>&#160;&#160;&#160;&#160; </span>&#8220;antlr3.runtime.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;ajaxcontroltoolkit.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;Castle.DynamicProxy2.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;Castle.Core.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;FluentNHibernate.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;log4net.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;system.linq.dynamic.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;xunit.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;nhibernate.caches.syscache2.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;cssfriendly.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;iesi.collections.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;nhibernate.bytecode.castle.dll&#8221;, `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;oracle.dataaccess.dll&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$libraries_to_copy = <span>&#160;&#160;&#160;&#160;&#160; </span>&#8220;system.data.sqlite.dll&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span><span>&#160;&#160;&#160;&#160; </span>$tester_directory = <span></span>&#8220;j:\shared_libraries\xunit\msbuild&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span><span style="font-family:Consolas;font-size:10pt;" lang="FR">$tester_executable =<span> </span>&#8220;xunit.console.x86.exe&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;" lang="FR"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span><span style="font-family:Consolas;font-size:10pt;">$tools_directory = <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;$tools&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$base_directory<span>&#160; </span>= <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>resolve-path .</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$thirdparty_directory = <span>&#160;&#160; </span>&#8220;$base_directory\thirdparty&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$build_directory = <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;$base_directory\build&#8221; </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$solution_file = <span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;$base_directory\$solution_name.sln&#8221; </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$release_directory = <span>&#160;&#160;&#160;&#160;&#160; </span>&#8220;$base_directory\release&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">} </span></p>
</blockquote>
<p>Clean and easy enough.&#160; You&#8217;ll notice that $libraries_to_merge and $libraries_to_copy are implied string arrays.&#160; That works out well since string arrays end up as params when passed to commands&#8230; and our $libraries_to_copy can be iterated over later in the code.</p>
<h3>Tasks &#8211; Default</h3>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task default -depends Release</span></p>
<p>The default task (if just running &#8216;psake&#8217; without parameters) runs Release.&#160; Easy enough.</p>
<h3>Tasks &#8211; Clean</h3>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Clean { </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>remove-item -force -recurse $build_directory -ErrorAction SilentlyContinue &#124; Out-Null</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>remove-item -force -recurse $release_directory -ErrorAction SilentlyContinue &#124; Out-Null</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">} </span></p>
</blockquote>
<p>Clean up those build and release directories.</p>
<h3>Tasks &#8211; Init</h3>
</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Init -depends Clean { </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160; </span>new-item $release_directory -itemType directory &#124; Out-Null</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160; </span>new-item $build_directory -itemType directory &#124; Out-Null</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160; </span>cp $tester_directory\*.* $build_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">} </span></p>
</blockquote>
<p>Restore those build and release directories that we cleaned up; then copy in our unit testing framework so we can run our tests (if necessary).</p>
<h3>Tasks &#8211; Compile</h3>
</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Compile -depends Init { </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span># from http://poshcode.org/1050 (first lines to get latest versions)</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>[System.Reflection.Assembly]::Load(&#8216;Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&#8217;) &#124; Out-Null</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile(&#8220;msbuild.exe&#8221;, &#8220;VersionLatest&#8221;)</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span># adding double slash for directories with spaces. Stupid MSBuild.</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>&#38;$msbuild /verbosity:minimal /p:Configuration=&#8221;Release&#8221; /p:Platform=&#8221;Any CPU&#8221; /p:OutDir=&#8221;$build_directory&#8221;\\ &#8220;$solution_file&#8221; </span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">} </span></p>
</blockquote>
<p>Compile is a bit tricky.&#160; As noted in the code, I ended up using a SharePoint example from <a href="http://poshcode.org/1050" target="_blank">PoSH code</a>&#160;to get MSBuild to behave.&#160; The standard <strong>exec</strong> methodology provided by PSake kept ignoring my parameters.&#160; Maybe someone has an good reason.. but this works.</p>
<p>You also see that my OutDir has <strong>TWO slashes</strong>.&#160; It seems that directories with spaces require the second.&#160; I&#8217;m sure this will somehow bite me later on, but it seems to be working for now. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><h3>Tasks &#8211; Test</h3>
</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Test -depends Compile {</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>$origin_directory = pwd</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>cd $build_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>exec .\$tester_executable &#8220;$build_directory\$test_library&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160; </span>cd $origin_directory<span>&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">}</span></p>
</blockquote>
<p>I want to thank Ayende&#160;for the idea to dump the origin directory into a parameter&#8212;brilliant.&#160; This&#160;one is pretty&#160;simple&#8212;just calls the tester and&#160;tests.</p>
<p><h3>Tasks &#8211; Merge</h3>
</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Merge {</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>$origin_directory = pwd</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>cd $build_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>remove-item &#8220;$solution_name.merge.dll&#8221; -erroraction SilentlyContinue</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>rename-item &#8220;$solution_name.dll&#8221; &#8220;$solution_name.merge.dll&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>&#38; $tools\ilmerge\ilmerge.exe /out:&#8221;$solution_name.dll&#8221; /t:library /xmldocs /log:&#8221;$solution_name.merge.log&#8221; `</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>&#8220;$solution_name.merge.dll&#8221; $libraries_to_merge</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>if ($lastExitCode -ne 0) {</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </span>throw &#8220;Error: Failed to merge assemblies!&#8221;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>}</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>cd $origin_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">}</span></p>
</blockquote>
<p>Merge calls ILMerge and wraps all of my libraries into one.&#160; Do I need to do this?&#160; Nah, but for the framework, I prefer to keep everything together.&#160; I don&#8217;t want to be chasing mis-versioned libraries around.&#160; Again, since $libraries_to_merge is a string array, it passes each &#8220;string&#8221; as a separate parameter&#8212;which is exactly what ILMerge wants to see.</p>
<p>I also have ILMerge generate and keep a log of&#160;what it did&#8212;just to have.&#160; Since the build directory gets blown away between builds (and isn&#8217;t replicated to source control), then no harm.&#160; Space is mostly free. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><h3>Tasks &#8211; Build &#38; Release</h3>
</p>
<blockquote>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Build -depends Compile, Merge {</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span># When I REALLY don&#8217;t want to test&#8230;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">}</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">&#160;</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">task Release -depends Test, Merge {</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>copy-item $build_directory\$solution_name.dll $release_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>copy-item $build_directory\$solution_name.xml $release_directory</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span># copy libraries that cannot be merged</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span>% { $libraries_to_copy } &#124; %{ copy-item (join-path $build_directory $_) $release_directory }</span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;"><span>&#160;&#160;&#160;&#160;&#160;&#160; </span></span></p>
<p style="margin:0;" class="MsoNoSpacing"><span style="font-family:Consolas;font-size:10pt;">}</span></p>
</blockquote>
<p>Build provides just that&#8212;building with no testing and no copying to the release directory.&#160; This is more for testing out the scripts, but useful in some cases.</p>
<p>Release copies the library and the xml documentation out ot the release directory.&#160; It then iterates through the string array of &#8220;other&#8221; libraries (non-manged code libraries that can&#8217;t be merged, etc) and copies them as well.</p>
</p>
<p>&#160;</p>
<p>&#160;</p>
<p>&#160;</p>
</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/powershell">powershell</a>, <a rel="tag" href="http://technorati.com/tag/msbuild">msbuild</a>, <a rel="tag" href="http://technorati.com/tag/psake">psake</a>, <a rel="tag" href="http://technorati.com/tag/visual+studio">visual+studio</a>, <a rel="tag" href="http://technorati.com/tag/c#">c#</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Could not load the type error "is not marked as serializable"]]></title>
<link>http://bestofcyber.wordpress.com/2009/08/28/could-not-load-the-type-error-is-not-marked-as-serializable/</link>
<pubDate>Fri, 28 Aug 2009 11:34:04 +0000</pubDate>
<dc:creator>Udaya Kumar</dc:creator>
<guid>http://bestofcyber.wordpress.com/2009/08/28/could-not-load-the-type-error-is-not-marked-as-serializable/</guid>
<description><![CDATA[There are various issues which may occur on custom application running under SharePoint ,if the appl]]></description>
<content:encoded><![CDATA[There are various issues which may occur on custom application running under SharePoint ,if the appl]]></content:encoded>
</item>
<item>
<title><![CDATA[Playing with Shaders: Creating a water effect]]></title>
<link>http://marlongrech.wordpress.com/2009/08/27/playing-with-shaders-creating-a-water-effect/</link>
<pubDate>Thu, 27 Aug 2009 15:06:03 +0000</pubDate>
<dc:creator>marlongrech</dc:creator>
<guid>http://marlongrech.wordpress.com/2009/08/27/playing-with-shaders-creating-a-water-effect/</guid>
<description><![CDATA[Lately I’ve been looking at a really cool project on Codeplex for Pixel Shaders. The set of shaders ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Lately I’ve been looking at a really cool project on <a href="http://www.codeplex.com/wpffx" target="_blank">Codeplex for Pixel Shaders</a>. The set of shaders in this library is awsome and really easy to use in you application….</p>
<p>All you need to do to consume any Shader is add a reference to the WPFShaderEffectLibrary class library and you can start using the shaders in XAML.What is really important is that you install the <a href="http://wpf.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=14962#DownloadId=40167" target="_blank">Shaders Build Task</a> before trying to build the shader library (if you just add a reference to the ready build dlls you don’t even need to do this).</p>
<p>&#160;</p>
<p><a href="http://marlongrech.files.wordpress.com/2009/08/water.png"><img style="display:inline;border-width:0;" title="Water" border="0" alt="Water" src="http://marlongrech.files.wordpress.com/2009/08/water_thumb.png?w=644&#038;h=389" width="644" height="389" /></a> </p>
<p>So let’s have a look at how we can use shaders to simulate water on screen.</p>
<p>This is very easy all we need is a ripple shader effect. so something like this </p>
<div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;line-height:12pt;background-color:#f4f4f4;width:97.5%;font-family:&#39;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;margin:20px 0 10px;padding:4px;" id="codeSnippetWrapper">
<div style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> &#60;Window.Resources&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum2">   2:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum3">   3:</span>    &#60;Storyboard x:Key=<span style="color:#006080;">&#34;waterAnimMain&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum4">   4:</span>        &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Phase&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;10&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;Stop&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum5">   5:</span>        &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Amplitude&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;0.6&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum6">   6:</span>        &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Frequency&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;30&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.5&#34;</span> FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum7">   7:</span>    &#60;/Storyboard&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum8">   8:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum9">   9:</span> &#60;/Window.Resources&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum10">  10:</span> &#60;Grid Background=<span style="color:#006080;">&#34;Transparent&#34;</span> &#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum11">  11:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum12">  12:</span>    &#60;Border&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum13">  13:</span>        &#60;Border.Background&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum14">  14:</span>            &#60;LinearGradientBrush EndPoint=<span style="color:#006080;">&#34;0.93,0.925&#34;</span> StartPoint=<span style="color:#006080;">&#34;0.094,0.125&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum15">  15:</span>                &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF272788&#34;</span> Offset=<span style="color:#006080;">&#34;0.112&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum16">  16:</span>                &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF090916&#34;</span> Offset=<span style="color:#006080;">&#34;0.721&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum17">  17:</span>                &#60;GradientStop Color=<span style="color:#006080;">&#34;#FE222267&#34;</span> Offset=<span style="color:#006080;">&#34;0.28&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum18">  18:</span>                &#60;GradientStop Color=<span style="color:#006080;">&#34;#FE131339&#34;</span> Offset=<span style="color:#006080;">&#34;0.453&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum19">  19:</span>                &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF04040A&#34;</span> Offset=<span style="color:#006080;">&#34;0.974&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum20">  20:</span>            &#60;/LinearGradientBrush&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum21">  21:</span>        &#60;/Border.Background&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum22">  22:</span>    </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum23">  23:</span>    &#60;/Border&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum24">  24:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum25">  25:</span> &#60;/Grid&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum26">  26:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum27">  27:</span> &#60;Window.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum28">  28:</span>    &#60;shader:RippleEffect Amplitude=<span style="color:#006080;">&#34;0&#34;</span> Frequency=<span style="color:#006080;">&#34;0&#34;</span> Phase=<span style="color:#006080;">&#34;0&#34;</span> x:Name=<span style="color:#006080;">&#34;rippleMain&#34;</span>  /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum29">  29:</span> &#60;/Window.Effect&#62;</pre>
<p><!--CRLF--></div>
</div>
<p>This is our Shader</p>
<div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;line-height:12pt;background-color:#f4f4f4;width:97.5%;font-family:&#39;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;margin:20px 0 10px;padding:4px;" id="codeSnippetWrapper">
<div style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> &#60;shader:RippleEffect Amplitude=<span style="color:#006080;">&#34;0&#34;</span> Frequency=<span style="color:#006080;">&#34;0&#34;</span> Phase=<span style="color:#006080;">&#34;0&#34;</span> x:Name=<span style="color:#006080;">&#34;rippleMain&#34;</span>  /&#62;</pre>
<p><!--CRLF--></div>
</div>
<p>And we animate this shader like so to make the effect of water</p>
<div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;line-height:12pt;background-color:#f4f4f4;width:97.5%;font-family:&#39;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;margin:20px 0 10px;padding:4px;" id="codeSnippetWrapper">
<div style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> &#60;Storyboard x:Key=<span style="color:#006080;">&#34;waterAnimMain&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum2">   2:</span>      &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Phase&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;10&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;Stop&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum3">   3:</span>      &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Amplitude&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;0.6&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum4">   4:</span>      &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Frequency&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;30&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.5&#34;</span> FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum5">   5:</span>  &#60;/Storyboard&#62;</pre>
<p><!--CRLF--></div>
</div>
<p>We invoke this animation by having a DispatcherTimer trigger the animation every now and then and changing the Center property of the Shader to a random point from 0 to 1.</p>
<p>This already gets us very close but it still does not feel like real water. The trick is to animate to ripple effects at the same time. This will make the ripple effects expand together and thus making the control which has the shader applied look like water. Yet the problem is that you can only apply ONE shader per control. BUT you can have another shader on the parent control and that would still apply the shader on all children (<a href="http://marlongrech.wordpress.com/2008/05/15/effects-in-net-sp1-for-wpf/" target="_blank">I explain this in this article</a>).</p>
<div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;line-height:12pt;background-color:#f4f4f4;width:97.5%;font-family:&#39;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;margin:20px 0 10px;padding:4px;" id="codeSnippetWrapper">
<div style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0;" id="codeSnippet">
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum1">   1:</span> &#60;Window.Resources&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum2">   2:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum3">   3:</span>     &#60;Storyboard x:Key=<span style="color:#006080;">&#34;waterAnimMain&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum4">   4:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Phase&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;10&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;Stop&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum5">   5:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Amplitude&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;0.6&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum6">   6:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleMain&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Frequency&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;30&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.5&#34;</span> FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum7">   7:</span>     &#60;/Storyboard&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum8">   8:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum9">   9:</span>     &#60;Storyboard x:Key=<span style="color:#006080;">&#34;waterAnimSub&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum10">  10:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleSub&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Phase&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;10&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;Stop&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum11">  11:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleSub&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Amplitude&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;0.6&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.0&#34;</span>  FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum12">  12:</span>         &#60;DoubleAnimation Storyboard.TargetName=<span style="color:#006080;">&#34;rippleSub&#34;</span> Storyboard.TargetProperty=<span style="color:#006080;">&#34;Frequency&#34;</span> To=<span style="color:#006080;">&#34;0&#34;</span> From=<span style="color:#006080;">&#34;30&#34;</span> Duration=<span style="color:#006080;">&#34;0:0:2.5&#34;</span> FillBehavior=<span style="color:#006080;">&#34;HoldEnd&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum13">  13:</span>     &#60;/Storyboard&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum14">  14:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum15">  15:</span> &#60;/Window.Resources&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum16">  16:</span> &#60;Grid Background=<span style="color:#006080;">&#34;Transparent&#34;</span> &#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum17">  17:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum18">  18:</span>     &#60;Border&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum19">  19:</span>         &#60;Border.Background&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum20">  20:</span>             &#60;LinearGradientBrush EndPoint=<span style="color:#006080;">&#34;0.93,0.925&#34;</span> StartPoint=<span style="color:#006080;">&#34;0.094,0.125&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum21">  21:</span>                 &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF272788&#34;</span> Offset=<span style="color:#006080;">&#34;0.112&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum22">  22:</span>                 &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF090916&#34;</span> Offset=<span style="color:#006080;">&#34;0.721&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum23">  23:</span>                 &#60;GradientStop Color=<span style="color:#006080;">&#34;#FE222267&#34;</span> Offset=<span style="color:#006080;">&#34;0.28&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum24">  24:</span>                 &#60;GradientStop Color=<span style="color:#006080;">&#34;#FE131339&#34;</span> Offset=<span style="color:#006080;">&#34;0.453&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum25">  25:</span>                 &#60;GradientStop Color=<span style="color:#006080;">&#34;#FF04040A&#34;</span> Offset=<span style="color:#006080;">&#34;0.974&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum26">  26:</span>             &#60;/LinearGradientBrush&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum27">  27:</span>         &#60;/Border.Background&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum28">  28:</span>         &#60;Border.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum29">  29:</span>             &#60;shader:RippleEffect Amplitude=<span style="color:#006080;">&#34;0&#34;</span> Frequency=<span style="color:#006080;">&#34;0&#34;</span> Phase=<span style="color:#006080;">&#34;0&#34;</span> x:Name=<span style="color:#006080;">&#34;ripple&#34;</span> Center=<span style="color:#006080;">&#34;{Binding ElementName=main, Path=(local:MouseBehaviour.LastMouseUp)}&#34;</span> /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum30">  30:</span>         &#60;/Border.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum31">  31:</span>     &#60;/Border&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum32">  32:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum33">  33:</span>     &#60;Grid.Triggers&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum34">  34:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum35">  35:</span>         &#60;EventTrigger RoutedEvent=<span style="color:#006080;">&#34;UIElement.MouseUp&#34;</span>&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum36">  36:</span>             &#60;BeginStoryboard Storyboard=<span style="color:#006080;">&#34;{StaticResource waterAnim}&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum37">  37:</span>             &#60;BeginStoryboard Storyboard=<span style="color:#006080;">&#34;{StaticResource waterAnimMain}&#34;</span>/&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum38">  38:</span>         &#60;/EventTrigger&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum39">  39:</span>     &#60;/Grid.Triggers&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum40">  40:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum41">  41:</span>     &#60;Grid.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum42">  42:</span>         &#60;shader:RippleEffect Amplitude=<span style="color:#006080;">&#34;0&#34;</span> Frequency=<span style="color:#006080;">&#34;0&#34;</span> Phase=<span style="color:#006080;">&#34;0&#34;</span> x:Name=<span style="color:#006080;">&#34;rippleSub&#34;</span>  /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum43">  43:</span>     &#60;/Grid.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum44">  44:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum45">  45:</span> &#60;/Grid&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum46">  46:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum47">  47:</span> &#60;Window.Effect&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:#f4f4f4;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum48">  48:</span>     &#60;shader:RippleEffect Amplitude=<span style="color:#006080;">&#34;0&#34;</span> Frequency=<span style="color:#006080;">&#34;0&#34;</span> Phase=<span style="color:#006080;">&#34;0&#34;</span> x:Name=<span style="color:#006080;">&#34;rippleMain&#34;</span>  /&#62;</pre>
<p><!--CRLF--></p>
<pre style="text-align:left;line-height:12pt;background-color:white;width:100%;font-family:&#39;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;margin:0;padding:0;"><span style="color:#606060;" id="lnum49">  49:</span> &#60;/Window.Effect&#62;</pre>
<p><!--CRLF--></div>
</div>
<p>And that’s it. Now we have a perfect water look thanks to the Codeplex Pixel Shader library <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I created a sample app that shows all this. The app also has another feature so that you can touch the water by using the mouse and the water would ripple from the point you touch (of course this is with Behaviours so that you can even reuse it <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  )</p>
<p>Happy coding <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p><a href="http://cid-96f8d49aa44c79c1.skydrive.live.com/self.aspx/Public/WaterDemo.zip" target="_blank">DOWNLOAD SOURCE CODE</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[A Practical Architecture for WCF – Part 3]]></title>
<link>http://computermutt.wordpress.com/2009/08/26/a-practical-architecture-for-wcf-part-3/</link>
<pubDate>Wed, 26 Aug 2009 20:01:35 +0000</pubDate>
<dc:creator>Mike Malter</dc:creator>
<guid>http://computermutt.wordpress.com/2009/08/26/a-practical-architecture-for-wcf-part-3/</guid>
<description><![CDATA[This is the third article in our WCF practical architecture series.  Part 1 is here, and part 2 is h]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This is the third article in our WCF practical architecture series.  <a title="A Practical Architecture for WCF - Part 1" href="http://computermutt.wordpress.com/2009/08/20/a-practical-architecture-for-wcf-part-1/">Part 1 is here</a>, and <a title="A Practical Architecture for WCF - Part 2" href="http://computermutt.wordpress.com/2009/08/24/a-practical-architecture-for-wcf-part-2/">part 2 is here</a>.</p>
<p>At a certian point, setting up a WCF environment moves you away from programming and more toward networking.  That is what this article is going to cover, how to setup a WCF client on IIS7 using the net.tcp protocol.  We will be crossing machine and domain boundaries and will be suggesting a starting point for a secure environment.</p>
<p>We are going to do  two things in this post</p>
<ol>
<li>Configure your local development machine to host a service in IIS7</li>
<li>Configure a seperate server to host a service in IIS7 and to recieve what you push from your local development machine.</li>
</ol>
<p>First, lets get service hosting done on your local machine so you have something to push to your application server.  Right click on your solution and then Add and then New Web Site.  Then select WCF Service as shown in the image below.  I choose the name CheeseListIISHostedServices.  It&#8217;s important now to pick the name you will be living with because I am recommending that this name not only be the name of your local environment, but the name of the new A record you will create to point to your application server.</p>
<p><img class="aligncenter size-full wp-image-322" title="HostingLocallyCreateIIS" src="http://computermutt.wordpress.com/files/2009/08/hostinglocallycreateiis.png" alt="HostingLocallyCreateIIS" width="670" height="741" /></p>
<p>Then in the AppCode folder delete the IService.cs and Service.cs files as you won&#8217;t need them because you have a seperate service layer.  Next, right click your site and click on Add new ASP.NET folder, then click on Bin.</p>
<p>Change the name of the Service.svc folder to the name of your service.  Since my service is called BrandServices, I renamed it to that.  Then you will want to go into the svc file and change the Service attribute.  Make sure that you include the namespace of your service too.  Look at the image below for how I named my Service attribute in the svc file. </p>
<p><img class="aligncenter size-full wp-image-325" title="RenameSVCFile" src="http://computermutt.wordpress.com/files/2009/08/renamesvcfile1.png" alt="RenameSVCFile" width="670" height="442" /></p>
<p>Notice in the image above that the location has been removed from the original Service.svc.  We will not need this as we are going to establish a reference to the project that contains the services.  To establish a reference, right click on the web site and then click on Add Reference.  Go to the projects tab and then click on the project that has your services.  In this instance for me it is CheeseListServices as shown in the image below.</p>
<p><img class="aligncenter size-full wp-image-327" title="CreateReferences" src="http://computermutt.wordpress.com/files/2009/08/createreferences.png" alt="CreateReferences" width="670" height="747" /></p>
<p>When you click on ok, your Bin folder will get filled up with all of the referenced dll&#8217;s in your service project including your newley created services dll.  Then, after a few more configuration details, you&#8217;ll have something to push out to your real services environment.</p>
<p>The next step is to configure the web.config file.  The two things to remember about the web.config file supporting services.  First it functions as the config file for the modules from the site we are wrapping with services, so all of its settings should be there, and we also have the services section.  Let&#8217;s take a look at the system.serviceModel section in the web.config in the figure below to look at how to configure our service for net.tcp and to be discoverable.</p>
<p><img class="aligncenter size-full wp-image-335" title="WebConfig" src="http://computermutt.wordpress.com/files/2009/08/webconfig.png" alt="WebConfig" width="670" height="548" /></p>
<p>You can copy and past what is here and change the names to fit your names.  In the bindings section we have a netTcp binding tag.  There is more here than is necessary, but this binding section will support transactions and a certian level of security.  So for now just to get this running, this can be copyed and pasted.</p>
<p>In the services section we have three services, but two of them are collapsed because we won&#8217;t need them now, but we will later.  In the service for Brand services we set our binding protocol to net.tcp and we also included a few endpoints.  The mex endpoint is used by the client to generate service metadata. </p>
<p>Since we are not using http but net.tcp as the service protocol, we cannot put the mex endpoint address into a browser and read the file, but we will be using the WCF Test Client to make sure our setup is working.  Normally, I never use the WCF Test Client because I&#8217;ll always have a client around with some sort of functionality to get myself off of the ground.  But I didn&#8217;t want to make you wait until we got done with the client to see if you had set up your services correctly.  So we are using the client here.  This part of the series is pretty long as it is.</p>
<p>Finally in the config is the behavior section.  In the serviceBehaviors tag we have additional information for our service.  You can cut and paste here too making sure that you have your service name correct.</p>
<p>Next, please check to see if your default web site has a net.tcp binding type.  To check it, click on the default web site and then right click and then click on Edit Bindings.  You should see net.tcp for port 808:*.  If you don&#8217;t, click on the add button and add it.  Later on in this post, we go into setting up bindings on IIS7 on Windows Server 2008.  Anyway, when you setup IIS7 on your workstation, all bindings should have been created by default.</p>
<p>Ok, we are getting really close to fireing up our service.  We just have to get the address of our service to feed to the WCF Test Client and then we are good to go.  Here is how to do that.  In IIS7, click on the website that is hosting your services and then in the center pane at the bottom click on Content View.  Then find the svc file for your service, click on it and then click on browse.  You should get something in your browser like the figure below.</p>
<p><img class="aligncenter size-full wp-image-336" title="BrowserBrandServices" src="http://computermutt.wordpress.com/files/2009/08/browserbrandservices.png" alt="BrowserBrandServices" width="670" height="719" /></p>
<p>If you got this, you are really in good shape, that means your site is setup correctly and you do not have any gross errors in your config file.  What you want is the address up close to the top right after svcutil.exe.  Copy and then pull up the WCF Test Client at C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\WcfTestClient.exe.  When you get it up, click on File and then Add Service.  Past the address into the end point address edit box like the figure below. </p>
<p><img class="aligncenter size-full wp-image-337" title="WCFTestClient" src="http://computermutt.wordpress.com/files/2009/08/wcftestclient.png" alt="WCFTestClient" width="670" height="444" /></p>
<p>Then click on OK and after a bit you should see a dialog box appear with a progress bar saying &#8220;Adding&#8221;.  When finished you should see your service under My Service Projects along with the service method.  In the figure below, you can see my ListAll() method.  I clicked on the listAll() method and then got a ListAll panel on the right.  Then I clicked on the Start a new proxy checkbox near the Invoke button and then clicked on the Invoke button and got the result below (click through the security warning).</p>
<p><img class="aligncenter size-full wp-image-339" title="FirstBrandService" src="http://computermutt.wordpress.com/files/2009/08/firstbrandservice.png" alt="FirstBrandService" width="670" height="667" /></p>
<p>The results are the return of the BrandList object from the ListAll() service.  If you click on the XML tab on the bottom, you can see the Request and Response messages.  If you got this far, you are in really good shape.  If not, please post your questions and I&#8217;ll answer them asap.</p>
<p>The next part of this post explains how to create an application server using IIS7 and the net.tcp protocol in your enterprise.</p>
<p>Every enterprise has its own security requirements and what configuration is necessary to meet those requirements.  So, this article is not intended to be then end all and be all of security, however, for traffic within your LAN, it is my opinion that what we are talking about here will be reasonably secure.</p>
<p>Also, as pointed out earlier in this series, we&#8217;re not going into all the options available, but are pointing out one simple and practical approach.  Resources for a more detailed discussion of options are here.</p>
<p>Ok, now on to the client.  WCF services can either self host, or use IIS.  We are going to look at how to host WCF Services with IIS7.  We are also going to be using the net.tcp protocol to do it.  The reason to use net.tcp is that by doing so you can expose your services equally to a web site or to a windows forms application.  You can do it using http or https, but net.tcp is much faster, and although it is a little harder to configure, it is really worth it.</p>
<p>What we are doing here is to setup the service on its own machine and with its own domain.  First thing is to create the DNS domain internally.  The default domain on our network is joyousliving.com and we also use maltercorp.com equally.  The Windows domain name is joyousliving.com.  We also have a number of other domains as we host and do development for clients.  We created a new domain called maltercorplabs.com and are using it for hosting services.  However the windows forms desktop client is on the joyousliving.com domain.  Below is a screenshot of the maltercorplabs.com domain after it was configured with the cheeselistiishostedservices A record.</p>
<p><img class="aligncenter size-full wp-image-310" title="DNSConfiguration" src="http://computermutt.wordpress.com/files/2009/08/dnsconfiguration.png" alt="DNSConfiguration" width="649" height="500" /></p>
<p>The next step is to create the site on IIS7 that will do the hosting.  To that, first you have to add the IP address you want to use for the site into your NIC configuration.  I never use the default web site, and always add additional IP&#8217;s for each website I need.  The screen shot below shows the configuration of the NIC. </p>
<p>To get there you go to Control Panel / Network Connections and click on the NIC you want to configure.  Then click on the properties button and then on the Internet Protocol Version 4 item.  Then click on the advanced button and on the top of the dialog box, you&#8217;ll see IP addresses.  Add the IP there.  Aftering adding the IP, make sure you can ping it from your workstation using the fully qualified domain name you setup in the DNS Manager.  In this case it is CheeseListIISHostingServices.MaltercorpLabs.com.</p>
<p><img class="aligncenter size-full wp-image-314" title="IIS7IPAddress" src="http://computermutt.wordpress.com/files/2009/08/iis7ipaddress.png" alt="IIS7IPAddress" width="565" height="664" /></p>
<p>Next, create the actual site.  My convention is to create a site name that is the same as the A record I created.  Under binding make sure you pick the new IP Address you created and leave the rest to default values.  We are going to go back and change a few things.</p>
<p>After creating the website, create an application pool where the Managed Pibeline Mode is Integrated.  Now comes the fun and controversial part.  I change the identity in the Process Model section from the NetworkService to something else.  That identity is a regular windows login for each application.  Users don&#8217;t know anything about it, it&#8217;s purpose is to be an administrative or application service account.  This account is used as the identity of the website as well as the login to the database.  We use an SSPI login to talk to the database so we don&#8217;t have to embed a login id and password into the web.config.</p>
<p>So, lets talk about this for a bit.  What I want to do as an architect is balance security with maintenance and prevent deployment errors.  So, I have at least three and sometimes 4 environments.  Each environment will have a complete set of machines; database, web and or services.</p>
<ol>
<li>Development</li>
<li>Integrated Unit Test</li>
<li>QA</li>
<li>Production</li>
</ol>
<p>For each application in each environment, I will create a windows login.  In each database I create a database role and then assign the application service account to that role.  Each environment has the same database role, but each environment will have a different application service account.  This makes it very easy to migrate database changes between environments; from dev to IUT to QA and then to production.  I don&#8217;t have to make any manual changes to any script because I am granting permissions on the role in the database. </p>
<p>Then in any web environment where I am using SSPI logins, the identity in the application pool is what is used to login into SQL Server.  Sometimes when moving scripts around, it is possible and likely that you will at one time or another, you will point to a database in the wrong environment.  However having a different application service account for each environment will cause an exception to be thrown and you&#8217;ll know immediately that the name of the server is wrong.</p>
<p>The reason you need to care about the database login for the service is that we are wrapping an existing website&#8217;s dll&#8217;s and they need a way to login to the database.  You could if you wanted create a different application service account to be used by services from the one used by the website.  It does not matter as long as that user gets added to the appropriate database role in the right database and it is the same as the identity in the application pool.</p>
<p>It may seem like a lot of work to create so many users and to do this extra configuration, but you will be glad you did the moment your development process comes under stress.  Its much better to see an immediate error telling you that you tried to get into the wrong database, than to realize that you have been pointing to the wrong database and now your data is screwed up, not to say what will happen with your credibility with the users having to re-enter data and trying to remember what they did.</p>
<p>So, right click on the new application pool and then click on advanced settings and change the name of the Identity to your application service account as shown in the image below.</p>
<p><img class="aligncenter size-full wp-image-318" title="NewIdentity" src="http://computermutt.wordpress.com/files/2009/08/newidentity.png" alt="NewIdentity" width="634" height="1099" /></p>
<p>After changing your site&#8217;s identity, you need to add a binding to support net.tcp.  So, right click on the website that you are going to use to host the service and click on Edit Bindings.  Then click on the Add button, and like the image below shows, select net.tcp from the dropdown and enter a port number followed by an asterick.  I choose 808:*.  then click ok.</p>
<p><img class="aligncenter size-full wp-image-320" title="AddBinding" src="http://computermutt.wordpress.com/files/2009/08/addbinding.png" alt="AddBinding" width="596" height="580" /></p>
<p>Now the website is setup with its own application pool and custom binding and is ready to be published to.  So, lets put our programmer&#8217;s hat back on and open Visual Studio.  We want to change the base address and point to the website we just set up, so change it from localhost.  In my case the new address is net.tcp://CheeseListIISHostedServices.MaltercorpLabs.com/.  Once you are done with the configuration changes, then go ahead and publish to your new server.  You can test it just like you did when you were getting services to run for the first time on your local machine.</p>
<p>Ok, that is it for this part.  There was a lot here, and I know this piece stayed pretty high level.  Remember there are <a title="Highly Recommended WCF Learning Resources" href="http://computermutt.wordpress.com/2009/05/06/highly-recommended-wcf-learning-resources/">WCF Learning Resources here </a>on the Computer Mutt.  Also, if you have any questions, post them and I&#8217;ll answer them ASAP.  Next up we will create a web and windows forms client.  After that we will dive into transactions and then to exception handling.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[A Practical Architecture for WCF - Part 1]]></title>
<link>http://computermutt.wordpress.com/2009/08/20/a-practical-architecture-for-wcf-part-1/</link>
<pubDate>Thu, 20 Aug 2009 20:39:22 +0000</pubDate>
<dc:creator>Mike Malter</dc:creator>
<guid>http://computermutt.wordpress.com/2009/08/20/a-practical-architecture-for-wcf-part-1/</guid>
<description><![CDATA[This is the first in a series of articles designed to provide an example of a practical architecture]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>This is the first in a series of articles designed to provide an example of a practical architecture for WCF in its support of a services oriented architecture.</p>
<p>We are going to look at how you could take an existing web site and wrap its functionality in services to be consumed by either a web site or a windows forms application.  We will show you how to configure your network and servers to offer these services across domains and machine boundaries.  We&#8217;ll also take a look at how to structure data contracts to provide robust objects and lists of objects across the wire with exception reporting.  Finally we&#8217;ll look at how to configure support for distributed transactions and some suggestions for structuring projects to make testing and deployment easier.</p>
<p>There are a few references that I recommend using as you are learning WCF and they are posted <a title="Highly Recommended WCF Learning Resources" href="http://computermutt.wordpress.com/2009/05/06/highly-recommended-wcf-learning-resources/" target="_blank">here on the Computer Mutt</a>.  Those resources will address a wider range of WCF concepts much more in-depth than I will here as this article is focused on providing an approach to a particular problem, and not structured to review all options that are available.  Michelle Leroux&#8217;s introduction in the chapter on working with WCF in Visual Studio 2008 which covers SOA and WCF is total gold, and every time I re-read it I get something out of it.</p>
<p>Ok, let&#8217;s take the first step look at what we have and what we want to wind up with.  We are starting out with a current web site that site is a very simple ASP.NET 3.5 public web application in production that provides a list of cheese brands and cheese types that are made without animal rennet.   It has discreet layers consisting of a data layer, business layer and presentation layer in the form of web pages.  The data layer talks to Microsoft SQL Server 2008 and runs on IIS7 on Windows Server 2008.  Everything is 64 bit and everything is on a single box.  Basically it is simple running website and thus a good candidate for a first step.</p>
<p>Here is a network diagram showing the current architecture of the website we are going to transform:</p>
<p><img class="size-full wp-image-225" title="Current Architecture" src="http://computermutt.wordpress.com/files/2009/08/currentarchitecture.png" alt="Current Architecture" width="670" height="639" /></p>
<p>The diagram below is what the architecture will look like after we transform it.  The differences are that major components are separated by machine boundaries.  The database has its own box, services has its own box, and the web site has its own box.  On the services box we also have the original business and data layers along with IIS.  </p>
<p>Once we transform our original website and began offering services, we are simply serving content to presentation layers both inside and outside of your network allowing you to use either browsers or Windows Forms applications.  In the case of a browser, the user points to a URL to get content, in your Windows Forms application, you can configure an endpoint to point to, either way, desktop configuration and support can be much simpler as a result.</p>
<p>Configuring the environment for services behind the firewall is simpler than offering them over the network, and the scope of this series is for services on the inside of the firewall.  In a subsequent article, I&#8217;ll walk you through the steps necessary to offer secure services over the internet.</p>
<p><img class="alignleft size-full wp-image-233" title="NewArchitecture" src="http://computermutt.wordpress.com/files/2009/08/newarchitecture.png" alt="NewArchitecture" width="670" height="624" /></p>
<p>We are going to use Visual Studio 2008 with .NET 3.5 along with WCF Services Templates to code services.  Development is on a Vista machine.  An aside on Vista first.  I&#8217;ve heard how Vista sucked and to avoid it, however when I switched to developing and supporting ASP.NET apps on Windows Server 2008 &#38; IIS7, I found that using Vista simplified development. </p>
<p>First, Vista uses IIS7 (which is the version on Server 2008) and it understands the web.config files generated by Visual Studio 2008.  I can also configure those web.config files once in one place in the file, unlike developing on XP where you have to configure the same thing in several places in the file.  Yes, UAC blows, but you can turn it off and I have had no problems using it.  I&#8217;m not advocating that you switch from XP if you want to develop services to run on Windows Server 2008, I&#8217;m just passing along that I found with Vista I created a less error prone development environment.</p>
<p>One last word on environment.  While you will be able to do everything in this series of articles on one machine, it will work out better for you in the long run if you have an Active Directory environment with at least three dedicated boxes; Web, Services, Database.  If you have limited equipment, consider creating seperate environments using Hyper-V.  Go to <a title="Cloning Virtual Machines using Hyper-V Without the Pain" href="http://computermutt.wordpress.com/category/hyper-v/" target="_blank">my recent post </a>for help on creating and cloning Hyper-V environments. </p>
<p>I really want to emphasize that it is in your interest to invest the sweat in creating seperate environments to run the examples in this series.  The reason is that a lot happens by default when you run everything on a single box and you&#8217;ll never realize it until you begin to move things around, and by then you&#8217;ll have to spend an undetermined amount of time to backtrack to uncover your mistakes.  Also, nobody is really going to be running this stuff on a single machine in a production environment anyway, so you might as well get used to it right off of the bat.  If you understand what the network requires to support WCF you&#8217;ll be more valuable to your company and customers.  </p>
<p>Before finishing this introduction, some thoughts on the Web Client Software Factory (WCSF).  This tool will allow you to code WCF services using a visual designer in Visual Studio.   One of its strengths is that it forces a particular format on project directory structure which can be advantagous since everyone on the team will be forced to structure their work the same way.   I began working in WCF using this tool, and I have to say it was a very confusing time for me as took a lot of effort to understand where the tool left off and WCF began; it was unnecessairly complex.</p>
<p>Furtheremore, once you start a project in the tool and need to make changes, you must go back and make them through the designer.  There are some other very severe side effects to.  One is that the tool will create directory and filenames that will break Visual Studio and this goes double if you are using Team Foundation Server.  Having outlined some of my concerns, you have to that creating such a tool is a huge accomplishment, and although this tool is just in its beginning stages, over time I am certian refinements will be introduced smoothing out some of its early difficulties.</p>
<p>In my mind it is best to start out simply and do everything manually so you get a clear understanding of what you need to do to support WCF services.</p>
<p>Next up &#8211; <a title="A Practical Architecture for WCF - Part 2" href="http://computermutt.wordpress.com/2009/08/24/a-practical-architecture-for-wcf-part-2/">A Practical Architecture for WCF &#8211; Part 2</a> which will demonstrate the creation of services.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Want Open Search Integration in Your Website&hellip;?]]></title>
<link>http://ducas.wordpress.com/2009/08/06/want-open-search-integration-in-your-website/</link>
<pubDate>Wed, 05 Aug 2009 22:42:37 +0000</pubDate>
<dc:creator>ducas</dc:creator>
<guid>http://ducas.wordpress.com/2009/08/06/want-open-search-integration-in-your-website/</guid>
<description><![CDATA[Over the past few weeks, Tatham Oddie, Damian Edwards and myself have been working on publishing a f]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Over the past few weeks, <a href="http://blog.tatham.oddie.com.au/">Tatham Oddie</a>, <a href="http://damianedwards.wordpress.com/">Damian Edwards</a> and myself have been working on publishing a framework/toolkit for integration OpenSearch into any ASP.NET search enabled website. I’m pleased to announce we have finally hit a release!</p>
<p>The project is available at <a href="http://opensearchtoolkit.codeplex.com">opensearchtoolkit.codeplex.com</a>. Tatham has a great post on how to integrate it into your site on <a href="http://blog.tatham.oddie.com.au/2009/07/19/announcing-opensearch-on-asp-net-made-super-easy-with-the-opensearch-toolkit/">his blog</a>…</p>
<blockquote><p>OpenSearch is a technology that already has widespread support across the web and is now getting even more relevant with Internet Explorer 8’s Visual Search feature and the Federated Search feature in the upcoming Windows 7 release.</p>
<p>…</p>
<p>Now it’s time to make it even easier. <a href="http://ducas.wordpress.com/">Ducas Francis</a>, one of the other members of my team, took on the job of building out our JSON feed for Firefox as well as our RSS feed for Windows 7 Federated Search. More formats, more fiddly serialization code. Following this, he started <a href="http://opensearchtoolkit.codeplex.com/">the OpenSearch Toolkit</a>; an open source, drop-in toolkit for ASP.NET developers to use when they want to offer OpenSearch.</p>
<p>Today marks our first release.</p></blockquote>
<p>So get on over to codeplex, hit up Tatham’s blog for instructions and drop the toolkit into your web site so you can take advantage of all the coolness that is OpenSearch.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Using RedGate ANTS to Profile XUnit Tests]]></title>
<link>http://tiredblogger.wordpress.com/2009/08/05/using-redgate-ants-to-profile-xunit-tests/</link>
<pubDate>Wed, 05 Aug 2009 16:29:22 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/08/05/using-redgate-ants-to-profile-xunit-tests/</guid>
<description><![CDATA[RedGate&rsquo;s ANTS Performance and Memory profilers can do some pretty slick testing, so why not a]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>RedGate&#8217;s ANTS Performance and Memory profilers can do some pretty slick testing, so why not automate it?&#160; The &#8220;theory&#8221; is that if my coverage is hitting all the high points, I&#8217;m profiling all the high points and can see bottlenecks.</p>
<p>So, how does this work?&#160; Since the tests are in a compiled library, I can&#8217;t just &#8220;load&#8221; the unit tests. However, you can load Xunit and run the tests.</p>
<p><strong>NOTE:</strong> If your profiling x86 libraries on an x64 machine, you&#8217;ll need XUnit 1.5 CTP (or later) that includes <em>xunit.console.x86.exe</em>.&#160; If you&#8217;re on an x86 or do not call x86 libraries, pay no attention to this notice. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>To begin, start up ANTS Performance Profiler&#160;and Profile a New <em>.NET Executable</em>.</p>
<p><img border="2" hspace="5" alt="XUnit ala ANTS Profiler" vspace="5" src="http://photos.tiredstudent.com/WebStorageHandler.ashx?tb=false&#38;id=550" /></p>
<p>For the .NET Executable, point it towards XUnit and in the Arguments, point it towards the library you are testing.&#160; Simple enough.</p>
<p>Click &#8220;Start Profiling&#8221; and let the profiling begin!</p>
<p>Now if I could just get the &#8220;top 10&#8221; methods to export to HTML or something so I could automate this in our reporting.</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/ANTS+Profiler">ANTS+Profiler</a>, <a rel="tag" href="http://technorati.com/tag/RedGate">RedGate</a>, <a rel="tag" href="http://technorati.com/tag/xunit">xunit</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[CSS Goodies in IE 8 ]]></title>
<link>http://bestofcyber.wordpress.com/2009/07/31/css-goodies-in-ie-8/</link>
<pubDate>Fri, 31 Jul 2009 05:51:39 +0000</pubDate>
<dc:creator>Udaya Kumar</dc:creator>
<guid>http://bestofcyber.wordpress.com/2009/07/31/css-goodies-in-ie-8/</guid>
<description><![CDATA[Microsoft has made plenty of changes and additions to IE8 which is fully compliant with the CSS Leve]]></description>
<content:encoded><![CDATA[Microsoft has made plenty of changes and additions to IE8 which is fully compliant with the CSS Leve]]></content:encoded>
</item>
<item>
<title><![CDATA[Fetching Nested Group Memberships in Active Directory]]></title>
<link>http://tiredblogger.wordpress.com/2009/07/22/fetching-nested-group-memberships-in-active-directory/</link>
<pubDate>Wed, 22 Jul 2009 14:47:14 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/07/22/fetching-nested-group-memberships-in-active-directory/</guid>
<description><![CDATA[As we&rsquo;ve started using Active Directory more and more to provide single sign-on services for o]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>As we&#8217;ve started using Active Directory more and more to provide single sign-on services for our web applications, group memberships have become more important.</p>
<p>We recently rolled out an application that took advantage of nesting groups (easier to add and manage five global groups than 10,000 individuals); however, our existing code to fetch memberships wouldn&#8217;t look at nested groups.</p>
<p>So if I was a member of &#8220;Student Achievement&#8221;, how could I parse the memberships of that group and determine if I was in &#8220;MIS&#8221;?</p>
<p>Thankfully, a bit of recursion does the trick&#8230; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>As our infrastructure is entirely Windows Server 2003 and higher, I use the&#160;<a href="http://msdn.microsoft.com/en-us/library/system.directoryservices.protocols.aspx" target="_blank">System.DirectoryServices.Protocols </a>namespace and methods to connect to and parse out information from LDAP.&#160; Because of this, I rely on SearchResult(s) rather than DirectoryEntries.&#160; </p>
<p>In our environment, a &#8220;user&#8221; is defined as:</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="background:#820000;color:white;">&#8220;(&#38;(objectCategory=person)(objectClass=user)(mail=*)({0}={1}))&#8221;</span></p>
</div>
<p><!--EndFragment--></p>
<p>Everything looks pretty plain except we require that a valid &#8220;user&#8221; have an email address.&#160; That ensures we filter out junk/test accounts as only employees have Exchange accounts.</p>
<p>Groups are even easier:</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="background:#820000;color:white;">&#8220;(objectCategory=group)&#8221;</span></p>
</div>
<p><!--EndFragment--></p>
<p>If, say I&#8217;ve queried for a single user, the groups property is populated simply by looking at the local user&#8217;s &#8220;memberOf&#8221; attribute.</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="color:#8080c0;">private</span> <span style="color:#8080c0;">static</span> <span style="color:#2b91af;">IEnumerable</span>&#60;<span style="color:#8080c0;">string</span>&#62; <span style="color:#fef1a9;">ParseGroupMemberships</span>(<span style="color:#c7c7f1;">SearchResultEntry</span> <span style="color:#fef1a9;">result</span>, <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">countOfGroups</span>)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">i</span> = 0; <span style="color:#fef1a9;">i</span> &#60; <span style="color:#fef1a9;">countOfGroups</span>; <span style="color:#fef1a9;">i</span>++)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">fullGroupName</span> = (<span style="color:#8080c0;">string</span>) <span style="color:#fef1a9;">result</span>.<span style="color:#fef1a9;">Attributes</span>[<span style="background:#820000;color:white;">"memberOf"</span>][<span style="color:#fef1a9;">i</span>];</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#cc7515;">//Fully Qualified Distinguished Name looks like:</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#cc7515;">//CN={GroupName},OU={AnOU},DC={domain},DC={suffix}</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#cc7515;">//CN=DCI,OU=Groups,OU=Data Center,DC=usd259,DC=net</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">startGroupName</span> = <span style="color:#fef1a9;">fullGroupName</span>.<span style="color:#fef1a9;">IndexOf</span>(<span style="background:#820000;color:white;">&#8220;=&#8221;</span>, 1);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">endGroupName</span> = <span style="color:#fef1a9;">fullGroupName</span>.<span style="color:#fef1a9;">IndexOf</span>(<span style="background:#820000;color:white;">&#8220;,&#8221;</span>, 1);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (<span style="color:#fef1a9;">startGroupName</span> != -1)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">string</span> <span style="color:#fef1a9;">friendlyName</span> =</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">fullGroupName</span>.<span style="color:#fef1a9;">Substring</span>(<span style="color:#fef1a9;">startGroupName</span> + 1, (<span style="color:#fef1a9;">endGroupName</span> &#8211; <span style="color:#fef1a9;">startGroupName</span>) &#8211; 1);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">yield</span> <span style="color:#8080c0;">return</span> <span style="color:#fef1a9;">friendlyName</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>That was fine for the primary groups (attached through memberOf); however, it didn&#8217;t look at the groups those groups were a &#8220;memberOf&#8221;. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>After quite a bit of trial and error, the new method looks pretty ugly, but seems to be quite performant and reliant in tests.&#160;</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;"><span style="color:#8080c0;"></p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="color:#8080c0;">private</span> <span style="color:#8080c0;">static</span> <span style="color:#2b91af;">IEnumerable</span>&#60;<span style="color:#8080c0;">string</span>&#62; <span style="color:#fef1a9;">ParseGroupMemberships</span>(</p>
<p style="margin:0;">&#160; &#160; <span style="color:#c7c7f1;">SearchResultEntry</span> <span style="color:#fef1a9;">result</span>, <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">countOfGroups</span>)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">primaryGroups</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">List</span>&#60;<span style="color:#8080c0;">string</span>&#62;(<span style="color:#fef1a9;">countOfGroups</span>);</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">allGroups</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">List</span>&#60;<span style="color:#8080c0;">string</span>&#62;();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">index</span> = 0; <span style="color:#fef1a9;">index</span> &#60; <span style="color:#fef1a9;">countOfGroups</span>; <span style="color:#fef1a9;">index</span>++)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">result</span>.<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>][<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>());</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">result</span>.<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>][<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>());</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">connection</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">ActiveDirectory</span>().<span style="color:#fef1a9;">GetConnection</span>();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">while</span> (0 &#60; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Count</span>)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">searchRequest</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">SearchRequest</span>(<span style="color:#fef1a9;">distinguishedName</span>,</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">CreateFilterFromGroups</span>(<span style="color:#fef1a9;">primaryGroups</span>),</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#2b91af;">SearchScope</span>.<span style="color:#fef1a9;">Subtree</span>,</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">ldapGroupsAttribute</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Clear</span>();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">response</span> = (<span style="color:#c7c7f1;">SearchResponse</span>)<span style="color:#fef1a9;">connection</span>.<span style="color:#fef1a9;">SendRequest</span>(<span style="color:#fef1a9;">searchRequest</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (<span style="color:#fef1a9;">response</span> != <span style="color:#8080c0;">null</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">entriesCount</span> = <span style="color:#fef1a9;">response</span>.<span style="color:#fef1a9;">Entries</span>.<span style="color:#fef1a9;">Count</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">entry</span> = 0; <span style="color:#fef1a9;">entry</span> &#60; <span style="color:#fef1a9;">entriesCount</span>; <span style="color:#fef1a9;">entry</span>++)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#c7c7f1;">DirectoryAttribute</span> <span style="color:#fef1a9;">groupList</span> = </p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">response</span>.<span style="color:#fef1a9;">Entries</span>[<span style="color:#fef1a9;">entry</span>].<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>];</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (<span style="color:#fef1a9;">groupList</span> != <span style="color:#8080c0;">null</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">groupCount</span> = <span style="color:#fef1a9;">groupList</span>.<span style="color:#fef1a9;">Count</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">index</span> = 0; <span style="color:#fef1a9;">index</span> &#60; <span style="color:#fef1a9;">groupCount</span>; <span style="color:#fef1a9;">index</span>++)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">string</span> <span style="color:#fef1a9;">dn</span> = <span style="color:#fef1a9;">groupList</span>[<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (!<span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Contains</span>(<span style="color:#fef1a9;">dn</span>))</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">connection</span>.<span style="color:#fef1a9;">Dispose</span>();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">string</span> <span style="color:#fef1a9;">dn</span> <span style="color:#8080c0;">in</span> <span style="color:#fef1a9;">allGroups</span>)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">yield</span> <span style="color:#8080c0;">return</span> <span style="color:#fef1a9;">GetFriendlyName</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></span></div>
<p><!--EndFragment--></p>
<p>Here&#8217;s a breakdown of the highlights:</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">primaryGroups</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">List</span>&#60;<span style="color:#8080c0;">string</span>&#62;(<span style="color:#fef1a9;">countOfGroups</span>);</p>
<p style="margin:0;"><span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">allGroups</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">List</span>&#60;<span style="color:#8080c0;">string</span>&#62;();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;"><span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">index</span> = 0; <span style="color:#fef1a9;">index</span> &#60; <span style="color:#fef1a9;">countOfGroups</span>; <span style="color:#fef1a9;">index</span>++)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">result</span>.<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>][<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>());</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">result</span>.<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>][<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>());</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>This section takes the SearchResultEntry&#8217;s primary groups and adds each one of them to two lists.</p>
<ul>
<li>The &#8216;primaryGroups&#8217; list is exactly that&#8212;here&#8217;s a list of groups that we need to iterate over and find the nested groups.&#160; </li>
<li>The &#8216;allGroups&#8217; will hold our master list of every unique group and will provide our return value.</li>
</ul>
<p><span style="color:#8080c0;"></p>
<p style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;margin:0;"><span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">searchRequest</span> = <span style="color:#8080c0;">new</span> <span style="color:#c7c7f1;">SearchRequest</span>(<span style="color:#fef1a9;">distinguishedName</span>,</p>
<p style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">CreateFilterFromGroups</span>(<span style="color:#fef1a9;">primaryGroups</span>),</p>
<p style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#2b91af;">SearchScope</span>.<span style="color:#fef1a9;">Subtree</span>,</p>
<p style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">ldapGroupsAttribute</span>);</p>
<p style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;margin:0;"><span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Clear</span>();</p>
<p></span></p>
<p>This code formulates our LDAP search request.&#160;distinguishedName and ldapGroupsAttribute are two constants in my code base (for our domain&#8217;s DN and &#8220;memberOf&#8221;).&#160; CreateFilterFromGroups takes the list of groups and concats them together&#8212;so we&#8217;re only looking at the groups we want, not everything.</p>
<p>Finally, we&#8217;re reusing our primaryGroups list to look for nested within nested&#8230; within nested, so clear that out&#8212;infinite loops hinder performance. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">entriesCount</span> = <span style="color:#fef1a9;">response</span>.<span style="color:#fef1a9;">Entries</span>.<span style="color:#fef1a9;">Count</span>;</p>
<p style="margin:0;"><span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">entry</span> = 0; <span style="color:#fef1a9;">entry</span> &#60; <span style="color:#fef1a9;">entriesCount</span>; <span style="color:#fef1a9;">entry</span>++)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#c7c7f1;">DirectoryAttribute</span> <span style="color:#fef1a9;">groupList</span> = </p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#fef1a9;">response</span>.<span style="color:#fef1a9;">Entries</span>[<span style="color:#fef1a9;">entry</span>].<span style="color:#fef1a9;">Attributes</span>[<span style="color:#fef1a9;">ldapGroupsAttribute</span>];</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">if</span> (<span style="color:#fef1a9;">groupList</span> != <span style="color:#8080c0;">null</span>)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">groupCount</span> = <span style="color:#fef1a9;">groupList</span>.<span style="color:#fef1a9;">Count</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">for</span> (<span style="color:#8080c0;">int</span> <span style="color:#fef1a9;">index</span> = 0; <span style="color:#fef1a9;">index</span> &#60; <span style="color:#fef1a9;">groupCount</span>; <span style="color:#fef1a9;">index</span>++)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">string</span> <span style="color:#fef1a9;">dn</span> = <span style="color:#fef1a9;">groupList</span>[<span style="color:#fef1a9;">index</span>].<span style="color:#fef1a9;">ToString</span>();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (!<span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Contains</span>(<span style="color:#fef1a9;">dn</span>))</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">allGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">primaryGroups</span>.<span style="color:#fef1a9;">Add</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Here&#8217;s our massive, disgusting block of if statements that populate the lists and keep the where statement running as long as primaryGroups returns a count &#62; 0.</p>
<div style="font-family:Inconsolata, Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:10pt;">
<p style="margin:0;"><span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">string</span> <span style="color:#fef1a9;">dn</span> <span style="color:#8080c0;">in</span> <span style="color:#fef1a9;">allGroups</span>)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">yield</span> <span style="color:#8080c0;">return</span> <span style="color:#fef1a9;">GetFriendlyName</span>(<span style="color:#fef1a9;">dn</span>);</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Finally, use a helper method to convert the DN to a &#8220;friendly name&#8221; and return it to the caller (using yield since our method returns an IEnumerable&#60;string&#62;).</p>
<p>Running a quick test gives me:</p>
<blockquote>
<h2 class="ok"><font size="1">UserAccount_Can_Get_Group_Memberships_With_Default_Security : Passed</font></h2>
<div class="node">
<div class="output"><font size="1">Group&#160;count&#160;for&#160;David&#160;Longnecker&#160;is&#160;138<br />Elapsed&#160;time&#160;for&#160;first&#160;query:&#160;00:00:00.0420000</font></div>
</div>
</blockquote>
<p>Wow, I&#8217;m in a lot of groups&#8230; O_o.&#160;The query is relatively quick (that is with connection buildup and teardown time and generating the rest of the attributes of the user) especially considering our AD infrastructure is far from&#160;optimal. </p>
<p>In addition,&#160;a LDAP query using <a href="http://technet.microsoft.com/en-us/library/aa997340%28EXCHG.65%29.aspx" target="_blank">ADUC</a>&#160;gives the same results.&#160; </p>
<p>If nothing else, its consistent! <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; </p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/c#">c#</a>, <a rel="tag" href="http://technorati.com/tag/.net+3.5">.net+3.5</a>, <a rel="tag" href="http://technorati.com/tag/active+directory">active+directory</a>, <a rel="tag" href="http://technorati.com/tag/group+membership">group+membership</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Filtering an Enum by Attribute]]></title>
<link>http://tiredblogger.wordpress.com/2009/07/09/filtering-an-enum-by-attribute/</link>
<pubDate>Thu, 09 Jul 2009 16:59:08 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/07/09/filtering-an-enum-by-attribute/</guid>
<description><![CDATA[I had a curve ball thrown at me this morning&mdash;changing requirements.&nbsp; It happens and was e]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I had a curve ball thrown at me this morning&#8212;changing requirements.&#160; It happens and was easily solved by a couple of custom attributes and a helper method.</p>
<p><font color="#ff0000"><strong>UPDATE: </strong>I&#8217;ve updated the code (and explaination) for FilterEnumWithAttributeOf below to tidy it up a bit.</font></p>
<p>In our current project,&#160;there is an enum of standard, static&#160;&#8220;periods&#8221; (times of days students are in school).&#160; Easy enough.</p>
<blockquote>
<p>BeforeSchool = 0,<br />FirstPeriod = 1,<br />SecondPeriod&#160;= 2,<br />etc.</p>
</blockquote>
<p>But what happens if we want to &#8220;query&#8221; our list down a bit&#8230; say a certain group only wanted a subset of the &#8220;periods&#8221;.</p>
<p>I could create an entirely different Enum &#8212; Group1Period and Group2Period.</p>
<p>But then handling things in FluentNHibernate&#8217;s automapping would get&#160;freaked out with the Period property.</p>
<p>So, what about a custom attribute?</p>
<ol>
<li>I can assign multiple custom attributes to the same Enum field so I can be in Group1 and Group2 at the same time.</li>
<li>I can keep the same Enum &#8220;Period&#8221; for my ORM layer.</li>
<li>Now how do I query it down&#8230;?</li>
</ol>
<p>Here&#8217;s an abstracted example of how the enum looks right now:</p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;">
<p style="margin:0;"><span style="color:#8080c0;">public</span> <span style="color:#8080c0;">enum</span> <span style="color:#2b91af;">Period</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; [<span style="color:#c7c7f1;">Elementary</span>][<span style="color:#c7c7f1;">Secondary</span>]</p>
<p style="margin:0;">&#160; &#160; [<span style="color:#c7c7f1;">Description</span>(<span style="background:#820000;color:white;">"Before School"</span>)]</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">BeforeSchool</span> = 0,</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; [<span style="color:#c7c7f1;">Elementary</span>]</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">Homeroom</span> = 12,</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; [<span style="color:#c7c7f1;">Secondary</span>]</p>
<p style="margin:0;">&#160; &#160; [<span style="color:#c7c7f1;">Description</span>(<span style="background:#820000;color:white;">"1st"</span>)]</p>
<p style="margin:0;">&#160; &#160; <span style="color:#fef1a9;">First</span> = 1,</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Elementary and Secondary (our two groups, in this case) are &#8220;logicless&#8221; attributes (I&#8217;m just looking at them as flags, not passing/storing information).</p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;">
<p style="margin:0;">[<span style="color:#c7c7f1;">AttributeUsage</span>(<span style="color:#2b91af;">AttributeTargets</span>.<span style="color:#fef1a9;">Field</span>)]</p>
<p style="margin:0;"><span style="color:#8080c0;">public</span> <span style="color:#8080c0;">class</span> <span style="color:#c7c7f1;">ElementaryAttribute</span> : <span style="color:#c7c7f1;">Attribute</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">}</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">[<span style="color:#c7c7f1;">AttributeUsage</span>(<span style="color:#2b91af;">AttributeTargets</span>.<span style="color:#fef1a9;">Field</span>)]</p>
<p style="margin:0;"><span style="color:#8080c0;">public</span> <span style="color:#8080c0;">class</span> <span style="color:#c7c7f1;">SecondaryAttribute</span> : <span style="color:#c7c7f1;">Attribute</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Now, to filter out those pesky periods based on the attributes.</p>
<p><strong><font color="#ff0000">Update: </font></strong></p>
<p><strong><font color="#ff0000">Old Code!</font></strong></p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;"><span style="color:#8080c0;"></p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;"><span style="color:#8080c0;"></p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;">
<p style="margin:0;"><span style="color:#8080c0;">public</span> <span style="color:#2b91af;">IEnumerable</span>&#60;<span style="color:#fef1a9;">TEnum</span>&#62; <span style="color:#fef1a9;">FilterEnumWithAttributeOf</span>&#60;<span style="color:#fef1a9;">TEnum</span>, <span style="color:#fef1a9;">TAttribute</span>&#62;()</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">field</span> <span style="color:#8080c0;">in</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">typeof</span> (<span style="color:#fef1a9;">TEnum</span>).<span style="color:#fef1a9;">GetFields</span>(<span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">GetField</span> &#124;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; <span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">Public</span> &#124;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; <span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">Static</span>))</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">attribute</span> <span style="color:#8080c0;">in</span> </p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#fef1a9;">field</span>.<span style="color:#fef1a9;">GetCustomAttributes</span>(<span style="color:#8080c0;">typeof</span> (<span style="color:#fef1a9;">TAttribute</span>), <span style="color:#8080c0;">false</span>))</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">yield</span> <span style="color:#8080c0;">return</span> (<span style="color:#fef1a9;">TEnum</span>) <span style="color:#fef1a9;">field</span>.<span style="color:#fef1a9;">GetValue</span>(<span style="color:#8080c0;">null</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}<font color="#e0e0e0"></font></p>
</div>
<p><!--EndFragment--></span></div>
<p><!--EndFragment--></span></div>
<p><!--EndFragment--></p>
<p><strong><font color="#ff0000">New Code!</font></strong></p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;">
<p style="margin:0;"><span style="color:#8080c0;">public</span> <span style="color:#8080c0;">static</span> <span style="color:#2b91af;">IEnumerable</span>&#60;<span style="color:#fef1a9;">TEnum</span>&#62; <span style="color:#fef1a9;">FilterEnumWithAttributeOf</span>&#60;<span style="color:#fef1a9;">TEnum</span>, <span style="color:#fef1a9;">TAttribute</span>&#62;()</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">where</span> <span style="color:#fef1a9;">TEnum</span> : <span style="color:#8080c0;">struct</span></p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">where</span> <span style="color:#fef1a9;">TAttribute</span> : <span style="color:#8080c0;">class</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">field</span> <span style="color:#8080c0;">in</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">typeof</span>(<span style="color:#fef1a9;">TEnum</span>).<span style="color:#fef1a9;">GetFields</span>(<span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">GetField</span> &#124;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; <span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">Public</span> &#124;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; <span style="color:#2b91af;">BindingFlags</span>.<span style="color:#fef1a9;">Static</span>))</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#8080c0;">if</span> (<span style="color:#fef1a9;">field</span>.<span style="color:#fef1a9;">GetCustomAttributes</span>(<span style="color:#8080c0;">typeof</span>(<span style="color:#fef1a9;">TAttribute</span>), <span style="color:#8080c0;">false</span>).<span style="color:#fef1a9;">Length</span> &#62; 0)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#8080c0;">yield</span> <span style="color:#8080c0;">return</span> (<span style="color:#fef1a9;">TEnum</span>)<span style="color:#fef1a9;">field</span>.<span style="color:#fef1a9;">GetValue</span>(<span style="color:#8080c0;">null</span>);</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">} </p>
</div>
<p><strong><font color="#ff0000">Why new code?</font></strong></p>
<p><font color="#ff0000">Well, after looking over the code, I don&#8217;t need to iterate through each attribute, simply see if the field contains it (Length &#62; 0).&#160; If it does, then return it.&#160; That cuts a loop out of our code and performs the same function.&#160; I also added two generic constraints.&#160; You can&#8217;t constrain by Enum, but struct works well.</font></p>
<p>I&#8217;m passing in two generics in this case&#8212;TEnum, which is the type of the of the Enum and TAttribute.. the type of the attribute.&#160; Yeah, I realize that my creativity of naming is pretty low.&#160; Work with me here, alright? <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Past that, the loops are pretty easy.</p>
<ol>
<li>Loop through each field of the enumeration.&#160; Return the field (GetField) and be sure to check Public and Static fields.</li>
<li><font color="#ff0000"><strike>Loop through each custom attribute on each field (returned by GetField) and only return the fields that match the type of our attribute.&#160; I pass along the false parameter (do not inherit) because I&#8217;m not interested in inherited attributes.&#160;You could leave this as true. YMMV</strike></font>.</li>
<li>If the field&#8217;s attribute&#8217;s contains our type, yield out the actual Enum value (a string of the field isn&#8217;t as useful).</li>
</ol>
<p>Now, for using it&#8230;</p>
<div style="font-family:Monaco, Consolas;background:#181818;color:#e0e0e0;font-size:8pt;">
<p style="margin:0;"><span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">enums</span> = <span style="color:#fef1a9;">FilterEnumWithAttributeOf</span>&#60;<span style="color:#2b91af;">Period</span>, <span style="color:#c7c7f1;">ElementaryAttribute</span>&#62;();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;"><span style="color:#8080c0;">foreach</span> (<span style="color:#8080c0;">var</span> <span style="color:#fef1a9;">period</span> <span style="color:#8080c0;">in</span> <span style="color:#fef1a9;">enums</span>)</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#c7c7f1;">Console</span>.<span style="color:#fef1a9;">WriteLine</span>(<span style="background:#820000;color:white;">&#8220;{0}, {1}&#8221;</span>.<span style="color:#fef1a9;">AsFormatFor</span>(<span style="color:#fef1a9;">period</span>, (<span style="color:#8080c0;">int</span>)<span style="color:#fef1a9;">period</span>));</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Easy enough.&#160; ElementaryAttribute returns:</p>
<blockquote>
<p>BeforeSchool,&#160;0<br />Homeroom,&#160;12<br />AfterSchool,&#160;10<br />etc..</p>
</blockquote>
<p dir="ltr">Running the same code, but asking for SecondaryAttribute returns:</p>
<blockquote>
<p dir="ltr">BeforeSchool,&#160;0<br />First,&#160;1<br />Second,&#160;2<br />etc..</p>
</blockquote>
<p dir="ltr">Sweet.</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/enum">enum</a>, <a rel="tag" href="http://technorati.com/tag/c#">c#</a>, <a rel="tag" href="http://technorati.com/tag/generics">generics</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[AutoMappings in NHibernate - A Quick Runthrough]]></title>
<link>http://tiredblogger.wordpress.com/2009/06/26/automappings-in-nhibernate-a-quick-runthrough/</link>
<pubDate>Fri, 26 Jun 2009 19:58:00 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/06/26/automappings-in-nhibernate-a-quick-runthrough/</guid>
<description><![CDATA[For most of my projects, at least since I&rsquo;ve moved to NHibernate/Fluent NHibernate, I&rsquo;ve]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>For most of my projects, at least since I&#8217;ve moved to NHibernate/Fluent NHibernate, I&#8217;ve been trapped using the existing data structures of prior iterations.&#160; Funky naming conventions (many due to cross-cultural, international column naming), missing data relationships, and general craziness.</p>
<p>Having used Fluent Mappings (creating a class that implements ClassMap&#60;objectType&#62;)&#160;in the past, they were a huge jump up from writing painful data objects, connecting them together, and recreating the wheel with &#8220;SELECT {column} from {table}&#8221; code.&#160; Create a map, use the fluent methods to match column to property, and away you go.</p>
<p>In a recent project, I&#8217;ve had the opportunity to build a new system from the ground up.&#160; With this, I decided to dive head first into using the AutoMappings functionality of Fluent NHibernate.&#160; </p>
<p><em>This post is somewhat a rambling self-discussion of my explorations with AutoMappings.</em></p>
<p><strong><u>What are AutoMappings?</u></strong></p>
<p>The FluentNHibernate wiki provides a simple <a href="http://is.gd/1eJeG" target="_blank">definition</a>:</p>
<blockquote>
<p>[&#8230;] which is a mechanism for automatically mapping all your entities based on a set of conventions.</p>
</blockquote>
<p dir="ltr">Rather than hand-mapping each column to a property, we create conventions (rules) to map those.. automatically.&#160; Hey look, auto&#8230;mappings.&#160; <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p dir="ltr"><strong><u>How?</u></strong></p>
<p dir="ltr">Using the same fluent language, configuring AutoMapping is an exercise in implementing conventions for the logical naming and handling of data.</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#2bdad5;">Fluently</span></p>
<p style="margin:0;">&#160; &#160; .Configure()</p>
<p style="margin:0;">&#160; &#160; .Database(<span style="color:#2bdad5;">MsSqlConfiguration</span>.MsSql2005</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .ConnectionString(cs =&#62; cs</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .Server(<span style="background:#6f0205;color:white;">&#8220;server&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .Database(<span style="background:#6f0205;color:white;">&#8220;db&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .Username(<span style="background:#6f0205;color:white;">&#8220;user&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .Password(<span style="background:#6f0205;color:white;">&#8220;password&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; )</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .UseReflectionOptimizer()</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .UseOuterJoin()</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .AdoNetBatchSize(<span style="color:aqua;font-weight:bold;">10</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .DefaultSchema(<span style="background:#6f0205;color:white;">&#8220;dbo&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .ShowSql()</p>
<p style="margin:0;">&#160; &#160; )</p>
<p style="margin:0;">&#160;&#160;&#160; .ExposeConfiguration(raw =&#62;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; <span style="color:#9ea928;">// Testing/NHibernate Profiler stuffs.</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; raw.SetProperty(<span style="background:#6f0205;color:white;">&#8220;generate_statistics&#8221;</span>, <span style="background:#6f0205;color:white;">&#8220;true&#8221;</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; RebuildSchema(raw);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; })</p>
<p style="margin:0;">&#160; &#160; .Mappings(m =&#62;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; m.AutoMappings.Add(<span style="color:#2bdad5;">AutoPersistenceModel</span></p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; .MapEntitiesFromAssemblyOf&#60;<span style="color:#2bdad5;">Walkthrough</span>&#62;()</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; .ConventionDiscovery.Setup(c =&#62;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; c.Add&#60;<span style="color:#2bdad5;">EnumMappingConvention</span>&#62;();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; c.Add&#60;<span style="color:#2bdad5;">ReferencesConvention</span>&#62;();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; c.Add&#60;<span style="color:#2bdad5;">HasManyConvention</span>&#62;();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; c.Add&#60;<span style="color:#2bdad5;">ClassMappingConvention</span>&#62;();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; })</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;&#160; .WithSetup(c =&#62; c.IsBaseType = type =&#62; type == <span style="color:#ff7c05;">typeof</span> (<span style="color:#2bdad5;">Entity</span>)))</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; .ExportTo(<span style="background:#6a0609;color:white;">@&#8221;.\&#8221;</span>)</p>
<p style="margin:0;">&#160; &#160; );</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">As you can see above, the only difference from a&#160;fluent mappings configuration is in the actual Mappings area.&#160; Good deal!&#160; That helps ensure my existing work using fluent mappings could translate without too much headache.</p>
<p dir="ltr">I&#8217;ve specified four conventions.&#160; Each of these conventions have interfaces that provide the necessary methods to ensure your rules are appied to the correct objects.</p>
<p dir="ltr"><strong>EnumMappingConvention</strong></p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">internal</span> <span style="color:#ff7c05;">class</span> <span style="color:#2bdad5;">EnumMappingConvention</span> : <span style="color:#2b91af;">IUserTypeConvention</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">bool</span> Accept(<span style="color:#2b91af;">IProperty</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> target.PropertyType.IsEnum;</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">void</span> Apply(<span style="color:#2b91af;">IProperty</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.CustomTypeIs(target.PropertyType);</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">bool</span> Accept(<span style="color:#2bdad5;">Type</span> type)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> type.IsEnum;</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">The great thing about these methods is they&#8217;re fluent enough to translate to English.</p>
<p dir="ltr">Accept&#8230; targets where the property type is an enumeration.</p>
<p dir="ltr">Apply&#8230; to the target that the &#8220;Custom Type Is&#8221; the property type of the target.<br />&#160; <strong>NOTE: </strong>This translates from a ClassMap into: Map(x =&#62; x.MyEnumFlag).CustomTypeIs(typeof(MyEnum));</p>
<p dir="ltr">Accept&#8230; a type that is an enumeration.</p>
<p dir="ltr"><strong>ReferenceConvention</strong></p>
<p dir="ltr">The Reference convention handles those reference relationships between our classes (and the foreign keys).</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">internal</span> <span style="color:#ff7c05;">class</span> <span style="color:#2bdad5;">ReferencesConvention</span> : <span style="color:#2b91af;">IReferenceConvention</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">bool</span> Accept(<span style="color:#2b91af;">IManyToOnePart</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> <span style="color:#ff7c05;">string</span>.IsNullOrEmpty(target.GetColumnName());</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">void</span> Apply(<span style="color:#2b91af;">IManyToOnePart</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.ColumnName(target.Property.Name + <span style="background:#6f0205;color:white;">&#8220;Id&#8221;</span>);</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">The most important part here is enforcing how your foreign keys are going to be named.&#160; I prefer the simple {Object}Id format.</p>
<p dir="ltr">Car.Battery on the object side and [Car].[BatteryId] on the database side.</p>
<p dir="ltr"><strong>HasManyConvention</strong></p>
<p dir="ltr">The HasManys are our lists, bags, and collections of objects.</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">internal</span> <span style="color:#ff7c05;">class</span> <span style="color:#2bdad5;">HasManyConvention</span> : <span style="color:#2b91af;">IHasManyConvention</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">bool</span> Accept(<span style="color:#2b91af;">IOneToManyPart</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> target.KeyColumnNames.List().Count == <span style="color:aqua;font-weight:bold;">0</span>;</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">void</span> Apply(<span style="color:#2b91af;">IOneToManyPart</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.KeyColumnNames.Add(target.EntityType.Name + <span style="background:#6f0205;color:white;">&#8220;Id&#8221;</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.Cascade.AllDeleteOrphan();</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.Inverse();</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">We want to make sure that we haven&#8217;t added any other key columns (the Count == 0), and then apply both the naming convention as well as a few properties.</p>
<p dir="ltr">Cascade.AllDeleteOrphan() and Inverse() allows our parent objects (Car) to add new child objects (Car.Battery (Battery), Car.Accessories (IList&#60;Accessory&#62;)) without separating them out.</p>
<p dir="ltr"><strong>ClassMappingConvention</strong></p>
<p dir="ltr">Finally, the important Class mapping.&#160; This convention ensures that our tables are named property with pluralization.</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">class</span> <span style="color:#2bdad5;">ClassMappingConvention</span> : <span style="color:#2b91af;">IClassConvention</span></p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">bool</span> Accept(<span style="color:#2b91af;">IClassMap</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> <span style="color:#ff7c05;">true</span>; <span style="color:#9ea928;">// everything</span></p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; <span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">void</span> Apply(<span style="color:#2b91af;">IClassMap</span> target)</p>
<p style="margin:0;">&#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; target.WithTable(PluralOf(target.EntityType.Name));</p>
<p style="margin:0;">&#160; &#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">I&#8217;m using a pluralization method from one of my base libraries that I borrowed from Hudson Akridge.&#160; This helper method works really well and I don&#8217;t need to add additional references and libraries into my application just to handle the table names.</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">static</span> <span style="color:#ff7c05;">string</span> PluralOf(<span style="color:#ff7c05;">string</span> text)</p>
<p style="margin:0;">&#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#ff7c05;">var</span> pluralString = text<font color="#ffffff">;</font></p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#ff7c05;">var</span> lastCharacter = pluralString.Substring(pluralString.Length &#8211; <span style="color:aqua;font-weight:bold;">1</span>).ToLower();</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#9ea928;">// y&#8217;s become ies (such as Category to Categories)</span></p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#ff7c05;">if</span> (<span style="color:#ff7c05;">string</span>.Equals(lastCharacter, <span style="background:#6f0205;color:white;">&#8220;y&#8221;</span>, <span style="color:#2b91af;">StringComparison</span>.InvariantCultureIgnoreCase))</p>
<p style="margin:0;">&#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; pluralString = pluralString.Remove(pluralString.Length &#8211; <span style="color:aqua;font-weight:bold;">1</span>);</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; pluralString += <span style="background:#6f0205;color:white;">&#8220;ie&#8221;</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; }</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#9ea928;">// ch&#8217;s become ches (such as Pirch to Pirches)</span></p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#ff7c05;">if</span> (<span style="color:#ff7c05;">string</span>.Equals(pluralString.Substring(pluralString.Length &#8211; <span style="color:aqua;font-weight:bold;">2</span>), <span style="background:#6f0205;color:white;">&#8220;ch&#8221;</span>,</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#2b91af;">StringComparison</span>.InvariantCultureIgnoreCase))</p>
<p style="margin:0;">&#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; pluralString += <span style="background:#6f0205;color:white;">&#8220;e&#8221;</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; &#160; &#160; <span style="color:#ff7c05;">switch</span> (lastCharacter)</p>
<p style="margin:0;">&#160; &#160; &#160; {</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; <span style="color:#ff7c05;">case</span> <span style="background:#6f0205;color:white;">&#8220;s&#8221;</span>:</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> pluralString + <span style="background:#6f0205;color:white;">&#8220;es&#8221;</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; <span style="color:#ff7c05;">default</span>:</p>
<p style="margin:0;">&#160; &#160; &#160; &#160; &#160; &#160; &#160; <span style="color:#ff7c05;">return</span> pluralString + <span style="background:#6f0205;color:white;">&#8220;s&#8221;</span>;</p>
<p style="margin:0;">&#160; &#160; &#160; }</p>
<p style="margin:0;">&#160; }</p>
</div>
<p><!--EndFragment--></p>
<p dir="ltr">Save and build.&#160; The ExportSchema method will generate the SQL and/or regen the database based on the specifications you&#8217;ve provided to it. and you&#8217;re ready to hit the ground running!</p>
<p dir="ltr">&#160;</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/fluent+nhibernate">fluent+nhibernate</a>, <a rel="tag" href="http://technorati.com/tag/automapping">automapping</a>, <a rel="tag" href="http://technorati.com/tag/nhibernate">nhibernate</a>, <a rel="tag" href="http://technorati.com/tag/sql+server+2005">sql+server+2005</a>, <a rel="tag" href="http://technorati.com/tag/.net+3.5">.net+3.5</a>, <a rel="tag" href="http://technorati.com/tag/c#">c#</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Rendering the Web Equally on Mobile Devices]]></title>
<link>http://tiredblogger.wordpress.com/2009/06/26/rendering-the-web-equally-on-mobile-devices/</link>
<pubDate>Fri, 26 Jun 2009 15:57:00 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/06/26/rendering-the-web-equally-on-mobile-devices/</guid>
<description><![CDATA[I&rsquo;ve been digging through the Interwebs for a while now and, I thought, had worked out all of ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been digging through the Interwebs for a while now and, I thought, had worked out all of the &#8220;kinks&#8221; of rendering on a mobile device&#8212;specifically iPhones.</p>
<p>The <a href="http://is.gd/1etNw" target="_blank">special &#8216;viewport&#8217; meta tag</a> means the world to iDevices.</p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">meta</span> name=<span style="color:lime;">&#8220;viewport&#8221;</span> content=<span style="color:lime;">&#8220;width = device-width&#8221;</span> <span style="color:yellow;">/&#62;</span></p>
</div>
<p><!--EndFragment--></p>
<p>I&#8217;m faced with a new challenge&#8212;the Palm Pre&#8217;s built-in web browser.&#160; My shiny new phone is great, but it isn&#8217;t without glitches.</p>
<p>The first glitch I&#8217;ve found appears to be a DNS issue&#8212; <a href="http://myserver/web">http://myserver/web</a>&#160;won&#8217;t resolve; however, <a href="http://123.45.67.89/web">http://123.45.67.89/web</a> will.&#160; It seems to be touchy.&#160; Most of our webs work just fine, others don&#8217;t.&#160; I haven&#8217;t narrowed it down to a single server or architecture as it seems to be a bit of everything.&#160; Wonky.</p>
<p>The next glitch is more important&#8212;the rendering.&#160; One of our tools is a simple form-based tool that looks great on the iPhone; however, renders partial screen and &#8220;garbles&#8221; when you move around the screen.</p>
<p><strong>Palm Pre:</strong></p>
<p><img border="2" hspace="5" alt="Garbled image" vspace="5" src="http://is.gd/1etgs" /></p>
<p><strong>iTouch/iPhone:</strong></p>
<p><img border="2" hspace="5" alt="" vspace="5" src="http://is.gd/1eux1" /></p>
<p>I&#8217;ve also found that anything in an ASP.NET Update Panel (like those Select buttons) are unusable.&#160; Other webs I&#8217;ve used (Bank of America, etc) use AJAX just fine, so I don&#8217;t think it&#8217;s that&#8212;probably a coding issue I need to dig into and resolve.</p>
<p><strong>UPDATE: </strong>Explicitly adding &#8220;LoadScriptsBeforeUI=&#8217;true&#8217;&#8221; to the ASP.NET ScriptManager seems to help with this.. a little.</p>
<p>Anyone else worked specifically with the Pre devices and rendering?&#160; I&#8217;d appreciate any meta tags or layout ideas that worked. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160; The Pre isn&#8217;t a common device in our organization&#8212;yet.</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/Palm+Pre">Palm+Pre</a>, <a rel="tag" href="http://technorati.com/tag/iPhone">iPhone</a>, <a rel="tag" href="http://technorati.com/tag/asp.net">asp.net</a>, <a rel="tag" href="http://technorati.com/tag/ajax">ajax</a>, <a rel="tag" href="http://technorati.com/tag/mobile+web">mobile+web</a></div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1: RC (ISO)]]></title>
<link>http://esersahin.wordpress.com/2009/06/20/microsoft-windows-sdk-for-windows-7-and-net-framework-3-5-sp1-rc-iso/</link>
<pubDate>Sat, 20 Jun 2009 19:48:39 +0000</pubDate>
<dc:creator>esersahin</dc:creator>
<guid>http://esersahin.wordpress.com/2009/06/20/microsoft-windows-sdk-for-windows-7-and-net-framework-3-5-sp1-rc-iso/</guid>
<description><![CDATA[http://www.microsoft.com/downloads/details.aspx?FamilyID=6db1f17f-5f1e-4e54-a331-c32285cdde0c&amp;di]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6db1f17f-5f1e-4e54-a331-c32285cdde0c&#38;displaylang=en">http://www.microsoft.com/downloads/details.aspx?FamilyID=6db1f17f-5f1e-4e54-a331-c32285cdde0c&#38;displaylang=en</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Кодогенерация T4]]></title>
<link>http://blog.team23.ru/2009/06/13/t4-codegeneration/</link>
<pubDate>Sat, 13 Jun 2009 17:56:00 +0000</pubDate>
<dc:creator>der Igel</dc:creator>
<guid>http://blog.team23.ru/2009/06/13/t4-codegeneration/</guid>
<description><![CDATA[Нет, это не про Терминатора Это про использование T4 Text Template Transformation Toolkit, встроенно]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Нет, это не про Терминатора <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Это про использование T4 Text Template Transformation Toolkit, встроенного в Visual Studio 2008 для автоматической генерации кода.</p>
<p>Кратко задача – есть исходники. Опять-то таки сгенерированные, но другим инструментом, <a href="http://incubator.apache.org/thrift/">Thrift</a>.     <br />Код на C#, публичные поля и свойства в классах с одинаковым именем, только различаются регистром.     <br />Код необходимо использовать из VB.NET. Упс! VB.NET нечувствителен к регистру! Приплыли.</p>
<p>Исходники конечно есть, но они регулярно обновляются – так что их исправлять нельзя.    <br />Классы не помечены partial – расширить напрямую тоже нельзя. </p>
<p>Но у нас же есть extension методы – спасибо .NET 3.5! Можно понаписать методов (эх… пока только методы, эктеншен свойств нет) с названием совпадающим со свойствами, но с каким-нибудь префиксом, подчеркиванием например. </p>
<p>Ок, хорошо. Но вручную писать обертки на 20 классов?! Да они еще, как я сказал, могут обновиться в будущем. Тут нужна автоматизация… И в VS 2008 она уже встроена – движок кодогенерации T4.</p>
<p>Файлы с расширением tt. Синтаксис очень похож на ASP.NET, только исполняются внутри Visual Studio (и не только, хостом может выступать любое приложение, и ваше в том числе).</p>
<p>И вот всё волшебство:</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:d3eb45f9-2c38-4499-b0a0-7733d996ee1d" class="wlWriterEditableSmartContent">
<div style="font-family:consolas,lucida console,courier,monospace;">
&#60;#@&#160;template&#160;language=<span style="color:#a31515;">&#8220;C#v3.5&#8243;</span>&#160;hostspecific=<span style="color:#a31515;">&#8220;true&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;assembly&#160;name=<span style="color:#a31515;">&#8220;EDAM.dll&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;assembly&#160;name=<span style="color:#a31515;">&#8220;System.Core&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;System.CodeDom&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;System.CodeDom.Compiler&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;System.IO&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;System.Linq&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;System.Reflection&#8221;</span>&#160;#&#62;<br />
&#60;#@&#160;import&#160;namespace=<span style="color:#a31515;">&#8220;Evernote.EDAM.Type&#8221;</span>&#160;#&#62;<br />
&#160;<br />
<span style="color:#008000;">//&#160;Autogenerated&#160;by&#160;&#60;#=&#160;Host.GetType()&#160;#&#62;<br />
//&#160;&#60;#=&#160;DateTime.Now&#160;#&#62;<br />
//&#160;DO&#160;NOT&#160;EDIT&#160;UNLESS&#160;YOU&#160;ARE&#160;SURE&#160;THAT&#160;YOU&#160;KNOW&#160;WHAT&#160;YOU&#160;ARE&#160;DOING<br />
</span><br />
<span style="color:#0000ff;">namespace</span>&#160;Evernote.EDAM.Type<br />
<span style="color:#0000ff;">{</span><br />
&#60;#&#160;<span style="color:#0000ff;">foreach</span>&#160;(var&#160;@class&#160;<span style="color:#0000ff;">in</span>&#160;Assembly.GetAssembly(BaseClass)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.GetExportedTypes()<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.Where(type&#160;=&#62;&#160;!type.IsNested)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.Where(type&#160;=&#62;&#160;type.Namespace&#160;==&#160;BaseClass.Namespace))&#160;<span style="color:#0000ff;">{</span>&#160;#&#62;<br />
&#160;&#160;<span style="color:#0000ff;">public</span>&#160;<span style="color:#0000ff;">static</span>&#160;<span style="color:#0000ff;">class</span>&#160;&#60;#=&#160;<span style="color:#2b91af;">@class</span>.Name&#160;#&#62;Ex<br />
&#160;&#160;<span style="color:#0000ff;">{</span><br />
&#160;&#160;&#60;#&#160;<span style="color:#0000ff;">foreach</span>&#160;(var&#160;prop&#160;<span style="color:#0000ff;">in</span>&#160;@class.GetProperties())&#160;<span style="color:#0000ff;">{</span>&#160;#&#62;<br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff;">public</span>&#160;<span style="color:#0000ff;">static</span>&#160;&#60;#=&#160;PrintType(prop.PropertyType)&#160;#&#62;&#160;_&#60;#=&#160;prop.Name&#160;#&#62;(<span style="color:#0000ff;">this</span>&#160;&#60;#=&#160;prop.DeclaringType&#160;#&#62;&#160;<span style="color:#0000ff;">value</span>)<br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff;">{</span><br />
&#160;&#160;&#160;&#160;&#160;&#160;<span style="color:#0000ff;">return</span>&#160;<span style="color:#0000ff;">value</span>.&#60;#=&#160;prop.Name&#160;#&#62;;<br />
&#160;&#160;&#160;&#160;<span style="color:#0000ff;">}</span><br />
&#160;&#160;&#60;#&#160;<span style="color:#0000ff;">}</span>#&#62;<br />
&#160;&#160;<span style="color:#0000ff;">}</span><br />
&#60;#&#160;<span style="color:#0000ff;">}</span>&#160;#&#62;<br />
<span style="color:#0000ff;">}</span><br />
&#60;#+&#160;Type&#160;BaseClass&#160;=&#160;<span style="color:#0000ff;">typeof</span>(Note);&#160;#&#62;<br />
&#60;#+&#160;<br />
<span style="color:#0000ff;">public</span>&#160;<span style="color:#2b91af;">string</span>&#160;PrintType(Type&#160;type)<br />
<span style="color:#0000ff;">{</span><br />
&#160;&#160;var&#160;typeExpr&#160;=&#160;<span style="color:#0000ff;">new</span>&#160;CodeTypeReferenceExpression(type);<br />
&#160;&#160;var&#160;csProvider&#160;=&#160;Microsoft.CSharp.CSharpCodeProvider.CreateProvider(<span style="color:#a31515;">&#8220;C#&#8221;</span>);<br />
&#160;&#160;var&#160;writer&#160;=&#160;<span style="color:#0000ff;">new</span>&#160;StringWriter();<br />
&#160;&#160;csProvider.GenerateCodeFromExpression(typeExpr,&#160;writer,&#160;<span style="color:#0000ff;">new</span>&#160;CodeGeneratorOptions());<br />
&#160;&#160;<span style="color:#0000ff;">return</span>&#160;writer.ToString();<br />
<span style="color:#0000ff;">}</span>&#160;#&#62;
</div>
</div>
<p>&#160;</p>
<p>Вкратце, по шагам:</p>
<ol>
<li>Перебираем все классы из сборки, из нужного пространства имен. </li>
<li>Для каждого класса генерируем статический класс с таким-же именем и суффиксом Ex. </li>
<li>Перебираем все свойства класса. </li>
<li>Генерируем экстеншен-метод нужного типа с именем как оригинальное ствойство, но с префиксом _. </li>
<li>Для генерация имени нужного типа используется маленькая хитрость. Так как по простому дженерики будут выводиться в IL-нотации, т.е. например System.Generic.List’1[System.String]. И это не будет компилироваться. Надо System.Generic.List&#60;System.String&#62; (для C#). Что и делается через CodeDom. Так как сборка на C# – то и провайдер для C# используется. Можно генерировать и в VB. Как в CodeDom, так и в самом T4 кстати. </li>
</ol>
<p>Всё, теперь при сборке будет генерироваться набор расширений для каждого нужного класса с методами дублирующими все свойства, которые уже без проблем можно использовать в VB.NET. Кстати, в VB можно опускать скобки при вызове метода, если он не принимает параметров, что делает код еще более изящным (насколько вообще можно говорить об изящности в этой ситуации):</p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:e238fdcf-d975-4f06-92b8-0272810f9f0b" class="wlWriterEditableSmartContent">
<div style="font-family:consolas,lucida console,courier,monospace;">
C#&#160;note.Attributes.Lattitude
</div>
</div>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:2EC9848E-067D-4e79-BAB7-06CA927DB962:54c7692f-84fa-4c6e-8906-fa5768c8f99f" class="wlWriterEditableSmartContent">
<div style="font-family:consolas,lucida console,courier,monospace;">
VB.NET&#160;note._Attributes._Lattitude
</div>
</div>
<p>&#160;</p>
<p>Полезные ссылки:</p>
<ul>
<li><a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/">T4: Text Template Transformation Toolkit</a> </li>
<li><a href="Generating Artifacts By Using Text Templates">Generating Artifacts By Using Text Templates</a> (раздел в MSDN) </li>
<li><a href="http://www.visualt4.com/">Visual T4</a> (плагин для редактирования файлов tt с подсветкой) </li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Benchmarks : Comparing LINQ to NHibernate Transforms/Grouping]]></title>
<link>http://tiredblogger.wordpress.com/2009/06/12/benchmarks-comparing-linq-to-nhibernate-transformsgrouping/</link>
<pubDate>Fri, 12 Jun 2009 14:07:37 +0000</pubDate>
<dc:creator>David Longnecker</dc:creator>
<guid>http://tiredblogger.wordpress.com/2009/06/12/benchmarks-comparing-linq-to-nhibernate-transformsgrouping/</guid>
<description><![CDATA[Yesterday, I wrote about setting up NHibernate to query up, group, count, and transform results and ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Yesterday, I <a href="http://is.gd/ZMhR" target="_blank">wrote</a> about setting up NHibernate to query up, group, count, and transform results and return them into a control.&#160; Why did I go to such effort?&#160; Well, the original LINQ query I had that refined the results didn&#8217;t perform up to par.&#160; As some may note, premature optimization is never a good practice so I needed some stats to back up the claims.</p>
<p>Overnight, I wrote up a quick test to query up both ways and benchmark the results.&#160; Here&#8217;s what I found.</p>
<p><strong>The &#8220;test&#8221;:</strong></p>
<div style="font-family:Monaco, Consolas;background:#383838;color:#dbe387;font-size:8pt;">
<p style="margin:0;"><span style="color:#ff7c05;">public</span> <span style="color:#ff7c05;">void</span> TEMP_quick_compare_of_linq_to_nhibernate()</p>
<p style="margin:0;">{</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:#ff7c05;">var</span> schoolId = <span style="color:aqua;font-weight:bold;">120</span>;</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:#ff7c05;">var</span> benchmark = <span style="color:#ff7c05;">new</span> <span style="color:#2bdad5;">Benchmark</span>();</p>
<p style="margin:0;">&#160;&#160;&#160; <span style="color:#ff7c05;">using</span> (<span style="color:#ff7c05;">var</span> repository = <span style="color:#ff7c05;">new</span> <span style="color:#2bdad5;">IncidentRepository</span>())</p>
<p style="margin:0;">&#160;&#160;&#160; {</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; benchmark.Start();</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#ff7c05;">var</span> resultsFromLinq = </p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; repository.GetCountByIncidentCodeWithLinq(schoolId);</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#ff7c05;">foreach</span> (<span style="color:#ff7c05;">var</span> item <span style="color:#ff7c05;">in</span> resultsFromLinq) </p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; {</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; <span style="color:#2bdad5;">Console</span>.WriteLine(item);</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; }</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; benchmark.Stop();</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#2bdad5;">Console</span>.WriteLine(<span style="background:#6f0205;color:white;">&#8220;Linq: {0}&#8221;</span>.AsFormatFor(benchmark.ElapsedTime));</p>
<p style="margin:0;">&#160;</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; benchmark.Start();</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#ff7c05;">var</span> resultsFromNhibernate = </p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; repository.GetCountByIncidentCode(schoolId);</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#ff7c05;">foreach</span> (<span style="color:#ff7c05;">var</span> item <span style="color:#ff7c05;">in</span> resultsFromNhibernate)</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; {</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160;&#160; &#160;&#160; <span style="color:#2bdad5;">Console</span>.WriteLine(item);</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; }</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; benchmark.Stop();</p>
<p style="margin:0;">&#160;&#160; &#160;&#160; &#160; <span style="color:#2bdad5;">Console</span>.WriteLine(<span style="background:#6f0205;color:white;">&#8220;NHibernate: {0}&#8221;</span>.AsFormatFor(benchmark.ElapsedTime));</p>
<p style="margin:0;">&#160;&#160;&#160; }</p>
<p style="margin:0;">}</p>
</div>
<p><!--EndFragment--></p>
<p>Setting up the benchmark (and the NHibernate Init) are outside of the benchmark&#8212;they&#8217;re necessary overhead.&#160; I&#8217;m&#160;also iterating through each of the results as part of the benchmark to ensure that everything is evaluated. Past that, pretty basic.&#160; On the database side, I&#8217;ve disabled statement caching to not sway the results as much.</p>
<p>With 24 records (the test data in the system), the results were pretty clear.&#160;The average of running the benchmark 100 times resulted in&#8230;</p>
<blockquote>
<p>Linq:&#160;00:00:00.7050000<br />NHibernate:&#160;00:00:00.0190000</p>
</blockquote>
<p>With 24 records, NHibernate was about 37x faster.&#160; </p>
<p>That&#8217;s nice, but what happens in a few&#160;weeks when there are a few&#160;thousand records?&#160; I populated a few hundred of each incident type into the system, giving me almost 4000 records (the anticipated monthly load of the system by the customer).&#160; How&#8217;d that change our averages?</p>
<blockquote>
<p>Linq:&#160;00:00:00.8869746<br />NHibernate:&#160;00:00:00.1381518</p>
</blockquote>
<p>Now we&#8217;re only 6x faster with NHibernate vs. LINQ.&#160; The duration from 24 to 4000 records for LINQ&#160; jumped ~.18 seconds for a 25% gain&#160;where as NHibernate jumped ~.11 seconds for a 626% gain.</p>
<p>So, with that, my original gut feeling and assumptions were <strong><u>wrong</u></strong>.&#160; More and more records don&#8217;t really slow down the LINQ filtering.. at least not by much.&#160; The performance gain is still appparent between the two methods (.88 sec vs. .13 sec); however, how much of that time is eaten up by rendering, server latency, etc and not by the actual processing?</p>
<div class="bjtags">Tags: <a rel="tag" href="http://technorati.com/tag/nhibernate">nhibernate</a>, <a rel="tag" href="http://technorati.com/tag/linq">linq</a>, <a rel="tag" href="http://technorati.com/tag/performance">performance</a>, <a rel="tag" href="http://technorati.com/tag/c#">c#</a>, <a rel="tag" href="http://technorati.com/tag/asp.net">asp.net</a>, <a rel="tag" href="http://technorati.com/tag/optimization">optimization</a></div>
</div>]]></content:encoded>
</item>

</channel>
</rss>
