<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUAMSXs_fCp7ImA9WhRXFE8.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862</id><updated>2011-12-20T15:29:48.544-08:00</updated><category term="Intro" /><category term="Team Foundation Server" /><category term="Team Build" /><category term="ViewStateModeById" /><category term="TFS" /><category term="Integration Testing" /><category term="UCM" /><category term="VS2010 Database Projects DBProj PostDeploy Script.PostDeployment.sql Visual Studio" /><category term="dynamic controls" /><category term="Control Tree" /><category term="TeamBuildService.exe" /><category term="Ajax" /><category term="ASP.NET" /><category term="won't work" /><category term="YakShaver" /><category term="sc.exe" /><category term="Tools" /><category term="add control to page" /><category term="frustration" /><category term="ViewState" /><category term="ClearCase" /><category term="Unit Testing" /><category term="Failed to load ViewState" /><category term="Service Controller" /><category term="CodePlex" /><title>YakShaving - Yet Another .NET Perspective</title><subtitle type="html">Wasting Time.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://yakshaver.blogspot.com/" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Yakshaving-YetAnothernetPerspective" /><feedburner:info uri="yakshaving-yetanothernetperspective" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0QBRXY-fip7ImA9WhdSFk0.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-256364376809783546</id><published>2011-07-25T07:49:00.000-07:00</published><updated>2011-07-25T07:49:14.856-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-25T07:49:14.856-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="VS2010 Database Projects DBProj PostDeploy Script.PostDeployment.sql Visual Studio" /><title>VS 2010 Database Projects Post Deployment Scripts not Executing</title><content type="html">Today I have been dealing with a really frustrating problem when working the DB Projects in Visual Studio 2010.&lt;br /&gt;
&lt;br /&gt;
One really great feature is the pre/post-deployment scripts that you can execute on each deploy for things like static or reference data.&amp;nbsp; Or in some cases some test data as well not run by a data generation plan.&lt;br /&gt;
&lt;br /&gt;
My issue was whenever I'd click deploy, the DB would be recreated, my tables I updated were created as expected, but it would not execute the post deployment file.&amp;nbsp; After some help from a co-worker, he diagnosed and found the problem was with the &lt;b&gt;Build Action&lt;/b&gt; property on the file itself.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-qyx1I82UHQ0/Ti2CQ74hXPI/AAAAAAAAACM/ujXDF7ercwI/s1600/SqlProjectPostDeploy.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="241" src="http://2.bp.blogspot.com/-qyx1I82UHQ0/Ti2CQ74hXPI/AAAAAAAAACM/ujXDF7ercwI/s320/SqlProjectPostDeploy.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
To correct, select the &lt;b&gt;Script.PostDeployment.sql &lt;/b&gt;file in the Solution Explorer.&amp;nbsp; Click F4 if necessary to display the property grid.&amp;nbsp; Click Build Action, choose &lt;b&gt;PostDeploy&lt;/b&gt;.&amp;nbsp; Deploy away.&lt;br /&gt;
&lt;br /&gt;
Hope this saves you a few frustrating hours.&lt;br /&gt;
&lt;br /&gt;
One note, you may only have 1 post deployment file in your project, use SQLCMD :r syntax to run all the scripts you want to execute post deploy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-256364376809783546?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/btmulnbJ1g8QnjN8S-HOG4iao8s/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/btmulnbJ1g8QnjN8S-HOG4iao8s/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/btmulnbJ1g8QnjN8S-HOG4iao8s/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/btmulnbJ1g8QnjN8S-HOG4iao8s/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/w-V4UbsKpYw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/256364376809783546/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=256364376809783546" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/256364376809783546?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/256364376809783546?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/w-V4UbsKpYw/vs-2010-database-projects-post.html" title="VS 2010 Database Projects Post Deployment Scripts not Executing" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-qyx1I82UHQ0/Ti2CQ74hXPI/AAAAAAAAACM/ujXDF7ercwI/s72-c/SqlProjectPostDeploy.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2011/07/vs-2010-database-projects-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QBSXY8eSp7ImA9WhZSEk4.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-6912139426613865853</id><published>2011-03-27T07:01:00.000-07:00</published><updated>2011-03-27T07:15:58.871-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-27T07:15:58.871-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Control Tree" /><category scheme="http://www.blogger.com/atom/ns#" term="ViewStateModeById" /><category scheme="http://www.blogger.com/atom/ns#" term="Failed to load ViewState" /><category scheme="http://www.blogger.com/atom/ns#" term="dynamic controls" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="add control to page" /><category scheme="http://www.blogger.com/atom/ns#" term="ViewState" /><category scheme="http://www.blogger.com/atom/ns#" term="frustration" /><title>The greatest ViewState attribute to ever exist - Dynamic Controls just became easy</title><content type="html">Recently at work, we were dealing with the ol' &lt;b&gt;dynamic controls&lt;/b&gt; and &lt;b&gt;ViewState&lt;/b&gt; problem. You know.. This one.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;Failed to load viewstate.
The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.
&lt;/pre&gt;&lt;br /&gt;
I've seen a lot of *elegant* solutions on how to solve this.  All these examples proving it out what have you.&lt;br /&gt;
&lt;br /&gt;
I can't beleive Microsoft would hose us over with such a thing!!!  &lt;br /&gt;
&lt;br /&gt;
Well, they didn't...  Hello &lt;b&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.viewstatemodebyidattribute.aspx"&gt;ViewStateModeById &lt;/a&gt;! &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
How does it work?&amp;nbsp; Reflect it, what you'll find is that it simply iterates through the control tree by name instead of the index version which iterates through the tree (for each INamingContainer ) and then takes a value at the same index position in the ViewState statebag.&amp;nbsp; This is highly efficient, and with the way web forms are typically used, it works.&lt;br /&gt;
&lt;br /&gt;
The counter to the ViewStateByModeId is performance.&amp;nbsp; But look at most of the dynamic control ViewState problem solving methods out there.&amp;nbsp; You'll find a great many simply use the same method to find the name of the control in the control tree.&amp;nbsp; If you consider the general computing power of modern servers, the performance impact is negligible.&amp;nbsp; There are edge cases where you have massive control trees, but if so, it might be a good idea to look at your overall page structure and other optimizations.&amp;nbsp; Don't blame it on the ViewState.&lt;br /&gt;
&lt;br /&gt;
Not only that, they implemented it as both a property on Control and an Attribute.&amp;nbsp; Remember that Page is inherited from Control, so OnInit, just set the property first, then add your controls here &lt;b&gt;not in Page_Load&lt;/b&gt;.&amp;nbsp; The lifecycle has already passed the LoadViewState event.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
There is one &lt;b&gt;gotcha&lt;/b&gt;.&amp;nbsp; It does not quite work correctly on radio groups, so you have to request the value from the Form in order to set it, get values. &amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
One line of code that has saved me more hours and that much frustration than is fathomable.&amp;nbsp; Hope you get the same. Time to cross post the hell out of this.&lt;br /&gt;
&lt;br /&gt;
You're welcome ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-6912139426613865853?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Y0GnXa9N55o1fXKBvWhPhUUHr7I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y0GnXa9N55o1fXKBvWhPhUUHr7I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Y0GnXa9N55o1fXKBvWhPhUUHr7I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Y0GnXa9N55o1fXKBvWhPhUUHr7I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/BADj-EtvTLc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/6912139426613865853/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=6912139426613865853" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6912139426613865853?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6912139426613865853?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/BADj-EtvTLc/greatest-viewstate-attribute-to-ever.html" title="The greatest ViewState attribute to ever exist - Dynamic Controls just became easy" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2011/03/greatest-viewstate-attribute-to-ever.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEARH88eip7ImA9Wx9QFE8.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-1625682172325955012</id><published>2010-12-26T19:30:00.001-08:00</published><updated>2010-12-26T19:30:45.172-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-26T19:30:45.172-08:00</app:edited><title>Some great jQuery UI Links</title><content type="html">50 useful links.&amp;nbsp; Was browsing for a combo box that was prettier than the current.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
http://www.noupe.com/jquery/50-amazing-jquery-examples-part1.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-1625682172325955012?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GVugawo0exl16QcQKfjfQE4ewbQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GVugawo0exl16QcQKfjfQE4ewbQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GVugawo0exl16QcQKfjfQE4ewbQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GVugawo0exl16QcQKfjfQE4ewbQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/thm-6c8ZBCk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/1625682172325955012/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=1625682172325955012" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/1625682172325955012?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/1625682172325955012?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/thm-6c8ZBCk/some-great-jquery-ui-links.html" title="Some great jQuery UI Links" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/12/some-great-jquery-ui-links.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8BQns7fSp7ImA9Wx9REU0.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-2063583978481434146</id><published>2010-12-11T14:50:00.000-08:00</published><updated>2010-12-11T14:50:53.505-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-11T14:50:53.505-08:00</app:edited><title>jQuery UI Tabs + XSLT + Double Page_Load Event + and carriage return</title><content type="html">You know, one of the great things about having ADHD is I now have an excuse for getting side tracked and going on a code jungle adventure to solve bugs of epic proportions.&lt;br /&gt;
&lt;br /&gt;
And that's just what happened this weekend!&lt;br /&gt;
&lt;br /&gt;
I've been using jQuery a lot more right along with ASP.NET MVC 2.&amp;nbsp; As most, I keep working on old projects and simply bring them up to speed, try different things out, the like.&lt;br /&gt;
&lt;br /&gt;
For those new to jQuery, it is a high performance, micro footprint, JavaScript library that that makes it possible to make client side development as extreme as something like Facebook for developers even like me... Not only that, there are literally thousands of extensions for this thing.&amp;nbsp; The one I was playing with is known as jQuery UI Tabs&lt;br /&gt;
&lt;br /&gt;
I chose to use an XML/XSL content engine I had written to do some email templating.&amp;nbsp; I wanted to convert this to a dynamic form that would be driven by XML. Basically, I wanted to create the input form + output(s) from common schema and neither knows of the other or has dependency.&amp;nbsp; Which is pretty much what XML is there for... ;)&lt;br /&gt;
&lt;br /&gt;
One such feature was to be able to break the input into a friendly / easy to use Form.&amp;nbsp; Using an XSL transform, It rendered an HTML form of 1..x # of tabs. Without the details of how the whole tab system works, for each tab, you have a &lt;br /&gt;
&lt;div&gt;with a unique identifier such as tabs-#.&amp;nbsp; Where # is a sequential value from 1..x.&amp;nbsp; Using the syntax&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&amp;nbsp;$(&lt;span style="color: maroon;"&gt;"#tabs"&lt;/span&gt;).tabs();&lt;/pre&gt;&lt;pre style="font-family: consolas;"&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
The XSL that transform to XSL looks like so:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:template&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;match&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;tab&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:variable&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;tabNumber&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:number&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;position()&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;format&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;1&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;xsl:variable&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
 
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;id&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tr_&lt;span style="color: blue;"&gt;&amp;amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:value-of&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;select&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;$tabNumber&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Clearly looks clean. Code generates, tabs generate...&lt;br /&gt;
&lt;br /&gt;
but then... something weird happens..&amp;nbsp; The tabs show up a second time, but this time, no formatting, everything looks horrible on the screen, and the Page_Load is called again by a GET.&amp;nbsp; Combine this with the dynamic nature of the control, and it becomes incredibly hard to debug.&lt;br /&gt;
&lt;br /&gt;
I disabled all my jQuery/JavaScript I had written.&amp;nbsp; Still getting a double load.&amp;nbsp; Not only that, injecting it.&amp;nbsp; I disabled the tabs portion itself, still coming up twice.&amp;nbsp; I'm getting a JavaScript runtime error much like when ASP.NET Ajax has two versions (1.0.xxx &amp;amp; 3.5) in the same application.&amp;nbsp; Checked that... Fine.&lt;br /&gt;
&lt;br /&gt;
Maybe jQuery has a bug in this version (I had downloaded 1.4.2 a few months back), so I upgraded to 1.4.4.&amp;nbsp; I switched to the Google CDN.&amp;nbsp; Over and over it kept coming back like a g*d damn zombie! &lt;br /&gt;
&lt;br /&gt;
I go back to my XSL, did I have a script reference in there?&amp;nbsp; Nothing stands out. &lt;br /&gt;
&lt;br /&gt;
Finally, trusty ol 'View HTML' and your favorite text editor.&amp;nbsp; Combing line by line, I'm trying to figure it out.&amp;nbsp; It's not standing out.&amp;nbsp; Until I finally come to the&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: blue;"&gt;"tr_tabs-2"&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="font-family: consolas;"&gt;&lt;/pre&gt;&lt;pre style="font-family: consolas;"&gt;&lt;/pre&gt;&lt;pre style="font-family: consolas;"&gt;&lt;/pre&gt;&lt;br /&gt;
or that's what I thought it should have looked like........&lt;br /&gt;
&lt;br /&gt;
Not quite though sport!&amp;nbsp; Looked a little more like&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;div&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;&lt;span style="color: blue;"&gt;"&amp;amp;#xA;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tr_tabs-2"&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Well, that certainly won't be found by tabs, and looks like we might have a little bug if so.&amp;nbsp; I don't know, I wasn't going to full investigate it.&amp;nbsp; I wanted to fix this and be done.&amp;nbsp; Why would this happen?&amp;nbsp; Back to XSL&lt;br /&gt;
&lt;br /&gt;
Ends up, Visual Studio and some editors like to put extra spaces and XSL doesn't like concating + string trimming without using XSL functions.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Remember this nugget?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;id&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tr_&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:value-of&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;select&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;concat('tabs-',&amp;nbsp;$tabNumber)&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;!--&lt;/span--&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
That little tr_ constant throws the whole thing off.&amp;nbsp; If you change it to (you will also notice the added spacing in Visual Studio when pressing delete)&amp;nbsp;&amp;nbsp; It works.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;id&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;tr_&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:value-of&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;select&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;$tabNumber&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;!--&lt;/span--&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
However, knowing how I like to hit Format Document, and this seemed like an easy mistake to make, I couldn't imagine this was the best way.&amp;nbsp; Nope!&amp;nbsp; of course not.&amp;nbsp; Using the XSL function (concat) solved this easily and still can use my format document feature in VS! &amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;pre style="font-family: consolas;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;div&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;id&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;xsl:value-of&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;select&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;concat('tr_tabs-',&amp;nbsp;$tabNumber)&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;!--&lt;/span--&gt;&lt;span style="color: #2b91af;"&gt;xsl:attribute&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
No more double GET and odd behavior.&amp;nbsp; I hope this helps someone!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-2063583978481434146?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kGMrYn5ACMjcIFqqVq33ziJzt2g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kGMrYn5ACMjcIFqqVq33ziJzt2g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kGMrYn5ACMjcIFqqVq33ziJzt2g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kGMrYn5ACMjcIFqqVq33ziJzt2g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/h9TfjjIuq6I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/2063583978481434146/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=2063583978481434146" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/2063583978481434146?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/2063583978481434146?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/h9TfjjIuq6I/jquery-ui-tabs-xslt-double-pageload.html" title="jQuery UI Tabs + XSLT + Double Page_Load Event + and carriage return" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/12/jquery-ui-tabs-xslt-double-pageload.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAGQXg7cSp7ImA9Wx5TGEg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-2090075580435425693</id><published>2010-08-02T13:51:00.000-07:00</published><updated>2010-08-03T08:52:00.609-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-03T08:52:00.609-07:00</app:edited><title>Version issues between TFS 2008 and TFS 2010 Libraries</title><content type="html">Finally been able to work on YakShaver a bit more trying to finally finish up what I'm calling the SFD feature.&amp;nbsp; As I've been working on it off and on for the past few years there sometimes can be days (read weeks/months) between getting dedicated time.&lt;br /&gt;
&lt;br /&gt;
Recently I made a change to go from the TFS 2010 libraries back to the 2008.&amp;nbsp; Not because something was wrong with them, just that one of the installation locations I had would not allow me to install TFS 2010 (anything related).&amp;nbsp; So, I rolled back my project to the 2008 and apparently just left it as is (never compiled or compiled and didn't pay attention to errors).&lt;br /&gt;
&lt;br /&gt;
Fast forward to last Friday.&amp;nbsp; I've finally got time, open up the solution, notice I have some errors.&amp;nbsp; "Not a big deal" I think to myself, how much could be wrong?&amp;nbsp; I knew it already worked before.&amp;nbsp; But I could not get this to compile.&amp;nbsp; The errors were all pretty close to the same.&lt;br /&gt;
&lt;br /&gt;
Microsoft.TeamFoundation.Build.Client.IProjectFile' is obsolete: 'This interface has been deprecated. Please remove all references.&lt;br /&gt;
&lt;br /&gt;
Not just this interface, IBuildStore was another.&amp;nbsp; But this was only a warning, so I ensured I had TreatWarningsAsErrors turned off, still couldn't get it to compile.&amp;nbsp; WTF, was all I could think.&lt;br /&gt;
&lt;br /&gt;
As I started diagnosing, I looked at another library I had referenced (not a project file reference, but just a DLL I had written previously.)&amp;nbsp; This DLL referenced the 2010 libraries and upon compilation would cause the error.&lt;br /&gt;
&lt;br /&gt;
I didn't see how this could actually cause an issue, but wanted to verify.&amp;nbsp; I found the project file for the DLL in question, included it in my solution, and sure enough same error.&amp;nbsp; I modified the project to utilize the 2008 libraries (9.0.0.0) instead.&amp;nbsp; Compiled.&amp;nbsp; Poof.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
It was logged as a bug with TFS in connect.&amp;nbsp; But doesn't look like it is.&amp;nbsp; Here is the &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/details/577048/cannot-implement-ibuilddefinition-class?wa=wsignin1.0#tabs"&gt;original link&lt;/a&gt; to see more details.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
https://connect.microsoft.com/VisualStudio/feedback/details/577048/cannot-implement-ibuilddefinition-class?wa=wsignin1.0#tabs&lt;br /&gt;
&lt;br /&gt;
Hope this helps, I struggled for a couple hours on it and the error message doesn't lead you down this path.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-2090075580435425693?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8KQ9JBteNTi0b_VP6mWsUwrk1as/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8KQ9JBteNTi0b_VP6mWsUwrk1as/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8KQ9JBteNTi0b_VP6mWsUwrk1as/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8KQ9JBteNTi0b_VP6mWsUwrk1as/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/PYQqWJG9ut4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/2090075580435425693/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=2090075580435425693" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/2090075580435425693?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/2090075580435425693?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/PYQqWJG9ut4/version-issues-between-tfs-2008-and-tfs.html" title="Version issues between TFS 2008 and TFS 2010 Libraries" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/08/version-issues-between-tfs-2008-and-tfs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UGSHo5eSp7ImA9WxFVGU8.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-7830251980254259928</id><published>2010-06-18T21:20:00.000-07:00</published><updated>2010-06-18T21:20:29.421-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-18T21:20:29.421-07:00</app:edited><title>New development laptop</title><content type="html">After 2.5 years, my current development laptop is just not keeping up as I would like.&amp;nbsp; The new rave seems to be in the i7 series processor from intel and the T7500 Core 2 Duo just does not handle VMWare + Visual Studio 2010 and a few other apps quite as well.&amp;nbsp; Plus, Quad Core vs. Duo.&amp;nbsp; Easy call.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Like before, I wanted to make sure I got a laptop that lasted.&amp;nbsp; I consider 2.5 years (1.5 years after paying it off) to be a acceptable amount of time, especially for a laptop.&amp;nbsp; I upgraded it over time of course, but it does have it's limits.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
As a result, I ordered a new Dell Studio XPS 16.&amp;nbsp; The basic configuration from Dell is&lt;br /&gt;
&lt;br /&gt;
Intel i7 720QM Quad Core&lt;br /&gt;
500G SATA HDD @ 7200 RPM&lt;br /&gt;
8 GB 1333MHZ&lt;br /&gt;
1920 x 1080P - Didn't spring for the RGB LED.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
Instead.&amp;nbsp; I ordered one of these &lt;a href="http://newmodeus.com/shop/index.php?main_page=product_info&amp;amp;products_id=296"&gt;caddy&lt;/a&gt;'s.&amp;nbsp; and&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820233087"&gt; this SSD drive&lt;/a&gt;.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
The plan.&amp;nbsp; Replace the 500GB drive with the SSD -&amp;gt; install Windows 7 using slot load DVD&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Replace Slot load DVD with caddy from above.&amp;nbsp; Put pre-existing 500GB drive, now I have a SSD + HDD XPS system.&amp;nbsp; Install Visual Studio Program Files on my SSD.&amp;nbsp; Store project on the HDD.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
If all goes well, this will be my fastest mobile PC to date.&amp;nbsp; All this for &amp;lt; 2000 and a good amount of lifetime in it.&amp;nbsp; Looking forward to getting it in, hopefully it lives up to all my expectations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-7830251980254259928?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5jXwt1maxiXwls6JWTu1my5Gob0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5jXwt1maxiXwls6JWTu1my5Gob0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5jXwt1maxiXwls6JWTu1my5Gob0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5jXwt1maxiXwls6JWTu1my5Gob0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/6YMmnozZ2ac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/7830251980254259928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=7830251980254259928" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7830251980254259928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7830251980254259928?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/6YMmnozZ2ac/new-development-laptop.html" title="New development laptop" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/06/new-development-laptop.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QAQ38yeSp7ImA9WxFQFUQ.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-5464320288405722092</id><published>2010-05-11T08:22:00.000-07:00</published><updated>2010-05-11T08:22:22.191-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-11T08:22:22.191-07:00</app:edited><title>Do it Fu*king now!</title><content type="html">Typically in my blog I try to avoid swearing.&amp;nbsp; Sure, I swear like sailor in person, but for some reason, the written word in front of god (heavy internet user) and everyone; I try to be more careful and show a &lt;strong&gt;little &lt;/strong&gt;more respect.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
But this article deserved the cross reference and I doubt I could have said it any better.&amp;nbsp; &lt;a href="http://seoblackhat.com/2007/01/29/do-it-fucking-now/"&gt;Do it Fucking now!&lt;/a&gt;&amp;nbsp; This doesn't have to mean you are being yelled at by a boss or anything negative.&amp;nbsp; It is a positive statement.&amp;nbsp; No need to wait, if you know what to do, do it.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Losers&amp;nbsp;wallow in&amp;nbsp;self pity.&amp;nbsp; &lt;br /&gt;
Winners go home and f*** the prom queen.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
Which one do you want to be?&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-5464320288405722092?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0h6AIAOyJarhGtQxOdJnJ3E3yvY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0h6AIAOyJarhGtQxOdJnJ3E3yvY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0h6AIAOyJarhGtQxOdJnJ3E3yvY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0h6AIAOyJarhGtQxOdJnJ3E3yvY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/w-olfswTAhk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/5464320288405722092/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=5464320288405722092" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5464320288405722092?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5464320288405722092?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/w-olfswTAhk/do-it-fuking-now.html" title="Do it Fu*king now!" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/05/do-it-fuking-now.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ANSHc9eip7ImA9WxFRGU0.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-248845001896878614</id><published>2010-05-03T09:50:00.000-07:00</published><updated>2010-05-03T09:56:39.962-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-03T09:56:39.962-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Team Foundation Server" /><category scheme="http://www.blogger.com/atom/ns#" term="TeamBuildService.exe" /><category scheme="http://www.blogger.com/atom/ns#" term="Team Build" /><category scheme="http://www.blogger.com/atom/ns#" term="Service Controller" /><category scheme="http://www.blogger.com/atom/ns#" term="frustration" /><category scheme="http://www.blogger.com/atom/ns#" term="won't work" /><category scheme="http://www.blogger.com/atom/ns#" term="sc.exe" /><title>Creating a new Team Build service with sc.exe and TeamBuildService.exe</title><content type="html">At work we've been transitioning over to Team Build 2008 from Cruise Control.NET 1.5. It's not that we have anything against CC.NET, in fact it's quite an amazing and versitle program. We are simply going in the direction to have everything in the same software stack.&lt;br /&gt;&lt;br /&gt;I do feel we will still use some CC.NET features from time to time and simply invoke the TFSBuild.exe instead. As a result, we will still get all our data pumped into the TFSBuild Store and no one will be the wiser.&lt;br /&gt;&lt;br /&gt;There are two ways to run the TFSBuildService. The one is interactive (command line mode) and the other is as a service. To run this as a service, you have to use the &lt;strong&gt;sc.exe&lt;/strong&gt; command.&lt;br /&gt;&lt;br /&gt;I struggled for a couple hours until I found this &lt;a href="http://www.msfn.org/board/program-service-t83272.html"&gt;post&lt;/a&gt;. Deep in there, you will see him mark out that &lt;strong&gt;after each = sign. There must be a space. &lt;/strong&gt;Otherwise it will keep running the syntax options and you go insane trying to figure out what you are doing wrong.&lt;br /&gt;&lt;br /&gt;Did this, worked perfectly.&lt;br /&gt;&lt;br /&gt;Hope this helps your trouble shooting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-248845001896878614?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C4TmUjnR55lwvt7NAJCZLmgi23U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C4TmUjnR55lwvt7NAJCZLmgi23U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C4TmUjnR55lwvt7NAJCZLmgi23U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C4TmUjnR55lwvt7NAJCZLmgi23U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/5r5Ns3n7Nis" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/248845001896878614/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=248845001896878614" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/248845001896878614?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/248845001896878614?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/5r5Ns3n7Nis/creating-new-team-build-service-with.html" title="Creating a new Team Build service with sc.exe and TeamBuildService.exe" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2010/05/creating-new-team-build-service-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4CQn05fip7ImA9WxFVGUg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-5352066846129916772</id><published>2009-12-15T20:34:00.000-08:00</published><updated>2010-06-19T07:49:23.326-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-19T07:49:23.326-07:00</app:edited><title>The power of parameterContainer and ITemplate</title><content type="html">Ok. Really trying to get back into blogging. Instead of always doing something complex, try to do something simple.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this case. I want to discuss an issue I was working with R.A.D. ComboBox this week.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I'm continuing work on the YakShaver. Working on a portion of the UI in which case I use logical groups to divide out customers from projects. These groups contain a very small number of elements, anywhere from 1-5. Picture a tree structure such that&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-Customer 1&lt;br /&gt;
&lt;br /&gt;
- Project 1&lt;br /&gt;
&lt;br /&gt;
- Project 2&lt;br /&gt;
&lt;br /&gt;
- Project 3&lt;br /&gt;
&lt;br /&gt;
-Customer 2&lt;br /&gt;
&lt;br /&gt;
- And So on...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One of the great things about Telerik RAD ComboBox is the ability to have separator items, to give the user an easier view of logical groupings. This used to require a lot of in depth work between css, javascript, but now I simply drag a control on a page, click a few things and I'm done with it and everything looks pretty. RadComboBox easily allows me to set the text of the separator item or just leave it blank to create a line.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It also allows us to be more creative by using the to add all sorts of pizazz to our combo box improving the user experience; which was exactly what I intended to do. In my case, I was turning the drop down into a checkbox that I would validate later.&lt;br /&gt;
&lt;br /&gt;
Hence came my problem.&lt;br /&gt;
&lt;br /&gt;
The item template is invoked for every RadItem that exists, regardless of if its a separator or not. Having a simple table to handle our structure doesn't work. In my case what happened was every combo item would render with a checkbox, including my separator items. I wanted to add some conditional logic that says "If this is a separator item, then display this, else this."&lt;br /&gt;
&lt;br /&gt;
Typically I would not put any sort of server side code in the UI, but this seemed to be one of the instances that it made the most sense. I wanted easy access to the the item being bound (the RadComboBoxItem) to tell if it was a separator. With no good way from what I could find with a declarative syntax, I thought about how I could do it conditionally inside item template.&lt;br /&gt;
&lt;br /&gt;
Problem, how do I access the item? Answer: parameterContainer.&lt;br /&gt;
&lt;br /&gt;
parameterContainer is of type System.Web.UI.Control that represents the item being injected into the template. In our case, it was the RadComboBoxItem. With a simple cast, I can access all the properties and methods in the aspx and get type safely (plus intellisense!).&lt;br /&gt;
&lt;br /&gt;
I can use the standard &amp;lt;% %&amp;gt; syntax and therefore not have to have a dependency of HTML within the code behind. Here is an example.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 1:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBox runat="server" ID="rcbComponentDeploySites" OnLoad="cmb_Load"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 2:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 3:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;% if (!(parameterContainer as RadComboBoxItem).IsSeparator)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 4:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 5:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 6:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table border="0"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 7:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 8:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; 9:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:CheckBox runat="server" ID="chkDeployToSite" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 10:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 11:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 12:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%# DataBinder.Eval(Container, "Attributes['DisplayName']") %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 13:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;lt;%# DataBinder.Eval(Container, "Text") %&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 14:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 15:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 16:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 17:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 18:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 19:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 20:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 21:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 22:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;table border="0"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 23:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 24:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;td style="border-bottom: 1px dotted black;"&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 25:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%# DataBinder.Eval(Container, "Attributes['DisplayName']") %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 26:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (&amp;lt;%# DataBinder.Eval(Container, "Text") %&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 27:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 28:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 29:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 30:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;%&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 31:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 32:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; %&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 33:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 34:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;Items&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 35:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" IsSeparator="true" Text="Customer 1 Sites" DisplayName="Customer 1 Sites" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 36:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" Text="Customer Site 1" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 37:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" Text="Customer Site 2" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 38:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" IsSeparator="true" Text="Customer 2 Sites" DisplayName="Customer 2 Sites" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 39:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" Text="Customer Site 1" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 40:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;telerik:RadComboBoxItem runat="server" Text="Customer Site 2" /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 41:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/Items&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; 42:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/telerik:RadComboBox&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This should be true of anything that implements ITemplate. It gives a great deal of flexibility to the UI and still allows for type safe programming.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-5352066846129916772?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BfqUxJ4vnlphs3PVhdo7v-agxV0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BfqUxJ4vnlphs3PVhdo7v-agxV0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BfqUxJ4vnlphs3PVhdo7v-agxV0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BfqUxJ4vnlphs3PVhdo7v-agxV0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/VpioNvoo0S4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/5352066846129916772/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=5352066846129916772" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5352066846129916772?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5352066846129916772?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/VpioNvoo0S4/power-of-parametercontainer-and.html" title="The power of parameterContainer and ITemplate" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2009/12/power-of-parametercontainer-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IFQn84eSp7ImA9WxVaEk0.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-5274980929696646566</id><published>2009-04-08T08:30:00.000-07:00</published><updated>2009-04-08T09:51:53.131-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T09:51:53.131-07:00</app:edited><title>It's been awhile!</title><content type="html">Yes... I know, I haven't blogged to my loyal following of 2 readers but times have been busy.&lt;br /&gt;&lt;br /&gt;Busy doing what?  Well, on December 5, 2008 my wife and I welcomed our two sons into the world at 12:01, and 12:02pm.  Evan Christopher Taylor and Ethan Bradley Taylor, and yes, they are identical.  &lt;br /&gt;&lt;br /&gt;To anyone that has had twins, or any kind of multiples for that matter, you know that first few months there isn't time for anything, much less blogging.  As part of having twins and the new found responsibilities of parenting, I've been retraining myself in the way I work?&lt;br /&gt;&lt;br /&gt;Why would you do that?&lt;br /&gt;&lt;br /&gt;Well, back in the day I used to be able to have 3-4 hours of non-stop quiet to complete my coding tasks.  Now, that time is shorted to anywhere from 15-45 minutes without distraction, so my ability to stare at code and trace deeply into a process is much more difficult.  &lt;br /&gt;&lt;br /&gt;As a result I've learned to think about code constantly.  Of course, I do that anyways, but instead of daydreaming of perfect transcendent systems with 4GLs, I think about the method I need to write for a problem.  Taking things at a very granular level, and planning it all in my head before I ever execute.  &lt;br /&gt;&lt;br /&gt;I'm sure this is the way we are "supposed" to do software development, but thats not nearly as fun as attaching a debugger, clicking something and following it down the path of where it goes.  Alas no more.&lt;br /&gt;&lt;br /&gt;Now that the boys are 4 months, I seem to have more time on my hands to actually write, perhaps I'll actually get to do it now!&lt;br /&gt;&lt;br /&gt;Based on some new happenings at work, I'll be shifting my focus to ASP.NET MVC + Team Foundation Server (and a little bit of workflow, but not as much, at least not until .NET4).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-5274980929696646566?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/iJBbRxrf5o09nz0ur4L4UYtuqCg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iJBbRxrf5o09nz0ur4L4UYtuqCg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/iJBbRxrf5o09nz0ur4L4UYtuqCg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/iJBbRxrf5o09nz0ur4L4UYtuqCg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/uEm-xprP_Nw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/5274980929696646566/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=5274980929696646566" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5274980929696646566?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5274980929696646566?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/uEm-xprP_Nw/its-been-awhile.html" title="It's been awhile!" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2009/04/its-been-awhile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEINQ38yeSp7ImA9WxRRFE0.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-6401338205981795049</id><published>2008-09-25T20:13:00.001-07:00</published><updated>2008-09-25T21:16:32.191-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-25T21:16:32.191-07:00</app:edited><title>Deploying Workflow Foundation Part 1.5 - Thread Safety and ExternalDataExchange</title><content type="html">*Sigh* another late night debugging a CI build that has been failing all day. And just as I fix the portion I know is wrong, I find that another delivery not related to anything I do broke another part of the build. And, it's going to take some digging to find the problem.&lt;br /&gt;&lt;br /&gt;So, before I get into that beast, I wanted to at least share a note on Thread Safety and using ExternalDataExchange interfaces.&lt;br /&gt;&lt;br /&gt;The first important thing to note is &lt;strong&gt;ExternalDataExchange&lt;/strong&gt; services live as&lt;strong&gt; singletons &lt;/strong&gt;in&lt;strong&gt; &lt;/strong&gt;the workflow runtime&lt;strong&gt;.&lt;/strong&gt; However, unlike our powerful new toy WCF, you are not guarunteed a singleton with proper thread blocking.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What does that mean?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If you haven't heard of Free Threading, that's pretty much what this is. Think about when you add an ExternalDataExchange service to the workflow runtime. When you do it in code, it would look something to the effect of.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using (WorkflowRuntime runtime = new WorkflowRuntime("WorkflowRuntimeConfigurationPT"))&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;  ExternalDataExchangeService dataExchangeService = new ExternalDataExchangeService();&lt;br /&gt;  MyWorkflowService service1 = new MyWorkflowService();&lt;br /&gt;  runtime.addService(dataExchangeService)&lt;br /&gt;  dataExchangeService.AddService(service1);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The important thing to note above is the construction of our Workflow service that we will use to perform whatever function we wish.  From our previous example it could be to update the database with information from the workflow state about an order, such as adding or removing an item.  &lt;br /&gt;&lt;br /&gt;We construct an instance of that service and let the runtime and dataexchange take that over.  But keep in mind, we constructed the instance (instead of referencing a type in which case the runtime would create instances as needed).  &lt;br /&gt;&lt;br /&gt;Often times we find ourselves being a bit lazy and not thinking about what exactly is going to be accessing instances of our classes.  Especially when we are not necessarily thinking about multi-threaded programming (I think WCF spoiled this for us).  After all, the application that &lt;b&gt;I&lt;/b&gt; wrote doesn't use the ThreadPool or anything else touching System.Threading.  &lt;br /&gt;&lt;br /&gt;But Workflow does.  &lt;br /&gt;&lt;br /&gt;What can happen is two workflows may reach a state in which they call the same method on the same interface.  Because you can only have only 1 instance of any interface loaded into a single runtime this can cause both threads from each workflow instance to "cross paths".  When debugging, some may notice this as "code jumping", where your running F10, and then all of a sudden your 3 lines before you were and not paying attention to your thread monitor window.  ;)  &lt;br /&gt;&lt;br /&gt;What can happen is the same thing in any free threaded application.  Always remember the basics of computers, a processor can only process a single instruction at a time.  And a line of code does not necessarily equal a single instruction (no where close ;)) so, the Thread Scheduler deep inside the OS will swap out different sequences of instructions from different processes at different times, not necessarily completing a logical set of instructions as we humans see it.  &lt;br /&gt;&lt;br /&gt;Sometimes this doesn't matter, however in most instances you may be using a class level or even method level variable, in which case if both threads are accessing the method at the same time, thread A sets a variable to 1 and thread B sets it to 2.  When thread A gets scheduled its next instruction, values that it originally had may not be there, leading to "weird" or "random" results and or exceptions.  Also, the most common example is that both thread A and B create a race condition where neither can exit a loop because of what the other one is doing.  &lt;br /&gt;&lt;br /&gt;I will not go into a huge speech of the importance of thread safety and how to do it, there are much better examples out there than what I will give you.  The key to take from this post is always think when developing your workflow services, "two workflow may access this code at the exact same time, what have I done to protect myself".  The easy thing to do is use of the &lt;b&gt;lock&lt;/b&gt; statement.  This will save you hours of headache later.  &lt;br /&gt;&lt;br /&gt;HTH&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-6401338205981795049?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/t_hAw9Mzt5FkCw9jRduTwwjDs70/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t_hAw9Mzt5FkCw9jRduTwwjDs70/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/t_hAw9Mzt5FkCw9jRduTwwjDs70/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/t_hAw9Mzt5FkCw9jRduTwwjDs70/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/GZYDBTQNck8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/6401338205981795049/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=6401338205981795049" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6401338205981795049?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6401338205981795049?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/GZYDBTQNck8/deploying-workflow-foundation-part-15.html" title="Deploying Workflow Foundation Part 1.5 - Thread Safety and ExternalDataExchange" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/09/deploying-workflow-foundation-part-15.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQGQ344fSp7ImA9WxRSFUo.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-7348054713176314578</id><published>2008-08-29T22:07:00.000-07:00</published><updated>2008-09-16T07:45:22.035-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-16T07:45:22.035-07:00</app:edited><title>Deploying Workflow Foundation Part 1 - Introduction and Solution Setup</title><content type="html">&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;It's been a long time since I've gotten a chance to write. I certainly had a number of topics to discuss, just no time to sit down and put them into words. Well, words that made sense.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I've decided to write about a topic that I thought needed some attention. I've seen a number of posts of people struggling with deploying and upgrading Workflow Foundation as well as dealing with the same issue in my professional life. Before that though...&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Over the past 8 weeks, my life has taken considerable changes both personally and professionally. No, I didn't leave my job, however, if you remember in previous posts, I work for a large financial institution, and my first few months were really nothing documentation. In my opinion not necessarily the most &lt;strong&gt;useful &lt;/strong&gt;documentation, but I digress. That all changed about 12 weeks ago with me being the onshore lead for an offshore project at work. &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Back to that in a moment...&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I wouldn't normally share something as personal on a technical blog, but for this, a small snippet is acceptable. Just over a year ago my wife and I lost our son Ryan at birth (he was 38 weeks). Of course, a tragic time and difficult for both of us. However in April we found out my wife was pregnant again. We were incredibly excited and as we made it past the first trimester we were anxiously awaiting the day to find out the gender. Of course, like any parents we started shopping for names, we quickly selected a girls name without any question (just as we had selected Ryan's). But we were stuck between two boys names. Well, that day came and looks like there was a reason we couldn't decide... We need 'em both. ;)&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Back to our regularly scheduled programming...&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;A little background on this project. We had 4 workflows, each being very simliar in soliciting some responses from various stakeholders in an operation and modifying data accordingly. Nothing too crazy. Now I obviously cannot share those workflows, so I've created a beginning to end + iterations example of using Windows Workflow in *any* environment which I will be sharing over the next few posts.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Ok let us take a process we all know. An online shopping cart system. To start off, I've created the most simple cart system that I can. It contains no data other than an ID (and that Id will be provided by the workflow engine). Below is what my state machine looks like. &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://4.bp.blogspot.com/_6Jl8T34_Y0Y/SLjbwrT3DeI/AAAAAAAAAAg/ogn8kRJ810E/s1600-h/SNAG-0000.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5240179795751800290" style="" alt="" src="http://4.bp.blogspot.com/_6Jl8T34_Y0Y/SLjbwrT3DeI/AAAAAAAAAAg/ogn8kRJ810E/s320/SNAG-0000.jpg" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;The workflow has 3 states. ShoppingCartState, OrderPlacedState, and OrderShippedState. The workflow responds to events from ExternalDataExchange decorated interfaces. &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;But before we get into all that. I want to talk about the solution layout and a very important thing about workflow that is overlooked. That my friends, is versioning, and how to properly version Workflow. &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;span style="font-weight: bold;"&gt;Microsoft's Provided Workflow Templates for VS2005 &amp;amp; VS2008&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm a huge Microsoft fan, so this isn't a complaint, just a clarification. The Workflow project templates that are included with the Workflow Extensions for VS2005 and VS2008 are not meant to be used in an almost *any* production environment other than one where either&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The workflow never changes&lt;/li&gt;&lt;li&gt;If upgraded, all existing data is either destroyed or migrated (sometimes &lt;span style="text-decoration: line-through;"&gt;always&lt;/span&gt; painfully).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;This doesn't sound like a very good situation in a large application or small. Truthfully, I've found that following the BizTalk solution layout seems to be the best way to easily change and upgrade workflows. And what exactly is that?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Interfaces Project - Version # should never change (next post I will cover how it can). This represents interfaces Workflow uses to communicate with External Services using the ExternalDataExchangeService.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;NOTE:&lt;/span&gt; Your interfaces project should also include enum's and inherited ExternalDataEventArgs.  If you don't, you will need to verify and possibly modify&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Workflow Project - Version # should change on nearly every deployment&lt;/li&gt;&lt;li&gt;Services Implementation Project - Version # should change on an as needed basis.&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Or, a picture is worth 1000 words.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_6Jl8T34_Y0Y/SLsFG0RC5UI/AAAAAAAAABI/Rxp25wERr2A/s1600-h/SNAG-0002.jpg"&gt;&lt;img style="cursor: pointer;" src="http://3.bp.blogspot.com/_6Jl8T34_Y0Y/SLsFG0RC5UI/AAAAAAAAABI/Rxp25wERr2A/s400/SNAG-0002.jpg" alt="" id="BLOGGER_PHOTO_ID_5240788206043194690" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have three projects of interest represented here. Now I have actually broken one of my own rules in which case I have joined the services implementation with my Workflow project. Though it isn't necessarily a best practice, the version # on the services is not nearly as important as the interface version # for this example. So we can cheat a little in this example.&lt;br /&gt;&lt;br /&gt;Also notice I've added a Strong Name key to my Workflow Project as well as the interface project. I have to add it to the interface project because it is referenced by the workflow project. The workflow project is strong named because I'm going to install it into the GAC. I could install the interface library in the GAC as well.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why should the interface version never change?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This seems to be the biggest "gotcha" when developing Workflow enabled applications.  It isn't a bug, but something very much meant by design.  Under the hood WF has it's own runtime that handles events through it's own messaging infrastructure.  If you look deep enough, you'll find the eventing model uses something similar to MSMQ to deliver an event message to a specified workflow.  It may actually be MSMQ, but I cannot say for sure at this point.  This way, the runtime handles the message delivery of an event without us having to worry about if the workflow is in the proper state to receive the event.  This post will not go into the details of guarunteed asynchronous message delivery, but it's a fun topic if you have the time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Why install the Workflow DLL in the GAC?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Simple, in most cases (even something like this shopping cart) we will have long running transactions. The process of getting the order into our warehouse may be fast, however, if we are shipping a physical item there may be a few days between shipping and updating it. Workflow offers persistence services for keeping these transactions alive through reboots, shutdowns, and whatever else may happen.&lt;br /&gt;&lt;br /&gt;Lets say we add a new step to the process, such as AtVendorState where we ship part of our order from a 3rd party vendor. When we deploy this, we still want our existing workflow to finish running the way they started, that way we don't have to come up with some sort of upgrade program or a completly separate deployment of the services and workflows.&lt;br /&gt;&lt;br /&gt;In order to allow both the old workflows and new workflows run in the same runtime with independent versions, we must install both workflow assemblies in the GAC and allow the runtime to determine which one it wants at any particular time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;We all admit, the workflow's have to change, not only that, but long running processes subscribe to one verison of the workflow and are intended to finish that way. After all, the runtime cannot determine how to properly transition version 1.0 of your workflow to version 1.1. &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;But you know what &lt;strong&gt;doesn't&lt;/strong&gt; change?  &lt;strong&gt;Interfaces&lt;/strong&gt;. Specifically I'm talking about the interfaces that are used to raise events into the workflow instance, and for the workflow instance to contact external systems (I know you can use WCF with 3.5, but we are only allowed to use up to 3.0 at work, and thankful for that). This was where I found the most "problems" when deploying workflow. &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;However, it wasn't as if the deployment was hard, it was realizing the exceptions we were getting even though we never changed anything but a version were because of strong rules in place and not problems other than that which the code is delivered.&lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;Workflow is a lot like BizTalk, in the way that it is *very* version dependent. However, BizTalk provides some niceties for binding between versions of send ports, receive ports and orchastrations. If you want that in workflow, you are doing it yourself.&lt;br /&gt;&lt;br /&gt;Look forward to part 2 where I talk more about ExternalDataExchange services and Thread Safety.  This is a huge topic and very easy to glaze over, but will start causing you more problems as the # of workflows (especially long running) continues to grow.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-7348054713176314578?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hPLUtPrDuUEdJJ6fKGCxNW6WcqE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hPLUtPrDuUEdJJ6fKGCxNW6WcqE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hPLUtPrDuUEdJJ6fKGCxNW6WcqE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hPLUtPrDuUEdJJ6fKGCxNW6WcqE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/t3poiUfFIwI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/7348054713176314578/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=7348054713176314578" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7348054713176314578?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7348054713176314578?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/t3poiUfFIwI/deploying-workflow-foundation-part-1.html" title="Deploying Workflow Foundation Part 1 - Introduction and Solution Setup" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6Jl8T34_Y0Y/SLjbwrT3DeI/AAAAAAAAAAg/ogn8kRJ810E/s72-c/SNAG-0000.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/08/deploying-workflow-foundation-part-1.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EGQHk9eCp7ImA9WxdSE0w.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-6668062894739259385</id><published>2008-05-20T14:18:00.000-07:00</published><updated>2008-05-20T14:40:21.760-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-20T14:40:21.760-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Team Foundation Server" /><category scheme="http://www.blogger.com/atom/ns#" term="CodePlex" /><category scheme="http://www.blogger.com/atom/ns#" term="ClearCase" /><category scheme="http://www.blogger.com/atom/ns#" term="TFS" /><category scheme="http://www.blogger.com/atom/ns#" term="YakShaver" /><category scheme="http://www.blogger.com/atom/ns#" term="UCM" /><title>YakShaver.NET = UCM+ for TFS</title><content type="html">I've been quiet recently.  Mainly because I've been flipping my house.  No, not to sell, but because I want to enjoy it that way.  We moved in just about 2 years ago, and never really touched a thing.  After August I had little motivation until recently, in which case I had more than I could imagine (perhaps quitting smoking helped).&lt;br /&gt;&lt;br /&gt;That isn't what this entry is about however (I'll post pics at a later time).  Well sort of.  My reason for taking the break was both because of the house and because I wasn't exactly sure what I wanted of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;YakShaver&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I should rephrase that, I knew what I wanted, however I didn't really have a method to my madness.  It was going in a number of different directions with no solid foundation to any of it.  Or for that matter, what was my starting point?&lt;br /&gt;&lt;br /&gt;At work, we use Rational &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;ClearCase&lt;/span&gt; UCM (Unified Change Management).  This is slightly different than Base &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;ClearCase&lt;/span&gt; (which is really just a glorified version of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;SubVersion&lt;/span&gt; from what some have told me) in the sense that it provides an overlay to the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SCM&lt;/span&gt; tool.  &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_5"&gt;Unfortunately&lt;/span&gt; at work, our &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;ClearCase&lt;/span&gt; admins do not necessarily explain all the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;intricacies&lt;/span&gt; of what UCM and how its terminology applies to more commonly known terms (such as Stream == Branch, View == Workspace, Deliver == Copy + Merge).&lt;br /&gt;&lt;br /&gt;Because there is very little explanation, most people seem to have a bad taste in their mouth about CC UCM, when in fact, it's rather brilliant.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ClearCase&lt;/span&gt; is still slow and kludgy and I'm more of a fan of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;TFS&lt;/span&gt; with the direct work item integration (rather than &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;Rational's&lt;/span&gt; other products such as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;RequisitePro&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;ClearQuest&lt;/span&gt; which integrate into CC+UCM).&lt;br /&gt;&lt;br /&gt;Brilliant?  IBM product?  Isn't this blasphemy from a .NET programmer and MS lover?  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;C'mon&lt;/span&gt;, we're all coders, whether that is Java or .NET, Ruby or Python.  IBM has good idea, MS has good ideas, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;Avanade&lt;/span&gt; comes up with good ideas and gives them to MS, the cycle goes on and on.  But I digress.&lt;br /&gt;&lt;br /&gt;So what exactly is the 50,000 foot view of UCM?  Let's look at what I consider to be the fundamental part, which is &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;UCM's&lt;/span&gt; branching strategy.  Again, UCM isn't anything special other than the fact it does some tasks for you.  So when you create a Stream, your creating a branch that can be isolated for the developer, they can check in their work without affecting &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;anyone elses code&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;We are all *supposed* to follow a branching strategy, however many times we get lazy and forget, UCM kind of prevents this, creating your private development stream and those changes get merged into an Integration Stream (aka Trunk.  though I should be careful, it doesn't necessarily mean trunk, especially if you have feature integration streams).&lt;br /&gt;&lt;br /&gt;When the developer has completed their activities (another term in UCM world, aka Work Items) and all works well, they deliver this to the integration stream, where all developers deliver work and do merging between elements to get a finalized product.&lt;br /&gt;&lt;br /&gt;The nice thing about Rational is they have a decent Merge/Diff tool that can handle most merging on it's own.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;TFS&lt;/span&gt; offers the same feature, though I haven't truly seen how well its merging capabilities are.  My previous experience on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;TFS&lt;/span&gt; was in a 3 person team that rarely every collided.  My current environment has 75+ developers, all doing their own thing and colliding quite often, UCM helps filter some of that.&lt;br /&gt;&lt;br /&gt;Now that I've said all that, to the point of the blog.  As I started to understand UCM more and more (especially during a CC upgrade recently) I realized this was exactly what I wanted out of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;YakShaver&lt;/span&gt;.NET.  A UCM like tool (that provided automatic branching strategy and merging, while taking advantage of other &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;TFS&lt;/span&gt; tools), but provides a bit more.  This is where the idea of "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;Sandboxing&lt;/span&gt;" comes into play.&lt;br /&gt;&lt;br /&gt;If I could take an integration stream/branch and deploy that version to a sandbox environment (isolated much like my development environment is) then I can accomplish the goal of working with Testers/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;QA&lt;/span&gt;/Clients in an isolated environment and keeping congruency between all of it using a friendly application.  This is where the UCM+ comes in (UCM plus a little more).&lt;br /&gt;&lt;br /&gt;I'm not sure if I can use this name or not, I'll have to find out, but it is the goal to turn &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;YakShaver&lt;/span&gt;.NET into a UCM type front end for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;TFS&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I'm glad I can finally put that in a single sentence.  Now that I know what I want to build, time to actually do it.  ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-6668062894739259385?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Jn50d8hmM_AwCoMILDhvI1ZnOpQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jn50d8hmM_AwCoMILDhvI1ZnOpQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Jn50d8hmM_AwCoMILDhvI1ZnOpQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jn50d8hmM_AwCoMILDhvI1ZnOpQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/gvOeqljm12M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/6668062894739259385/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=6668062894739259385" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6668062894739259385?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6668062894739259385?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/gvOeqljm12M/yakshavernet-ucm-for-tfs.html" title="YakShaver.NET = UCM+ for TFS" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/05/yakshavernet-ucm-for-tfs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcCRX0_eSp7ImA9WxZUEkg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-6205826109590678506</id><published>2008-04-03T13:51:00.000-07:00</published><updated>2008-04-03T13:54:24.341-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-03T13:54:24.341-07:00</app:edited><title>Another Awesome Tool for Remote Development</title><content type="html">I happened to catch this little gem inside Visual Studio at work.  I've been reading more by Scott Hanselman recently.  He had a great link to this wicked little tool called Microsoft SharedView.&lt;br /&gt;&lt;br /&gt;http://connect.microsoft.com/site/sitehome.aspx?SiteID=94&lt;br /&gt;&lt;br /&gt;Wow...  Be anywhere the world and get a code review.  Sick...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-6205826109590678506?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vl2LUKM6EVANNZvmObOX5Mta564/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vl2LUKM6EVANNZvmObOX5Mta564/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vl2LUKM6EVANNZvmObOX5Mta564/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vl2LUKM6EVANNZvmObOX5Mta564/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/yKK1pcteSI4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/6205826109590678506/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=6205826109590678506" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6205826109590678506?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/6205826109590678506?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/yKK1pcteSI4/another-awesome-tool-for-remote.html" title="Another Awesome Tool for Remote Development" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/04/another-awesome-tool-for-remote.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHQX46eSp7ImA9WxZXF0U.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-1750224790289956897</id><published>2008-03-05T21:01:00.000-08:00</published><updated>2008-03-05T21:10:30.011-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-05T21:10:30.011-08:00</app:edited><title>CC.NET + MS Test 2008 + New Template</title><content type="html">In a bit of YakShaving today I found the need to modify the MSTestSummary.xsl file for CC.NET so that it worked properly with the output from mstest.exe 2008.  I haven't seen if 2005 uses the same format or not. &lt;br /&gt;&lt;br /&gt;Anyways, hope some find this useful.  You can download it from my CodePlex site &lt;a href="http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=yakshaver&amp;amp;DownloadId=29215"&gt;here&lt;/a&gt;.  I'll see if ThoughtWorks wants to put it up on their site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-1750224790289956897?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/xxjresR2ZfsJINtP7kj50h4B4UU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xxjresR2ZfsJINtP7kj50h4B4UU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/xxjresR2ZfsJINtP7kj50h4B4UU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/xxjresR2ZfsJINtP7kj50h4B4UU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/eMAr2Bd5Xhk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/1750224790289956897/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=1750224790289956897" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/1750224790289956897?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/1750224790289956897?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/eMAr2Bd5Xhk/ccnet-ms-test-2008-new-template.html" title="CC.NET + MS Test 2008 + New Template" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/03/ccnet-ms-test-2008-new-template.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUCSHw-eip7ImA9WxZXE00.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-8636282270756701852</id><published>2008-02-29T07:36:00.000-08:00</published><updated>2008-02-29T07:51:09.252-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-29T07:51:09.252-08:00</app:edited><title>Interesting Distinction Between BizTalk 2006 and Workflow</title><content type="html">I've been working with Workflow Foundation quite a bit lately and even had  the opportunity to be teaching it to my design team at work about it's intricacies (which has been a lot of fun as well).&lt;br /&gt;&lt;br /&gt;Coming from a BizTalk background also makes it exciting to see the differences between it and WF and how they are similar.  Something neat about BizTalk is its use of Send Ports and Send Groups, which allows multiple services to be informed of an event within an orchestration (the equivalent to a sequential workflow in WF).  With a send port, I could theoretically have multiple instances of the same type of service with small differences between the two and use correlation to deal with events back from multiple data sources.&lt;br /&gt;&lt;br /&gt;However in WF, it isn't quite the same.  Given everything is interface driven that is what the WF Runtime is looking at, so if I try to add multiple services of the same interface to the DataExchangeService an exception is thrown with the following message&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"An instance of ExternalDataExchangeService of type TestWorkflowApp.IApproverService already exists in the runtime container."&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The code that I used to do this is pretty simple.  I created another class (although it would appear I could just instantiate another instance of my ApproverService class) which was the exact same implementation (just a different name).  Then tried to add both to the Data Exchange Service as so&lt;br /&gt;&lt;br /&gt;dataExchangeService.AddService(approverService);&lt;br /&gt;dataExchangeService.AddService(secondApproverService);&lt;br /&gt;&lt;br /&gt;Exception thrown.&lt;br /&gt;&lt;br /&gt;I suppose there should be some major distinctions in capability between a free product that is part of the framework like Workflow vs. a 25k+ product like BizTalk.  Certainly BizTalk offers much more than a workflow runtime (far beyond the scope of this blog) but thought it was important to point out some differences.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-8636282270756701852?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bsUOC1UydeIaJ_YgsLWWk7IZorQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bsUOC1UydeIaJ_YgsLWWk7IZorQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bsUOC1UydeIaJ_YgsLWWk7IZorQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bsUOC1UydeIaJ_YgsLWWk7IZorQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/lnMTrJrPEI0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/8636282270756701852/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=8636282270756701852" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/8636282270756701852?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/8636282270756701852?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/lnMTrJrPEI0/interesting-distinction-between-biztalk.html" title="Interesting Distinction Between BizTalk 2006 and Workflow" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/interesting-distinction-between-biztalk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAMQXoyeCp7ImA9WxZXEEU.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-4276441866292364955</id><published>2008-02-26T19:14:00.000-08:00</published><updated>2008-02-26T21:06:20.490-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-26T21:06:20.490-08:00</app:edited><title>Nested State Activities in Windows Workflow</title><content type="html">By pure accident today I stumbled upon Nested State Activities, and of course my curiosity got the best of me in finding out what exactly these things are, how they worked, and who had done anything with it.&lt;br /&gt;&lt;br /&gt;A quick Google search for Nested State Activity didn't turn up much, except an article on MSDN stating that they were beyond the scope of this article.  Still, good article on state machines, you can find it &lt;a href="http://msdn.microsoft.com/msdnmag/issues/08/02/WFStateMachines/default.aspx"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Searching a little further, I found an article that somewhat covered it although they didn't use WWF, instead their own state machine toolkit.  Also a good read and can be found &lt;a href="http://www.codeproject.com/KB/cs/statemachinetoolkitprtiii.aspx"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However I still haven't found much on these things in WWF...  So, I decided to play a little.  Why not right?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First, lets just look at what a nested state looks like compared to the other in the designer.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_6Jl8T34_Y0Y/R8Tg8EH_EHI/AAAAAAAAAAY/WDL0XGKgSjE/s1600-h/state1.jpg"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_6Jl8T34_Y0Y/R8Tg8EH_EHI/AAAAAAAAAAY/WDL0XGKgSjE/s320/state1.jpg" alt="" id="BLOGGER_PHOTO_ID_5171505594632179826" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Given of course this is a simplistic example at first, so lets explore it a little more.  The first question that I asked was "What would I ever need this for?"  And to tell you the truth, I don't have a for sure answer for that. &lt;br /&gt;&lt;br /&gt;What I have seen so far is that if a state houses other state (in our example above &lt;span style="font-weight: bold;"&gt;stateActivity1 &lt;/span&gt;containing &lt;span style="font-weight: bold;"&gt;stateActivity2 &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;stateActivity3)&lt;/span&gt; you cannot set that state from another SetState activity.  An example of this is from the BuildPublished State I can set the next state to &lt;span style="font-weight: bold;"&gt;stateActivity2&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;stateActivity3&lt;/span&gt; or itself for that matter.  however, I cannot set the state to &lt;span style="font-weight: bold;"&gt;stateActivity1&lt;/span&gt;. &lt;br /&gt;&lt;br /&gt;Something intereting however, &lt;span style="font-weight: bold;"&gt;stateActivity1&lt;/span&gt; can have events handling scopes associated with it.  So it appears the event can respond when the the current state is within one of the sub states. &lt;br /&gt;&lt;br /&gt;I haven't found a great use of this yet, however the ability to have substates does add a new level of capability that I never realized.  I guess an example of its use may be a help desk application in which case when an issue is resolved you may have substates such as post-mortum review, develop action plan, and something else. &lt;br /&gt;&lt;br /&gt;I may explore this more later if I see a need, but thought it was cool nonetheless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-4276441866292364955?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4CSr1L98OickvKmfj64qgU3otAc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4CSr1L98OickvKmfj64qgU3otAc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4CSr1L98OickvKmfj64qgU3otAc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4CSr1L98OickvKmfj64qgU3otAc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/o9cbzvZ6dTc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/4276441866292364955/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=4276441866292364955" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/4276441866292364955?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/4276441866292364955?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/o9cbzvZ6dTc/nested-state-activities-in-windows.html" title="Nested State Activities in Windows Workflow" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_6Jl8T34_Y0Y/R8Tg8EH_EHI/AAAAAAAAAAY/WDL0XGKgSjE/s72-c/state1.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/nested-state-activities-in-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ICRnY8eSp7ImA9WxZQFkg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-8625108519214347160</id><published>2008-02-21T19:15:00.000-08:00</published><updated>2008-02-21T19:39:27.871-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-21T19:39:27.871-08:00</app:edited><title>Integration Testing Woes with TFS WorkItemStore</title><content type="html">Working with YakShaver I've been worried about how I was going to test without setting up a full Team Foundation environment (which is a challenge sometimes in itself, well, it's just a tedious job).  Also if I make a mistake, I'm looking at quite a bit of time to rebuild my environment.  &lt;br /&gt;&lt;br /&gt;This was a challenge until I realized that Microsoft has released VPC images of TFS for download that is the full environment all setup and ready to go.  Yes, the image expires on April 1, but they will release more images after that.  And I'm not as worried about keeping code there as I'm' testing against working with the TFS API.  &lt;br /&gt;&lt;br /&gt;Add in the fact that Virtual PC 2007 is now a free download and we have an instant environment for testing.  The machine name stays the same (TFSRTM08) so I can just setup simple constants in my unit tests for connectivity.  However, this isn't what this entry is about.  Just letting people know its useful.  &lt;br /&gt;&lt;br /&gt;In working with this image I ran into an issue where I would create an area and want to instantly use it.  I know from experience with the Team Explorer that if you create a new work item, then add an area or iteration and want to use that in the work item you created previously you must refresh the work item page so the new Area's and Iterations show up.  &lt;br /&gt;&lt;br /&gt;However, there seems to be a bit of delay with using the VPC (at least I think so).  Using the .RefreshCache() or .SyncToCache() methods on the WorkItemStore class seem a bit sketchy.  They would work 1/3 times in my testing.  &lt;br /&gt;&lt;br /&gt;I didn't want my implementation to constantly check for an area because that could get it caught in an infinite loop.  So in my testing class I create the area, and then wait until the workItemStore.Projects[ProjectName].AreaRootNodes[areaName] is available (you have to wrap in a try catch because if you try to get it and it doesn't exist you will get a ClientDeniedOrNotFoundException.  &lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: Consolas, "Courier New", Courier, Monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;  &lt;span class="kwrd"&gt;bool&lt;/span&gt; areaFound = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;            &lt;span class="kwrd"&gt;while&lt;/span&gt; (!areaFound) &lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;try&lt;/span&gt; &lt;br /&gt;                {&lt;br /&gt;                    System.Threading.Thread.Sleep(3000);&lt;br /&gt;                    tfsWorkItemStore.RefreshCache();&lt;br /&gt;                    &lt;span class="kwrd"&gt;string&lt;/span&gt; tempArea = tfsWorkItemStore.Projects[currentProject.Name].AreaRootNodes[area].Path;&lt;br /&gt;                    areaFound = &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;span class="rem"&gt;// iif it isn't found an exception is thrown never getting to this.&lt;/span&gt;&lt;br /&gt;                    &lt;br /&gt;                } &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception ex) {&lt;br /&gt;                    areaFound = &lt;span class="kwrd"&gt;false&lt;/span&gt;;&lt;br /&gt;                }&lt;br /&gt;            }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I could use the contains method, but it looks for an instance of a Node and not just a string representation.  This just seemed easier at the time to solve my problem without causing huge issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-8625108519214347160?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/D0YARKKIvNmm5sqK3o-hAy3LE4Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D0YARKKIvNmm5sqK3o-hAy3LE4Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/D0YARKKIvNmm5sqK3o-hAy3LE4Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/D0YARKKIvNmm5sqK3o-hAy3LE4Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/V0u7LtzMkdQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/8625108519214347160/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=8625108519214347160" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/8625108519214347160?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/8625108519214347160?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/V0u7LtzMkdQ/integration-testing-woes-with-tfs.html" title="Integration Testing Woes with TFS WorkItemStore" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/integration-testing-woes-with-tfs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQCR3o9eip7ImA9WxZQEU4.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-3571749899654277651</id><published>2008-02-15T20:56:00.000-08:00</published><updated>2008-02-15T21:06:06.462-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-15T21:06:06.462-08:00</app:edited><title>TDD + VP + DNN</title><content type="html">&lt;a href="http://www.dotnetnuke.com/Community/Blogs/tabid/825/BlogID/20/Default.aspx"&gt;Phil Beadle&lt;/a&gt; from DNN has a &lt;a href="http://www.dotnetnuke.com/Community/Blogs/tabid/825/EntryID/1732/Default.aspx"&gt;new post&lt;/a&gt; up adding in a layer of abstraction in the UI for better testability.  At work we've been working with the same model (although I believe Phil has modified it some) and found it pretty good for testing the UI and reducing places for failure.  &lt;br /&gt;&lt;br /&gt;He mentions using Rhino Mocks which I've been taking a look at as well recently.  Pretty cool stuff, but make sure you read up on identifying Mocks vs. Stubs.  This framework can do a lot of things, it's strongly typed, has natural syntax, and pretty much endless possibilities.  &lt;br /&gt;&lt;br /&gt;I've personally been struggling between this model and MVC (such as Microsoft's new ASP.NET MVC pattern that Scott Guthrie and Phil Haack have been blogging about).  They use very similar language but are pretty different in the end.  I think MVP is a little bit easier to implement but MVC is easier to test.  Both provide great mechanisms for testing though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-3571749899654277651?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/143vcv69WKZ7cJjimyWeiK8HoEg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/143vcv69WKZ7cJjimyWeiK8HoEg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/143vcv69WKZ7cJjimyWeiK8HoEg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/143vcv69WKZ7cJjimyWeiK8HoEg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/aGijj4xBBko" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/3571749899654277651/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=3571749899654277651" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/3571749899654277651?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/3571749899654277651?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/aGijj4xBBko/tdd-vp-dnn.html" title="TDD + VP + DNN" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/tdd-vp-dnn.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8NSX87eip7ImA9WxZRF0s.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-5568136654653223439</id><published>2008-02-11T12:43:00.000-08:00</published><updated>2008-02-11T12:48:18.102-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-11T12:48:18.102-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Integration Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Unit Testing" /><category scheme="http://www.blogger.com/atom/ns#" term="Tools" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax" /><title>Cool Automated Testing Tool</title><content type="html">Found this tool on a buddy of mine's blog.  Looks pretty cool.  One of the downfalls I've seen in a lot of webtesting tools (including MSTest, HP QTP, etc) is the lack of good support for Ajax calls.  QTP offers the ability to set "delays" however this is more of a hack than a good Ajax testing solution.&lt;br /&gt;&lt;br /&gt;By no means do I think testing Ajax, or for that matter even developing an Ajax testing system is a small task.  Why do you think I'm looking for tools? &lt;br /&gt;&lt;br /&gt;http://www.artoftest.com/Products.aspx&lt;br /&gt;&lt;br /&gt;That is the link.  Hopefully I'll get some time to play with this thing a little later.  I still need to finish a post on integration testing with Workflow this evening, so that will take priority.  But next weekend is a 3 day weekend, so you never know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-5568136654653223439?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/a9hATiU4Hjh6CzA-ctWHc2GjUZ8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a9hATiU4Hjh6CzA-ctWHc2GjUZ8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/a9hATiU4Hjh6CzA-ctWHc2GjUZ8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/a9hATiU4Hjh6CzA-ctWHc2GjUZ8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/37Up5Pc5zZA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/5568136654653223439/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=5568136654653223439" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5568136654653223439?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/5568136654653223439?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/37Up5Pc5zZA/cool-automated-testing-tool.html" title="Cool Automated Testing Tool" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/cool-automated-testing-tool.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8AR3w4fip7ImA9WxZQEEg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-7207247717053222834</id><published>2008-02-10T20:19:00.000-08:00</published><updated>2008-02-14T21:20:46.236-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-14T21:20:46.236-08:00</app:edited><title>Windows Workflow Integration Testing - Part I</title><content type="html">&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;.csharpcode, .csharpcode pre&lt;br /&gt;{&lt;br /&gt; font-size: small;&lt;br /&gt; color: black;&lt;br /&gt; font-family: Consolas, "Courier New", Courier, Monospace;&lt;br /&gt; background-color: #ffffff;&lt;br /&gt; /*white-space: pre;*/&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode pre { margin: 0em; }&lt;br /&gt;&lt;br /&gt;.csharpcode .rem { color: #008000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .kwrd { color: #0000ff; }&lt;br /&gt;&lt;br /&gt;.csharpcode .str { color: #006080; }&lt;br /&gt;&lt;br /&gt;.csharpcode .op { color: #0000c0; }&lt;br /&gt;&lt;br /&gt;.csharpcode .preproc { color: #cc6633; }&lt;br /&gt;&lt;br /&gt;.csharpcode .asp { background-color: #ffff00; }&lt;br /&gt;&lt;br /&gt;.csharpcode .html { color: #800000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .attr { color: #ff0000; }&lt;br /&gt;&lt;br /&gt;.csharpcode .alt &lt;br /&gt;{&lt;br /&gt; background-color: #f4f4f4;&lt;br /&gt; width: 100%;&lt;br /&gt; margin: 0em;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.csharpcode .lnum { color: #606060; }&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;And now for my first "official" post. In this post we are going to take a look at Integration Testing with a bunch of technologies, in particular Windows Workflow Foundation, MSTest, and Rhino Mocks (a little). In my next post I may get into more with NCover, but I figure it is too much at this point.&lt;br /&gt;&lt;br /&gt;To start, why do I use &lt;span style="font-weight: bold;"&gt;integration testing&lt;/span&gt; and not &lt;span style="font-weight: bold;"&gt;unit testing&lt;/span&gt;. Recently, both in work and among many professionals and hobbyists I've seen a lot of people distinguishing the two, which I whole heartedly agree with. I think a good testing strategy is a combination of both, as well as a number of other types of testing as well.&lt;br /&gt;&lt;br /&gt;Unit testing a workflow activity doesn't really make sense. After all a workflow represents some series of activities executing at specified times or response to events external to the system. A powerful tool though is the ability to repeat the tests that the workflow will go through in an automated fashion. This post looks to cover how I approached the situation and some reasonings behind it.&lt;br /&gt;&lt;br /&gt;The workflow we are using is a rather simple sequential workflow but more complex than some other workflows we see in a lot of demos/tutors. We use a Delay Activity, a couple CallExternalMethodActivity 's, Listen, HandleExternalEventActivity, Policy, and a few loops.  Something a little closer to what we would see in the real world, as well as &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; being related to an order.  ;) Below is a screen shot of the workflow.  Click on it for a larger image.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_6Jl8T34_Y0Y/R6_NSEH_EGI/AAAAAAAAAAQ/jaO0Nm0haBM/s1600-h/SNAG-0000.jpg"&gt;&lt;img style="cursor: pointer; width: 344px; height: 486px;" src="http://1.bp.blogspot.com/_6Jl8T34_Y0Y/R6_NSEH_EGI/AAAAAAAAAAQ/jaO0Nm0haBM/s320/SNAG-0000.jpg" alt="" id="BLOGGER_PHOTO_ID_5165573007845822562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;What does it do?  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the first workflow from my new project on CodePlex called &lt;a href="http://www.codeplex.com/yakshaver"&gt;YakShaver.NET.&lt;/a&gt;  The purpose of this workflow is to take an item submitted from YaKapture (a Screen Capture &amp;amp; Work Item Entry User Control) run it through an IAnalysisService (used to map context information (user,page) to the workitem tracker data such as Component, Release in CodePlex and/or TFS).  Let's walk through it from a high level perspective.&lt;br /&gt;&lt;br /&gt;1) A Consumer Service (YaKapture Screen Capture/Work Item Entry User Control) submits an instance of IWorkItemDataContract.  This in turn is passed into the workflow when it is created.&lt;br /&gt;2) CallExternalMethodActivty is used to call the IAnalysisService.AnalyzeSubmittedWorkItem which looks at the data contract and returns an instance of YakShaverWorkItem.  I'm not sure if I want to do this or I want to just use the same data contract throughout the entire workflow.  For now, it's separate.&lt;br /&gt;3) From the results of this service, we run a policy over the data to determine if the item needs intervention, meaning that someone must come in and assign either one of all of the required items for a CodePlex issue, this being Component, Release, Work item Type, Impact Type, Title and Description.  The goal is to infer as much data as possible by information quietly passed from YaKapture along with the user data submitted.  Such as anything with the path /qabuild1_2_07 knows it is associated with a release called QA Build 1.2.07.&lt;br /&gt;4) If intervention is needed, we call out to a noticiation service (INotificationService) which can implement any method it wants to notify someone to intervene on this item so it can go in the Work Item tracker (or if needs to go to the helpdesk?)&lt;br /&gt;5) A Listen tree is implemented, a Delay Activity on one side (which you can pass in the delay between notifications through the parameters passed in at CreateWorkflow) and a HandleExternalEventActivity on the other.  At this point the workflow will continue to notify the service for eternity until it is handled.  A more realistic approach in the future may be to set up some sort of approval tree in the notification service, unncessary for now.&lt;br /&gt;6) When the handleExternalEvent happens the workflow sets the intervened flag to true, thus ending the inner while loop.  This then takes us to the top of the workflow where we re-run our analysis service and policy, determing again if we need intervention.&lt;br /&gt;7) When everything is finally taken care of, we call a IWorkItemProviderService.CreateWorkItem which creates the work item in the issue tracker.  At this point the outer while loop knows the break, and the workflow completes as normal.&lt;br /&gt;&lt;br /&gt;We could incorporate this workflow into a larger workflow or perhaps into a state machine, that is one of the beauties of WWF.  At least I think so.&lt;br /&gt;&lt;br /&gt;Now we know what the workflow does, how do we test it?&lt;br /&gt;&lt;br /&gt;There are three integration tests that I have setup&lt;br /&gt;&lt;br /&gt;1) Test to see that the notification service is called and data contract data is read&lt;br /&gt;2) Test to see that when notified a user can resubmit the data contracted with updated information, and when it does, the work item created process is called and the workflow completes.&lt;br /&gt;3) Test to see when a notified user does not respond in a certain time, that notification is sent again.  Maintaining the number of times the service has been called.&lt;br /&gt;&lt;br /&gt;WWF is supringly easy to setup for integration testing within any testing framework, whether that is NUnit, MBUnit, or MSTest.  I am using MSTest in this example, but an NUnit conversion would be a minimal effort.&lt;br /&gt;&lt;br /&gt;Let's look at the first test, to see if the notification service is called and data contract is read.  A delay activity keeps the workflow from going into hyper drive and repeating the loop at a ridiculous rate.  Plus, we are just attempting to test the workflow, we want to keep as many things constant in order to reduce the number of failure points in the test (especially important as we regression test).&lt;br /&gt;&lt;br /&gt;I've divided my services into pretty granular pieces, each having one method and maybe one event (not all interfaces had events at least at the time of this blogging).  This provides a couple advantages:&lt;br /&gt;&lt;br /&gt;1) By being granular I can narrow the points of failure in my process, this also allows me to toy with code both in and out of process and more easily measure code coverage (at least I think so)&lt;br /&gt;2) Independently mocking each service to test how each one performs under conditions independent of other factors (i.e. services), including the workflow process itself.&lt;br /&gt;&lt;br /&gt;There are a few things to consider when testing workflow (I love lists)&lt;br /&gt;&lt;br /&gt;1) Requires the WorkflowRuntime to be instantiated, suprisingly I found you can host multiple runtimes in a process (at least you can start multiple ones, something to explore in a later post...)  This part is as simple as creating an instance and starting the runtime.&lt;br /&gt;2) A lot of people (and I was certainly one of them) think that communication is as simple as calling certain .NET classes.  It is close to that, but there is a communication layer within workflow that has to be considered.  The simplest way to communicate with the hosting application (i.e. the testing host) is using the ExternalEvent and ExternalMethod activities.  However this requires having an interface defined to communicate, implementing a service and those activities.  A bit much for testing and then possibly having to rip it out for production.  Say hello to Tracking Services!&lt;br /&gt;3) Versioning - this can cause oddities if you test a workflow, modify it and run the new version again without changing the version #.  I find it easiest to simply delete all necessary data in the tracking and persistence db, or redeploy the database script on each test run (effective, but can get out of control if you don't manage it)&lt;br /&gt;4) WorkflowMonitor - comes with the SDK, probably one of your best visual test coverage tools, puts little check marks over every activity that gets called.  For fun you could extend  this application more to count times it was called (useful inside of loops)&lt;br /&gt;&lt;br /&gt;With that out of the way.&lt;br /&gt;&lt;br /&gt;First, I need to setup the workflow runtime.  Using a Unit Test template from MSTest I uncomment out the [ClassInitialize].  Because I am using events and methods to communicate, I need to add a data exchange service.&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;   [ClassInitialize()]&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; MyClassInitialize(TestContext testContext) {&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            sqlTrackingConnectionString = &lt;span class="str"&gt;"Data Source=.\\SQLExpress;Initial Catalog=WFTracking;integrated security=true;"&lt;/span&gt;;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            sqlPeristenceConnectionString = &lt;span class="str"&gt;"Data Source=.\\SQLExpress;Initial Catalog=WFPersistence;integrated security=true;"&lt;/span&gt;;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            &lt;span class="rem"&gt;// recreate the tracking db&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="rem"&gt;// recreate the persistance db&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;            &lt;span class="rem"&gt;// initialize the runtime&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            workflowRuntime = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkflowRuntime();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            dataExchangeService = &lt;span class="kwrd"&gt;new&lt;/span&gt; ExternalDataExchangeService();&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            workflowRuntime.AddService(dataExchangeService);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;            &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            SqlTrackingService sqlTrackingService = &lt;span class="kwrd"&gt;new&lt;/span&gt; SqlTrackingService(sqlTrackingConnectionString);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            SqlWorkflowPersistenceService sqlPersistanceService = &lt;span class="kwrd"&gt;new&lt;/span&gt; SqlWorkflowPersistenceService(sqlPeristenceConnectionString);&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            workflowRuntime.AddService(sqlTrackingService);&lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;            workflowRuntime.AddService(sqlPersistanceService);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            workflowRuntime.StartRuntime();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;In the example above I've added a tracking service and a persistence service as well as the data exchange service.  These are default services that come with WF, and work perfectly for our testing situation.&lt;br /&gt;&lt;br /&gt;This is only fired when the test run starts.  We can remove all these services and shutdown the workflow runtime on another method for [ClassCleanup].  Shutdown can be somewhat important because it will persist your workflows, a nice thing when your trying to debug what exactly is happening.&lt;br /&gt;&lt;br /&gt;Finally a test!&lt;br /&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;div class="csharpcode"&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[TestMethod, TestProperty(&lt;span class="str"&gt;"Category"&lt;/span&gt;, &lt;span class="str"&gt;@"Workflow\Integration\NotificationServiceTests"&lt;/span&gt;)]&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; TestNotifyForIntervention()&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        {&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            INotificationDummyService notificationService = &lt;span class="kwrd"&gt;new&lt;/span&gt; INotificationDummyService();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            IAnalysisDummyService analysisService = &lt;span class="kwrd"&gt;new&lt;/span&gt; IAnalysisDummyService();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            AutoResetEvent wfIdledEvent = &lt;span class="kwrd"&gt;new&lt;/span&gt; AutoResetEvent(&lt;span class="kwrd"&gt;false&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; namedParameters = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt;();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;            IWorkItemDataContract dataContract = &lt;span class="kwrd"&gt;new&lt;/span&gt; WorkItemDataContractDummyObject();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            DataExchangeService.AddService(notificationService);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            DataExchangeService.AddService(analysisService);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;            namedParameters.Add(&lt;span class="str"&gt;"WorkItemDataContract"&lt;/span&gt;, dataContract);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;            WorkflowInstance workflowInstance = WorkflowEngine.CreateWorkflow(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(WorkItemEntryWorkflow), namedParameters);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;            &lt;span class="rem"&gt;// attach events if I want.&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            WorkflowEngine.WorkflowPersisted += &lt;span class="kwrd"&gt;delegate&lt;/span&gt; (&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, WorkflowEventArgs args) &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;            {&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; (args.WorkflowInstance.InstanceId == workflowInstance.InstanceId)&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;                    wfIdledEvent.Set();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;            };&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;            workflowInstance.Start();&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            wfIdledEvent.WaitOne(&lt;span class="kwrd"&gt;new&lt;/span&gt; TimeSpan(0, 0, 60), &lt;span class="kwrd"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;            &lt;span class="rem"&gt;//grab the latest from the persistence store.  If it doesn't find it, an exception will be thrown&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;            workflowInstance = WorkflowEngine.GetWorkflow(workflowInstance.InstanceId);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            Assert.IsTrue(notificationService.NotifyForInterventionMethodCallCount &amp;gt; 0, &lt;span class="str"&gt;"Notification Service did not return that it sent notification"&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        }&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;Lets start by looking at a few key lines.  First, lines 4 &amp;amp; 5.  We declare two services with the naming convention &lt;interface&gt;DummyService.  These are pretty much exactly what they sound like, stubbed implementations of a number of interfaces that could exist.  We use dummy services in this case to again reduce the points of failure in our testing scenario.  We'll have a chance later on to plug in "real' services to see how they respond when integrated into the workflow. &lt;br /&gt;&lt;br /&gt;If we look at these implementations we similar they are not much different than something we could do with a mocking framework.  However, I didn't have enough experience with mocking frameworks, and second I was having trouble because of the need for the SerializableAttribute.  Not as pretty, but accomplishes the same thing.  Instead of verifying mock expectations, we assert that a method was called (proof the workflow is doing what we expect it to). &lt;br /&gt;&lt;br /&gt;Line 8 instantiates a dummy instance of IWorkItemDataContract, which is used in multiple places in our application.  I shouldn't say dummy object in this sense because it does have some intelligence.  By that I mean depending the how many times a method is called, it responds with different output to aid the workflow in later tests.  I realize I could keep this in yet another dummy class however I just don't see the need right now. &lt;br /&gt;&lt;br /&gt;On line 13 we add the semi smart datacontract to the parameter collection that we are going to pass into the start of the workflow.  One of the important things to remember about WWF is there are specific ways to communicate with the instances in the runtime.  I won't go into detail in this post, but using a Dictionary&lt;string,&gt; is an easy way to set any public property on the workflow class.  We need to do this because our workflow demands it almost immediately for the analysis service. &lt;br /&gt;&lt;br /&gt;Some may notice I'm using an anonymous method on the workflow persisted event.  This checks to see if the workflow that was persisted was the one we created, and if so to trigger an AutoResetEvent.  Why persisted?  It certainly isn't necessary, and not possible without adding a persistence service to the runtime.  Idled would work just as well but I want to make sure that I can get the workflow from the persistence store.  Which I do in line 29. &lt;br /&gt;&lt;br /&gt;Finally I do one assertion on the service to make sure the workflow called it. &lt;br /&gt;&lt;br /&gt;I run my tests through MStest on the test list and bingo!  We go green!&lt;br /&gt;&lt;br /&gt;You can download this code from the latest change from the codeplex project changeset 4960&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-7207247717053222834?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ITzy_r565uRy9MM7esOUEB3ouyo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ITzy_r565uRy9MM7esOUEB3ouyo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ITzy_r565uRy9MM7esOUEB3ouyo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ITzy_r565uRy9MM7esOUEB3ouyo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/rXPh16FzY5U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/7207247717053222834/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=7207247717053222834" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7207247717053222834?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/7207247717053222834?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/rXPh16FzY5U/windows-workflow-integration-testing.html" title="Windows Workflow Integration Testing - Part I" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_6Jl8T34_Y0Y/R6_NSEH_EGI/AAAAAAAAAAQ/jaO0Nm0haBM/s72-c/SNAG-0000.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/windows-workflow-integration-testing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHQnozfyp7ImA9WxZRFEg.&quot;"><id>tag:blogger.com,1999:blog-1761229997634861862.post-504964830258041005</id><published>2008-02-07T21:11:00.000-08:00</published><updated>2008-02-07T21:57:13.487-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-07T21:57:13.487-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Intro" /><title>First Post</title><content type="html">I've always wanted a blog.  I've read so many over the years that have helped me as a developer I figured I might as well try to participate as well.  I realize it will be a long time until any (if ever) reads this.  It's nice to think they would, but if not, hey, It's for my own sanity. &lt;br /&gt;&lt;br /&gt;The basics.  I work for a large company that shall remain nameless in Chicago, good people.  MASSIVE development team.  Much larger than anything I have ever worked with and we are masters of documentation.  Many of us joke about how much of a waterfall approach it is, even though we try to implement little agile methodologies such as continuous integration, unit testing, integration testing, and recently getting into mock objects.   However releases are many months apart, and most of the time in a release is spent documenting and having meetings.  Given the nature of our business, I see that as important, and we are trying to find a good approach to giving the old guard what they want, while trying to adopt more agile methods to give users what they are demanding. &lt;br /&gt;&lt;br /&gt;We suffer from the same things many others do, system that was converted over from a good legacy system which would have been &lt;span style="font-weight: bold;"&gt;just fine&lt;/span&gt; if they had gone ASP -&gt; ASP.NET.  But alas, no.  Some crazy architect (also to remain nameless) wanted to make it all enterprisey by creating his vision of transcendent/super pluggable framework software.  You know, the software that is perfect for any application and can scale, yada yada.  That sales pitch you almost dread, well this is the end result of that sales pitch.  I will say that I applaud the creators effort as I think it is academically brilliant, and I'm impressed by how he put it together.  But it creates unnecessary overhead and his definition of loose coupling was "everything is a dataset" ;) &lt;br /&gt;&lt;br /&gt;I'm not complaining, I just find it comical.  I also find it challenging, although in a way I didn't expect.  The challenge isn't delivering code, it is making sure you understand how data transforms the many layers that exist in the infrastructure.  Plus, it's a massive amount of data to analyze which can be exciting (at least I think so).  Plus it pays great and is strict on 40 hours so I can go home and spend time with my wife.&lt;br /&gt;&lt;br /&gt;This blog isn't about that though, however I may relate some work experiences.  No, this is more about my open source work that I've recently jumped into.  I've actually been using open source software for quite some time (I've used &lt;a href="http://www.dotnetnuke.com"&gt;DotNetNuke &lt;/a&gt;extensivly for the past 4 years) and with it have built some pretty cool stuff. &lt;br /&gt;&lt;br /&gt;I've joined the &lt;a href="http://www.dotnetnuke.com/DotNetNukeProjects/ModuleAnnouncements/tabid/924/Default.aspx"&gt;DNN Announcements&lt;/a&gt; module development team which I am very excited to get to participate on such a great level with DNN.  We've got some good people on the team right now and actually a pretty good size for a open source module.  Plus we have people from the US, Netherlands, and I believe Spain.  I probably have that wrong, but I know its a pretty spread team. &lt;br /&gt;&lt;br /&gt;I've also created a couple projects on CodePlex that I work on in my spare time.  One sharing the name of this blog - &lt;a href="http://www.codeplex.com/yakshaver"&gt;YakShaver.NET&lt;/a&gt; - which is an exploration at integration testing, unit testing, windows workflow, TFS API, CodePlex API, DNN Forge API, a number of help desk applications as well as going to a knowledge base and more.  Basically I want to look at software builds by looking at the life of a work item from start to finish (when does it need to be one?  When is it a support item? how do we keep people involved? )  I'm really hoping to use this in combination with the DNN development.  The project Wiki goes over the goals of the project.  The other is &lt;a href="http://www.codeplex.com/deliveryboy"&gt;DeliveryBoy&lt;/a&gt;.  Which I will comment on as well, but probably not for awhile.  I started that project looking for something to do, but then I was reading a book and wanted to do some YakShaving (Building tools for tools, could be considered a useful task, but not always necessary).  I'm hoping people find it necessary. &lt;br /&gt;&lt;br /&gt;That's it for now, I just finished my first integration tests for Windows Workflow  and will post the results if I wasn't so tired and had to go to work early tomorrow.  This weekend though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1761229997634861862-504964830258041005?l=yakshaver.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ovzagf3Lm3OM6qobKt8qZJK5JbI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ovzagf3Lm3OM6qobKt8qZJK5JbI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ovzagf3Lm3OM6qobKt8qZJK5JbI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ovzagf3Lm3OM6qobKt8qZJK5JbI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/Yakshaving-YetAnothernetPerspective/~4/ULjdXc787ec" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://yakshaver.blogspot.com/feeds/504964830258041005/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1761229997634861862&amp;postID=504964830258041005" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/504964830258041005?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1761229997634861862/posts/default/504964830258041005?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Yakshaving-YetAnothernetPerspective/~3/ULjdXc787ec/first-post.html" title="First Post" /><author><name>Chris Taylor</name><uri>http://www.blogger.com/profile/13918601851435620675</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://yakshaver.blogspot.com/2008/02/first-post.html</feedburner:origLink></entry></feed>

