<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Kevin Miller</title><link>http://blogs.dovetailsoftware.com/blogs/kmiller/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.2)</generator><geo:lat>30.406169</geo:lat><geo:long>-97.757438</geo:long><image><link>http://blogs.dovetailsoftware.com/blogs/kmiller/</link><url>http://farm2.static.flickr.com/1075/706129937_1a06f9f816_o.png</url><title>Kevin Miller - Early Onset</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/KevinMiller" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Adding a Custom Dialog To Your Wix Installer</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/lUgtqLcwRAE/adding-a-custom-dialog-to-your-wix-installer.aspx</link><pubDate>Wed, 04 Nov 2009 22:44:02 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11984</guid><dc:creator>kmiller</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11984.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11984</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11984</wfw:comment><description>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/al-kaiser/3654625032/"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;margin-left:0px;border-top:0px;margin-right:0px;border-right:0px;" title="installer ninja" border="0" alt="installer ninja" align="right" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_62488801.png" width="195" height="480" /&gt;&lt;/a&gt;Recently I made the move to Wix3 for a couple of projects and I have been quite happy. One of the things that has been simplified is adding a a custom step into the installer process. &lt;/p&gt;  &lt;p&gt;I’ll leave the heavy lifting of how to insert the custom dialog to &lt;a href="http://www.dotnetjack.com/" target="_blank"&gt;Jan Schepens’&lt;/a&gt; post &lt;a href="http://www.dotnetjack.com/post/Making-a-custom-setup-dialog-using-WiX-30.aspx" target="_blank"&gt;Making a custom setup dialog using WiX 3.0&lt;/a&gt;. He tells you how to customize your UI layout and insert a new dialog into the process. Read this post it explains it well. Neil Sleightholm has a similar post &lt;a href="http://neilsleightholm.blogspot.com/2008/08/customised-uis-for-wix.html" target="_blank"&gt;Customised UI’s For Wix&lt;/a&gt; that is about removing dialogs from the layout.&lt;/p&gt;  &lt;p&gt;I’m going to be straight with you. This post is mainly for myself. I want to have this resource six months from now when I need to do the same thing again. &lt;/p&gt;  &lt;h3&gt;Wiring Up Your Dialog&lt;/h3&gt;  &lt;p&gt;Jan does a good job with his post so good that I want to leave it mostly alone. I do want to underscore the need to wire up the dialog into the flow of the UI for going in the &lt;strong&gt;Back&lt;/strong&gt; and &lt;strong&gt;Next&lt;/strong&gt; wizard directions. &lt;/p&gt;  &lt;pre class="brush: xml; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;Back&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;LicenseAgreementDlg&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;Next&amp;quot; Event=&amp;quot;SetTargetPath&amp;quot; Value=&amp;quot;[WIXUI_INSTALLDIR]&amp;quot; Order=&amp;quot;1&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;Next&amp;quot; Event=&amp;quot;DoAction&amp;quot; Value=&amp;quot;WixUIValidatePath&amp;quot; Order=&amp;quot;2&amp;quot;&amp;gt;NOT WIXUI_DONTVALIDATEPATH&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;Next&amp;quot; Event=&amp;quot;SpawnDialog&amp;quot; Value=&amp;quot;InvalidDirDlg&amp;quot; Order=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;![CDATA[NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID&amp;lt;&amp;gt;&amp;quot;1&amp;quot;]]&amp;gt;&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;Next&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;webSiteLocator&amp;quot; Order=&amp;quot;4&amp;quot;&amp;gt;WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID=&amp;quot;1&amp;quot;&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;ChangeFolder&amp;quot; Property=&amp;quot;_BrowseProperty&amp;quot; Value=&amp;quot;[WIXUI_INSTALLDIR]&amp;quot; Order=&amp;quot;1&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;InstallDirDlg&amp;quot; Control=&amp;quot;ChangeFolder&amp;quot; Event=&amp;quot;SpawnDialog&amp;quot; Value=&amp;quot;BrowseDlg&amp;quot; Order=&amp;quot;2&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;

&amp;lt;Publish Dialog=&amp;quot;webSiteLocator&amp;quot; Control=&amp;quot;Back&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;InstallDirDlg&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;webSiteLocator&amp;quot; Control=&amp;quot;Next&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;VerifyReadyDlg&amp;quot;&amp;gt;1&amp;lt;/Publish&amp;gt;

&amp;lt;Publish Dialog=&amp;quot;VerifyReadyDlg&amp;quot; Control=&amp;quot;Back&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;webSiteLocator&amp;quot; Order=&amp;quot;1&amp;quot;&amp;gt;NOT Installed&amp;lt;/Publish&amp;gt;
&amp;lt;Publish Dialog=&amp;quot;VerifyReadyDlg&amp;quot; Control=&amp;quot;Back&amp;quot; Event=&amp;quot;NewDialog&amp;quot; Value=&amp;quot;MaintenanceTypeDlg&amp;quot; Order=&amp;quot;2&amp;quot;&amp;gt;Installed&amp;lt;/Publish&amp;gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The key when inserting your dialog is to also rewire the NewDiaqlog events from the previous and next dialogs in the wizard to point at your new dialog.&lt;/p&gt;

&lt;h3&gt;Creating the Custom Dialog&lt;/h3&gt;

&lt;p&gt;Hate to break this to you the fun part is over. The trick with the custom dialog is actually creating the custom dialog. Editing Xml user interfaces is not fun and the edit/test cycle between building your Wix installer and manually testing it is painful. I went looking for an interactive dialog editor and found &lt;a href="http://wixedit.sourceforge.net/"&gt;WixEdit&lt;/a&gt;. Suddenly a lot of the pain went away. WixEdit is still a bit rough here are a couple of tips.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Copy the WixEdit exe and dlls into your Wix doc directory to make it happy.&lt;/li&gt;

  &lt;li&gt;WixEdit doesn’t currently like the Wix3 namespace. I could not get it to open my .wxs files. If you have an existing dialog you wish to edit it... Create a new project with WixEdit and copy your Dialog Xml into that project file. Then copy the resulting dialog xml back out when you are done. Ulgy but better than nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_5259433D.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_4D0A5C8C.png" width="543" height="772" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;Bonus: Enabling and Disabling Controls Based On A Checkbox&lt;/h3&gt;

&lt;p&gt;I wanted the dialog to enable the text fields when a checkbox is pressed. The trick to this is having conditions on the controls toggling the control’s enabled state based on the checkbox’s property.&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;  &amp;lt;Control Id=&amp;quot;headerLabel&amp;quot; Type=&amp;quot;Text&amp;quot; X=&amp;quot;20&amp;quot; Y=&amp;quot;126&amp;quot; Width=&amp;quot;290&amp;quot; Height=&amp;quot;13&amp;quot; Text=&amp;quot;Host Header Name&amp;quot; /&amp;gt;
  &amp;lt;Control Id=&amp;quot;webSiteHeader&amp;quot; Type=&amp;quot;Edit&amp;quot; Property=&amp;quot;WEBSITEHEADER&amp;quot;
           X=&amp;quot;20&amp;quot; Y=&amp;quot;139&amp;quot; Width=&amp;quot;320&amp;quot; Height=&amp;quot;15&amp;quot;
           Text=&amp;quot;[WEBSITEHEADER]&amp;quot; Disabled=&amp;quot;yes&amp;quot;&amp;gt;
    &amp;lt;Condition Action=&amp;quot;disable&amp;quot;&amp;gt;&amp;lt;![CDATA[CUSTOMIZEWEBSITE &amp;lt;&amp;gt; &amp;quot;yes&amp;quot;]]&amp;gt;&amp;lt;/Condition&amp;gt;
    &amp;lt;Condition Action=&amp;quot;enable&amp;quot;&amp;gt;&amp;lt;![CDATA[CUSTOMIZEWEBSITE = &amp;quot;yes&amp;quot;]]&amp;gt;&amp;lt;/Condition&amp;gt;
  &amp;lt;/Control&amp;gt;

  &amp;lt;Control Type=&amp;quot;CheckBox&amp;quot; Id=&amp;quot;customizeWebSiteLocation&amp;quot; Property=&amp;quot;CUSTOMIZEWEBSITE&amp;quot;
           Width=&amp;quot;120&amp;quot; Height=&amp;quot;17&amp;quot; X=&amp;quot;240&amp;quot; Y=&amp;quot;56&amp;quot; 
           Text=&amp;quot;Customize Website Binding&amp;quot; CheckBoxValue=&amp;quot;yes&amp;quot;&amp;gt;
    &amp;lt;Condition Action=&amp;quot;show&amp;quot;&amp;gt;NOT Installed&amp;lt;/Condition&amp;gt;
  &amp;lt;/Control&amp;gt;&lt;/pre&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11984" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/lUgtqLcwRAE" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/wix/default.aspx">wix</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/11/04/adding-a-custom-dialog-to-your-wix-installer.aspx</feedburner:origLink></item><item><title>Simplification</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/U6YYYe7LGpw/simplification.aspx</link><pubDate>Tue, 03 Nov 2009 21:35:49 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11982</guid><dc:creator>kmiller</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11982.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11982</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11982</wfw:comment><description>&lt;p&gt;Just replaced this VB (shudder) code&lt;/p&gt;  &lt;pre class="brush: vb; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;' Build up additional info string using
'  research time as formatted string
addnl_info = &amp;quot;Elapsed time = &amp;quot;
t_long = research_time
If t_long &amp;gt; 86400 Then
	t_long2 = t_long \ 86400
Else
	t_long2 = 0
End If
t_long = t_long - t_long2 * 86400
addnl_info = addnl_info &amp;amp; VB6.Format(t_long2, &amp;quot;000&amp;quot;) &amp;amp; &amp;quot; &amp;quot;
If t_long &amp;gt; 3600 Then
	t_long2 = t_long \ 3600
Else
	t_long2 = 0
End If
t_long = t_long - t_long2 * 3600
addnl_info = addnl_info &amp;amp; VB6.Format(t_long2, &amp;quot;00&amp;quot;) &amp;amp; &amp;quot;:&amp;quot;
If t_long &amp;gt; 60 Then
	t_long2 = t_long \ 60
Else
	t_long2 = 0
End If
t_long = t_long - t_long2 * 60
addnl_info = addnl_info &amp;amp; VB6.Format(t_long2, &amp;quot;00&amp;quot;) &amp;amp; &amp;quot;.&amp;quot;&lt;/pre&gt;
With this VB (shudder) code:

&lt;pre class="brush: vb; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;addnl_info = &amp;quot;Elapsed time = &amp;quot; &amp;amp; GetElapsedTime(research_time) &amp;amp; &amp;quot;.&amp;quot;

...

Private Function GetElapsedTime(ByVal researchTimeInSeconds As Integer) As String

	Dim timeSpan As TimeSpan = timeSpan.FromSeconds(researchTimeInSeconds)

	Return String.Format(&amp;quot;{0:000} {1:00}:{2:00}&amp;quot;, timeSpan.Days, timeSpan.Hours, timeSpan.Minutes)

End Function&lt;/pre&gt;

&lt;p&gt;Ah that’s better.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11982" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/U6YYYe7LGpw" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/11/03/simplification.aspx</feedburner:origLink></item><item><title>Basic Web Application Loading With JMeter</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/Ad6CN-q5c_4/fun-with-jmeter.aspx</link><pubDate>Fri, 23 Oct 2009 22:10:17 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11977</guid><dc:creator>kmiller</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11977.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11977</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11977</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_741023E8.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;margin:0px 0px 0px 15px;display:inline;border-top:0px;border-right:0px;" title="Apache JMeter Logo" border="0" alt="Apache JMeter Logo" align="right" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_39B4AE07.png" width="355" height="202" /&gt;&lt;/a&gt;I needed to load test one of our web applications today. Load testing is not something I am too familiar with. A search turned up a list of open source load testing tools. At the top of the list was &lt;a href="http://jakarta.apache.org/jmeter/"&gt;Apache JMeter&lt;/a&gt; which I decided to gave a shot based on the awesomeness of the Apache project. I am not quite blown away but I was able to get a load test up and going in about 15 minutes which makes me very very happy. Here is what I did to create a load tester for our Dovetail Seeker &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/search/default.aspx"&gt;web search service&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Get It&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi"&gt;Download JMeter&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Extract it to a directory and run the &lt;strong&gt;.\bin\jmeter.bat&lt;/strong&gt; batch file. You’ll likely need Java installed for this to work. &lt;/li&gt;    &lt;li&gt;Now weren’t you afraid after seeing &lt;u&gt;Apache&lt;/u&gt; that some horrible text file would need to be edited? Thankfully this is not the case.&lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Set It Up&lt;/h4&gt;  &lt;p&gt;Next create a test plan by right clicking on the test plan icon in the tree view at the left and add a &lt;strong&gt;Thread Group&lt;/strong&gt;. Set the Number of Threads to &lt;strong&gt;10&lt;/strong&gt;&amp;#160; ramp it up in &lt;strong&gt;5&lt;/strong&gt; seconds.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_3FFB8495.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Thread Group" border="0" alt="Thread Group" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_7EED0530.png" width="644" height="265" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Right click on Thread Group and add a &lt;strong&gt;Loop Logic Controller&lt;/strong&gt; which is set to loop &lt;strong&gt;Forever&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_28ED0359.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Loop Controller" border="0" alt="Loop Controller" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_41106DB4.png" width="644" height="173" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Right click on Loop Controller and add a &lt;strong&gt;Http Request Sampler &lt;/strong&gt;setup the hostname, port, path appropriately. &lt;/p&gt;  &lt;p&gt;For my purposes I need to Also you’ll need to add a query string representing the search query I wish to do against the server. As I don’t really want to do the same query over and over again we will use a variable to push in value to each request that is made. This apparently is done using (n)ant like notation. &lt;strong&gt;${variable_name}&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_55298A3D.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_3EF36EEB.png" width="590" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;We need to define the &lt;strong&gt;query_value&lt;/strong&gt; variable which will be pushing the search query into each request. Right click on the Http Request and add a &lt;strong&gt;Random Variable Config Element&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_1D93C94F.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Random Variable" border="0" alt="Random Variable" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_7CA056A7.png" width="644" height="284" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Finally it would be handy to see what’s going on. To do that add a Listener. I found the Summary listener is handy. &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_5BACE400.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Reporting" border="0" alt="Reporting" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_0F74DA52.png" width="644" height="281" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h4&gt;Run it&lt;/h4&gt;  &lt;p&gt;To start the load test hit the Run menu and click on &lt;strong&gt;Start&lt;/strong&gt;. &lt;/p&gt;  &lt;p&gt;How do you know it is working? If you see the Error % column spike up to 100% you know something is wrong. Make sure you have your host and path right. You can also check your logs to see if you are getting correct requests.&lt;/p&gt;  &lt;h4&gt;Fun with Load Testing&lt;/h4&gt;  &lt;p&gt;I am likely doing something wrong here. I am no web test expert I just needed to load up a web application to see how a tangential mechanism behaved when the website was under load. There is a lot more depth to this tool. For example check out the &lt;strong&gt;View Results Tree&lt;/strong&gt; Listener to get a trace of each request. Handy. &lt;/p&gt;  &lt;p&gt;Hopefully you get the idea here you can create more than one Thread Group and create chains of Http Requests. You can control cookies and traffic numbers and all sorts of crazy things. If I was a tester I would be having much more fun but then I also might know a better tool than this. All I know is I went from zero to hitting my app with lots of users per second in 15 minutes.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11977" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/Ad6CN-q5c_4" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/testing/default.aspx">testing</category><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/asp.net/default.aspx">asp.net</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/10/23/fun-with-jmeter.aspx</feedburner:origLink></item><item><title>What Is Under The Hood In Dovetail Mobile?</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/Mavev4aRzr0/what-is-under-the-hood-in-dovetail-mobile.aspx</link><pubDate>Tue, 13 Oct 2009 20:37:06 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11971</guid><dc:creator>kmiller</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11971.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11971</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11971</wfw:comment><description>&lt;p&gt;Dovetail Mobile is our first shipping ASP.NET MVC based application. Because this is a newer technology one of our customers asked for some guidance on customizing the application. The following is a distillation of that guidance which I hope might come in handy for future Mobile customers.&lt;/p&gt;  &lt;h3&gt;Customizing Dovetail Mobile (Agent Lite)&lt;/h3&gt;  &lt;p&gt;Dovetail Mobile and its desktop skinned alter ego Agent Lite is a &lt;a href="http://www.asp.net/mvc/"&gt;ASP.Net MVC 1.0&lt;/a&gt; application. There are lots of reading and tutorial resources available that will translate directly to understanding how this type of application works and thus how to customize Dovetail Mobile. It is important to understand Model View Controller based web applications to know where the part you wish to change is most likely found.&lt;/p&gt;  &lt;h4&gt;Controllers&lt;/h4&gt;  &lt;p&gt;If you need to customize behavior you will likely need to add or modify controllers and their related views.&lt;/p&gt;  &lt;p&gt;We provide a place to add customized versions of your controllers. Please take a look at the ReadMe.txt under the &lt;strong&gt;controllers\CustomControllers&lt;/strong&gt; directory for guidance on how this hook works. You are not required to put your customization in the custom controllers directory. In other words you could easily modify the baseline code and be fine. We put the custom folder hook in there to help keep customized code sequestered from the baseline.&lt;/p&gt;  &lt;p&gt;Mobile uses dependency injection (DI) to make the controller behavior easier to test and thus maintain. The responsibility of creating controller classes and their dependencies is turned over to a tool called &lt;a href="http://dotnetslackers.com/articles/designpatterns/IntroductionToStructureMap.aspx"&gt;StructureMap&lt;/a&gt;.&amp;#160; The advantage of having StructureMap handle the complexity of controller creation is in isolation of controllers from their dependencies which in turn facilitates testability and also tends to keep the controllers thin. Elijah Manor has a post on using &lt;a href="http://elijahmanor.com/webdevdotnet/post/Using-StructureMap-with-ASPNET-MVC-MVC-Contrib.aspx"&gt;Structure Map with ASP.Net MVC&lt;/a&gt; which shows a pretty similar usage to how we use StructureMap in Dovetail Mobile and links to all sorts of goodness about DI and inversion of control. All things we are big fans of here at Dovetail. &lt;/p&gt;  &lt;h4&gt;Model&lt;/h4&gt;  &lt;p&gt;Dovetail Mobile data access is mostly done using Dovetail DataMaps to populate viewmodels which are consumed by by the views. I have already done an &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/04/27/introducing-dovetail-datamap.aspx"&gt;introductory post on DataMaps&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;Views&lt;/h4&gt;  &lt;p&gt;Views are organized under the views directory by controller. &lt;strong&gt;Views\CaseCreate\New.aspx - &lt;/strong&gt;the the location of the view shown when creating a new case. These files contain the the HTML of that to be rendered by that page view. Any changes to view files do not require that you rebuild the application. Each view gets a view model passed to it by the controller.&lt;/p&gt;  &lt;p&gt;If you simply want to style the application’s dive into the &lt;strong&gt;Content&lt;/strong&gt; directory for access to CSS and images. I believe we did a pretty good job of providing CSS id/class hooks for you to style the application.&lt;/p&gt;  &lt;p&gt;If you are familiar with ASP.Net applications you should be comfortable with the concept of &lt;a href="http://msdn.microsoft.com/en-us/library/wtxbf3hh.aspx"&gt;Master Pages&lt;/a&gt;. Mobile’s master page is found in the &lt;strong&gt;Views\Shared\Site.Master&lt;/strong&gt;. You’ll notice that there is also an &lt;strong&gt;AgentLite.Master&lt;/strong&gt; file. You can control which master page is used by changing the &lt;em&gt;//pages/masterPageFile&lt;/em&gt; attribute of the web.config file. If you change your master file to use the Agent Lite master page you will notice that it works much better with desktop browsers.&lt;/p&gt;  &lt;h4&gt;Finally&lt;/h4&gt;  &lt;p&gt;If you are looking for more information on the creation and development of Dovetail Mobile Gary and I have been posting about Mobile for some time check out our respective blogs &lt;a href="http://blogs.dovetailsoftware.com/blogs/gsherman/archive/tags/Dovetail+Mobile+Agent/default.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/mobile+agent/default.aspx"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11971" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/Mavev4aRzr0" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/mobile+agent/default.aspx">mobile agent</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/10/13/what-is-under-the-hood-in-dovetail-mobile.aspx</feedburner:origLink></item><item><title>Running Multiple Instances of a Windows Service Using TopShelf</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/HmrhzTcUK2Y/running-multiple-instances-of-a-windows-service-using-topshelf.aspx</link><pubDate>Thu, 24 Sep 2009 20:43:38 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11948</guid><dc:creator>kmiller</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11948.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11948</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11948</wfw:comment><description>&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/topshelf3small_507D71C4.png"&gt;&lt;img style="border-right-width:0px;margin:0px 0px 0px 15px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="top-shelf-3-small" border="0" alt="top-shelf-3-small" align="right" src="http://blogs.dovetailsoftware.com/blogs/kmiller/topshelf3small_thumb_0F6EF260.png" width="150" height="200" /&gt;&lt;/a&gt;   &lt;p&gt;Here is another one where I post about something &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/"&gt;Josh&lt;/a&gt; and team did that I borrowed and am using to great effect. When a console app or a windows service needed we like to use &lt;a href="http://code.google.com/p/topshelf/"&gt;TopShelf&lt;/a&gt; to get the job done. In this post I’ll show how to get two instances of a Windows service running on one machine using TopShelf.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Updated:&lt;/strong&gt; As Mike points out in the comments below as of &lt;a href="http://code.google.com/p/topshelf/source/detail?r=46"&gt;revision 46&lt;/a&gt; Dru added a command line parameter to handle this scenario. Great! Much better than our hacky solution below (written before this revision). Please skip this post and just add a &lt;strong&gt;–instance &amp;lt;instance name&amp;gt;&lt;/strong&gt; argument at the command line to install additional windows services. Here is an example:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;YourApplication.exe /install –instance NumeroDos&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now back to the original post which should be ignored so stop reading now &amp;lt;grin&amp;gt;. Sigh, this is what I get for posting about something cool we did back in March.&lt;/p&gt;  &lt;h3&gt;Topshelf Basics&lt;/h3&gt;  &lt;p&gt;For a better introduction to TopShelf checkout &lt;a href="http://codebetter.com/blogs/dru.sellers/default.aspx"&gt;Dru Sellers’s&lt;/a&gt; introductory post on &lt;a href="http://codebetter.com/blogs/dru.sellers/archive/2009/01/11/topshelf.aspx"&gt;TopShelf&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The code below is very close to the code we use to tell Topshelf how to setup one of our Windows services. &lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;static void Main(string[] args)
{
	var cfg = RunnerConfigurator.New(x =&amp;gt;
	{
		x.SetDisplayName(&amp;quot;Dovetail Seeker Service&amp;quot;);
		x.SetServiceName(&amp;quot;Seeker&amp;quot;);
		x.SetDescription(&amp;quot;Indexing service for Dovetail Seeker.&amp;quot;);

		x.ConfigureService&amp;lt;SeekerService&amp;gt;(&amp;quot;&amp;quot;, c =&amp;gt;
		{
			c.WhenStarted(s =&amp;gt; s.Start());
			c.WhenStopped(s =&amp;gt; s.Stop());
		});
	});

	Runner.Host(cfg, args);
}&lt;/pre&gt;

&lt;p&gt;All the application work is done by the SeekerService class. At runtime Topshelf makes it very easy to run an application as a console app or install it as a windows service.&lt;/p&gt;

&lt;pre&gt;Seeker.exe            #Runs as a console
Seeker.exe /install   #installs the service
Seeker.exe /uninstall #uninstalls the service&lt;/pre&gt;

&lt;h3&gt;Why You Are Here&lt;/h3&gt;

&lt;p&gt;Unfortunately, Windows by default only allows one windows service with a given name. So the second time you try to install the application you’ll get an error. &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;2009-09-24 15:27:32,486 ERROR Topshelf.Internal.Actions.InstallServiceAction - The Seeker service has already been installed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The solution is to change the name at runtime via configuration. Our solution was to add an application configuration setting defining the instance name of the service which then gets used at runtime. Here is the code above with a few changes.&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: false; collapse: false; first-line: 1; gutter: false; highlight: [3,7,8]; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;static void Main(string[] args)
{
	var instanceName = ConfigurationManager.AppSettings[&amp;quot;WindowsServiceInstanceName&amp;quot;];

	var cfg = RunnerConfigurator.New(x =&amp;gt;
	{
		x.SetDisplayName(&amp;quot;Dovetail Seeker Service &amp;quot; + instanceName);
		x.SetServiceName(&amp;quot;Seeker&amp;quot; + instanceName);
		x.SetDescription(&amp;quot;Indexing service for Dovetail Seeker.&amp;quot;);

		x.ConfigureService&amp;lt;SeekerService&amp;gt;(&amp;quot;&amp;quot;, c =&amp;gt;
		{
			c.WhenStarted(s =&amp;gt; s.Start());
			c.WhenStopped(s =&amp;gt; s.Stop());
		});
	});

	Runner.Host(cfg, args);
}&lt;/pre&gt;

&lt;p&gt;Here is a look at the app.config file with an alternate instance name defined:&lt;/p&gt;

&lt;pre class="brush: xml; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;appSettings file=&amp;quot;applicationSettings.config&amp;quot;&amp;gt;
    &amp;lt;add key=&amp;quot;WindowsServiceInstanceName&amp;quot; value=&amp;quot;NumeroDos&amp;quot;/&amp;gt;
  &amp;lt;/appSettings&amp;gt;
&amp;lt;/configuration&amp;gt;&lt;/pre&gt;

&lt;p&gt;Now installing the application does not give us an error. &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&amp;gt;Seeker.exe /install&lt;/p&gt;

  &lt;p&gt;Beginning the Install phase of the installation. 
    &lt;br /&gt;2009-09-24 15:32:34,176 INFO&amp;#160; Topshelf.Internal.Hosts.HostServiceInstaller - Installing Service SeekerNumeroDos 

    &lt;br /&gt;Installing service DovetailSeeker... 

    &lt;br /&gt;Service SeekerNumeroDos has been successfully installed. 

    &lt;br /&gt;Creating EventLog source SeekerNumeroDos in log Application... &lt;/p&gt;

  &lt;p&gt;The Install phase completed successfully, and the Commit phase is beginning. &lt;/p&gt;

  &lt;p&gt;The Commit phase completed successfully. &lt;/p&gt;

  &lt;p&gt;The transacted install has completed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Wee! We got multiple copies of our Windows service working on a single machine. When writing Windows services I recommend you check out Topshelf. Besides making it easy to work with Windows services. Topshelf works great in concert with IoC containers and allows you to easily get services on worker threads going about their business. But those details are for another post. Want to see more? Let me know.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11948" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/HmrhzTcUK2Y" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/09/24/running-multiple-instances-of-a-windows-service-using-topshelf.aspx</feedburner:origLink></item><item><title>Extension Methods I Use A Lot</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/DQA7_lj9M9A/extension-methods-i-use-a-lot.aspx</link><pubDate>Wed, 23 Sep 2009 18:05:37 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11940</guid><dc:creator>kmiller</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11940.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11940</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11940</wfw:comment><description>&lt;p&gt;C# extensions have been around for some time and it was a fad for a while to post your favorites. I am following way behind the extension party bus with this post of my favorite extensions. Most of these are poached from &lt;a href="http://www.lostechies.com/blogs/chad_myers/"&gt;Chad&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"&gt;Jeremy&lt;/a&gt; and &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/"&gt;Josh&lt;/a&gt; with &lt;strike&gt;a few&lt;/strike&gt; sadly only one of my own mixed in.&lt;/p&gt;  &lt;p&gt;Below is the Basic Extensions class that is common to a lot of our Dovetail projects. I am not a big believer in class libraries for simple little things like these as extensions that are useful on one project will be useless on another. &lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: false; collapse: false; first-line: 1; gutter: false; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 2; toolbar: true;"&gt;using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.Script.Serialization;

namespace Dovetail.Commons
{
    public static class BasicExtensions
    {
        /// &amp;lt;summary&amp;gt;
        /// Write string to the console. 
        /// &amp;lt;/summary&amp;gt;
        public static void WriteToConsole(this string stringValue)
        {
            Console.WriteLine(stringValue);
        }

        /// &amp;lt;summary&amp;gt;
        /// Fills the format string with the provided arguments
        /// &amp;lt;/summary&amp;gt;
        public static string ToFormat(this string format, params object[] args)
        {
            return String.Format(format, args);
        }

        public static string ToJson(this object objectToSerialize)
        {
            return new JavaScriptSerializer().Serialize(objectToSerialize);
        }

        public static T DeserializeJSON&amp;lt;T&amp;gt;(this string json) where T : class
        {
            return new JavaScriptSerializer().Deserialize&amp;lt;T&amp;gt;(json);
        }

        /// &amp;lt;summary&amp;gt;
        /// Returns true if the value being tested is not null and not an empty string
        /// &amp;lt;/summary&amp;gt;
        public static bool IsNotEmpty(this string stringValue)
        {
            return !String.IsNullOrEmpty(stringValue);
        }

        /// &amp;lt;summary&amp;gt;
        /// Returns true if the value being tested is null or an empty string
        /// &amp;lt;/summary&amp;gt;
        public static bool IsEmpty(this string stringValue)
        {
            return String.IsNullOrEmpty(stringValue);
        }

        /// &amp;lt;summary&amp;gt;
        /// Returns true if the value being tested is null or contains no items
        /// &amp;lt;/summary&amp;gt;
        public static bool IsEmpty&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; enumerable)
        {
            return (enumerable == null || enumerable.Count() &amp;lt; 1);
        }

        /// &amp;lt;summary&amp;gt;
        /// Performs an action with a counter for each item in a sequence and provides
        /// &amp;lt;/summary&amp;gt;
        public static IEnumerable&amp;lt;T&amp;gt; Each&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; values, Action&amp;lt;T, int&amp;gt; eachAction)
        {
            var index = 0;
            foreach (var item in values)
            {
                eachAction(item, index++);
            }

            return values;
        }

        /// &amp;lt;summary&amp;gt;
        /// Performs an action for each item in a sequence. Good for one-line foreach statements.
        /// &amp;lt;/summary&amp;gt;
        public static IEnumerable&amp;lt;T&amp;gt; Each&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; values, Action&amp;lt;T&amp;gt; eachAction)
        {
            foreach (var item in values)
            {
                eachAction(item);
            }

            return values;
        }

        /// &amp;lt;summary&amp;gt;
        /// Performs an action for each item in a sequence. Good for one-line foreach statements.
        /// &amp;lt;/summary&amp;gt;
        public static IEnumerable Each(this IEnumerable values, Action&amp;lt;object&amp;gt; eachAction)
        {
            foreach (var item in values)
            {
                eachAction(item);
            }

            return values;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;Enjoy and as always your mileage may vary. Don’t over do it with the extension methods. They are handy but can get in the way if overused. For example you might want think twice before adding an extension to System.Object that will get seen by every type in the system.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11940" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/DQA7_lj9M9A" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/c_2300_/default.aspx">c#</category><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/dovetail/default.aspx">dovetail</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/09/23/extension-methods-i-use-a-lot.aspx</feedburner:origLink></item><item><title>Think About User Experience</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/5nHnsbly-H0/think-about-user-experience.aspx</link><pubDate>Fri, 28 Aug 2009 13:43:12 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11897</guid><dc:creator>kmiller</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11897.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11897</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11897</wfw:comment><description>&lt;p&gt;Separate the user from complexity. Spam filtering is pretty complex stuff. The act of signaling an email is spam should not be. Which of these user interfaces for Spam handling do you think works better?&lt;/p&gt;  &lt;h4&gt;Outlook 2007 – 1 action = navigation + 6 options&lt;/h4&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_06818CED.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_76261533.png" width="657" height="495" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;A classic lesson from &lt;a href="http://www.sensible.com/buythebook.html"&gt;Don’t Make Me Think&lt;/a&gt;. The cognitive load in Outlook is very high. The steps for a email user wishing to mark an email as spam. &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Some how know to right click on the email. (acquired knowledge)&lt;/li&gt;    &lt;li&gt;Click on Junk E-mail.&amp;#160; (Find the menu item)&lt;/li&gt;    &lt;li&gt;Pick from a list of 6 potential junk email options. (Read and understand what each option means)&lt;/li&gt; &lt;/ol&gt;  &lt;h4&gt;GMail – 1 to 1&lt;/h4&gt;  &lt;p&gt;Gmail recently changed their menu items condensing them down and in my opinion reducing their readability. However I find the task of marking email as spam here a lot easier.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_5C51DF04.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_1BAF9295.png" width="532" height="326" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Click on &lt;strong&gt;Report spam &lt;/strong&gt;or use the keyboard shortcut &lt;strong&gt;!&lt;/strong&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;To make things even better Gmail as an email hosting service usually never gets this far. For this example I had to go dig emails out of my Spam folder. I get maybe 1 spam a week.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11897" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/5nHnsbly-H0" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/08/28/think-about-user-experience.aspx</feedburner:origLink></item><item><title>Producing and Consuming Messages using MassTransit and StructureMap</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/MC380nqW-FA/producing-and-consuming-messages-using-masstransit-and-structuremap.aspx</link><pubDate>Wed, 26 Aug 2009 17:16:16 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11883</guid><dc:creator>kmiller</dc:creator><slash:comments>11</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11883.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11883</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11883</wfw:comment><description>&lt;p&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;margin-left:0px;border-left-width:0px;margin-right:0px;" title="Josh is always the White Bomberman." border="0" alt="Josh is always the White Bomberman." align="right" src="http://blogs.dovetailsoftware.com/blogs/kmiller/whitebomberman_699FF62D.png" width="224" height="265" /&gt;I am spiking out right now what it takes to use a &lt;a href="http://code.google.com/p/masstransit/"&gt;Mass Transit&lt;/a&gt; as a message bus for handling a simple producer consumer messaging architecture. To be exact I want to see how easy it is to get Mass Transit working using StructureMap for an IoC container. &lt;/p&gt;  &lt;p&gt;Dovetail uses &lt;a href="http://martinfowler.com/articles/injection.html"&gt;Inversion of Control&lt;/a&gt; extensively to make our code more: testable and able to leap tall buildings, dodge bullets, and all that. Our favorite IoC container is &lt;a href="http://structuremap.sourceforge.net/Default.htm"&gt;StructureMap&lt;/a&gt;. Why? Because it is great and we have two contributors on staff: creator &lt;a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"&gt;Jeremy Miller&lt;/a&gt; and the brainy &lt;a href="http://www.lostechies.com/blogs/joshuaflanagan/"&gt;Josh Flanagan&lt;/a&gt;.&lt;/p&gt;  &lt;h3&gt;Getting Started&lt;/h3&gt;  &lt;p&gt;My first step was to grab the Mass Transit &lt;a href="http://masstransit.googlecode.com/svn/trunk/masstransit-read-only"&gt;trunk from SVN&lt;/a&gt;, build it and start up a new solution with three projects: &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;Producer&lt;/strong&gt; – produces messages. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Consumer&lt;/strong&gt; – consumers messages. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Common&lt;/strong&gt; – code shared between producer and consumer. In this case the Message and StructureMap registry. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_56C5A0BE.png" target="_blank"&gt;&lt;img style="border-right-width:0px;margin:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="Click to see a bigger version of the solution." border="0" alt="Click to see a bigger version of the solution." src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_67C9CEA1.png" width="228" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I included this solution view so you can see what references each project requires. &lt;/p&gt;  &lt;h3&gt;Producer&lt;/h3&gt;  &lt;p&gt;Here comes the window dressing. The Producer does one thing, generates SimpleMessages and Publishes them. &lt;/p&gt;  &lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; highlight: [5]; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class ProducerMain
{
    private static void Main(string[] args)
    {
        var container = new Container(x =&amp;gt; x.AddRegistry(new CommonRegistry()));

        using (var bus = container.GetInstance&amp;lt;IServiceBus&amp;gt;())
        {
            do
            {
                PublishSimpleMessage(bus);
            } 
            while (Console.ReadLine().Trim() != &amp;quot;x&amp;quot;);

            Console.WriteLine(&amp;quot;Stopping Publisher&amp;quot;);
        }
    }

    private static void PublishSimpleMessage(IServiceBus bus)
    {
        var message = new SimpleMessage {Body = Guid.NewGuid().ToString()};

        bus.Publish(message);

        Console.WriteLine(&amp;quot;Published message : '{0}'.&amp;quot;, message.Body);
    }
}&lt;/pre&gt;

&lt;p&gt;The interesting StructureMap setup stuff is in the CommonRegistry which is used between both Producer and Consumer projects. &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class CommonRegistry : MassTransitRegistryBase
{
    public const string MessageQueuePath = &amp;quot;msmq://localhost/mt-spike&amp;quot;;

    public CommonRegistry() : base(typeof(MsmqEndpoint))
    {
        RegisterServiceBus(MessageQueuePath, x =&amp;gt;
        {
            x.ConfigureService&amp;lt;RoutingConfigurator&amp;gt;(rs =&amp;gt; rs.Route&amp;lt;SimpleMessage&amp;gt;().To(MessageQueuePath));
        });

        MsmqEndpointConfigurator.Defaults(config =&amp;gt; { config.CreateMissingQueues = true; });
    }
}&lt;/pre&gt;

&lt;p&gt;Above is the &lt;a href="http://structuremap.sourceforge.net/RegistryDSL.htm#section1"&gt;StructureMap Registry&lt;/a&gt; code used by both Producer and Consumer to configure MassTransit. First, we are using MSMQ for the message endpoint. Next, we are configuring a route for all SimpleMessages to be placed in the desired queue. Chris Patterson pointed me to Dru’s post on &lt;a href="http://codebetter.com/blogs/dru.sellers/archive/2009/04/18/masstransit-routing.aspx"&gt;MassTransit Routing&lt;/a&gt; to make this work. This should not be not necessary if I was using the Subscription service. Finally, I ask Mass Transit to create any missing queues for me.&lt;/p&gt;

&lt;h3&gt;Consumer&lt;/h3&gt;

&lt;p&gt;The consumer of a &lt;strong&gt;SimpleMessage&lt;/strong&gt; is a class registered with Mass Transit derived from &lt;strong&gt;Consumes&amp;lt;SimpleMessage&amp;gt;.All&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is the equivalent of a Hello World message consumer:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class SimpleMessageConsumer : Consumes&amp;lt;SimpleMessage&amp;gt;.All, IBusService
{
    private IServiceBus bus;
    //private UnsubscribeAction unsubscribeAction;

    public void Consume(SimpleMessage message)
    {
        Console.WriteLine(&amp;quot;Received message : '{0}'&amp;quot;, message.Body);
    }

    public void Dispose()
    {
        bus.Dispose();
    }

    public void Start(IServiceBus bus)
    {
        this.bus = bus;
        //unsubscribeAction = bus.Subscribe(this);
        Console.WriteLine(&amp;quot;SimpleMessage consumer started.&amp;quot;);
    }

    public void Stop()
    {
        //unsubscribeAction();
    }
}&lt;/pre&gt;

&lt;p&gt;Again boring easy yet very important stuff. This consumer is where your business functionality goes. I would love to be enlightened if unsubscribe is necessary in context of how we are subscribing consumers as you’ll see next.&lt;/p&gt;

&lt;h3&gt;Automatically Registering And Subscribing Message Consumers &lt;/h3&gt;

&lt;p&gt;Before the any message consumers can receive messages they need to be registered with StructureMap and subscribed to the service bus. Take a look at the message Consumer setup:&lt;/p&gt;

&lt;pre class="brush: csharp; auto-links: true; collapse: false; first-line: 1; gutter: true; highlight: [11, 17]; html-script: false; light: false; ruler: false; smart-tabs: true; tab-size: 4; toolbar: true;"&gt;public class ConsumerMain
{
    static void Main(string[] args)
    {
        var container = new Container(x =&amp;gt;
        {
            x.AddRegistry(new CommonRegistry());
            x.Scan(scan =&amp;gt;
            {
                scan.TheCallingAssembly();
                scan.AddAllTypesOf(typeof (Consumes&amp;lt;&amp;gt;.All));
            });
        });

        using (var bus = container.GetInstance&amp;lt;IServiceBus&amp;gt;())
        {
            SubscribeConsumers(container, bus);

            Console.ReadLine();
            Console.WriteLine(&amp;quot;Stopping Subscriber&amp;quot;);
        }
    }

    private static void SubscribeConsumers(IContainer container, IServiceBus bus)
    {
        var consumerInstances = container.Model.PluginTypes
                                .Where(p =&amp;gt; typeof (Consumes&amp;lt;&amp;gt;.All).IsAssignableFrom(p.PluginType))
                                .SelectMany(p =&amp;gt; p.Instances);

        consumerInstances.Each(type =&amp;gt; bus.Subscribe(type.ConcreteType));
    }
}&lt;/pre&gt;

&lt;p&gt;To register all the consumers with StructureMap a scanner is used against executing assembly adding all consumers. &lt;/p&gt;

&lt;p&gt;Next we need each consumer registered with StructureMap to be subscribed to the service bus. After this is done all consumers will now start getting any messages being published by the Producer.&lt;/p&gt;

&lt;p&gt;The output is not too exciting. But who doesn’t like beautiful console application output?&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_14D4CC40.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_3B36AF8B.png" width="569" height="207" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_6F6AD8D1.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_39F216AC.png" width="569" height="135" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;To prove that adding more consumers was working find I created &lt;strong&gt;another consumer&lt;/strong&gt; class for the same message. Nothing else was required as the configuration is automatic.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/image_3266A73F.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image" border="0" alt="image" src="http://blogs.dovetailsoftware.com/blogs/kmiller/image_thumb_06B5DD43.png" width="593" height="159" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As desired. Both consumers are receiving each message being published. Also notice the beautiful Windows 7 purple window shading in the images above.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;I hope this post enables other Mass Transit newbies like myself who are looking for a tutorial on how to get up and running. Please let me know if I could be doing anything better. I’d love to hear your feedback.&lt;/p&gt;

&lt;p&gt;Thanks go out to &lt;a href="http://mikehadlow.blogspot.com/"&gt;Mike Hadlow&lt;/a&gt; as I used his &lt;a href="http://mikehadlow.blogspot.com/2009/07/first-look-at-masstransit.html"&gt;A First Look at MassTransit&lt;/a&gt; post as a template for getting started. Even more thanks to Chris Patterson a.k.a &lt;a href="http://phatboyg.com/"&gt;PhatBoyG&lt;/a&gt; for his quick and helpful Skype support and patient answers to dumb questions.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11883" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/MC380nqW-FA" height="1" width="1"/&gt;</description><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/08/26/producing-and-consuming-messages-using-masstransit-and-structuremap.aspx</feedburner:origLink></item><item><title>Mobile Case Creation</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/ctq7kss2G0o/mobile-case-creation.aspx</link><pubDate>Thu, 30 Jul 2009 17:44:30 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11852</guid><dc:creator>kmiller</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11852.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11852</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11852</wfw:comment><description>&lt;p&gt;One of the most requested features we get for Dovetail Mobile Agent is the ability to create cases. Request no more. Wait no longer. Well, maybe just a bit longer. I just finished an update that adds mobile create case functionality. We are going to use it internally for awhile before shipping it. If you want to take it for a test drive send me an email. Here is a sneak peek for everyone.&lt;/p&gt;  &lt;h3&gt;Finding the correct customer&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilefindcustomer_6D00EF53.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Search for the customer you are helping" border="0" alt="Search for the customer you are helping" src="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilefindcustomer_thumb_1694BA87.jpg" width="324" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Technically this screen was the most difficult to pull off. Finding a customer is typically the first thing you do when creating a case. In this situation it tells us two very important things: who is the contact for the case and what site are they are working at. Looking at the image above I see room for improvement. See this is why we are &lt;/p&gt;  &lt;p&gt;Behind the scenes here we are using new features in our Seeker search technology that allows Mobile to search for contacts. &lt;/p&gt;  &lt;h5&gt;Too much information. Move along…&lt;/h5&gt;  &lt;p&gt;To make this work we created a SQL View that returns records for contacts that are distinct to a site. We used this view to generate a &lt;strong&gt;contact&lt;/strong&gt; domain in the Seeker search index. When you search for &lt;strong&gt;domain:contact AND Miller&lt;/strong&gt; you get back all contacts named Miller no matter where they work even if they are really the same person. A good example is in the screen shot above Mark Miller is a contact in the system that works at both First Choice and Itty Bitty Machine. &lt;/p&gt;  &lt;p&gt;There is yet more nerdy info about how we enhanced Seeker to make all this work. You can request to include custom search fields with search results. Which is how we get both the contact id and site id for each contact search hit. Also search results can be optionally sorted by a custom search field. This is how we are displaying the search results in alphabetically order rather then by relevance.&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h3&gt;Composing a case&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecomposecase_03DFC0D0.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="Composing a case" border="0" alt="Composing a case" src="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecomposecase_thumb_2A41A41B.jpg" width="324" height="484" /&gt;&lt;/a&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecomposecaseselectingseverity_50A38766.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="iPhone drop down selection is really cool!" border="0" alt="iPhone drop down selection is really cool!" src="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecomposecaseselectingseverity_thumb_34269586.jpg" width="324" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This screen is pretty straight forward. Now that you have selected a contact you can enter details about the case set the severity and create it.&lt;/p&gt;  &lt;h3&gt;Case Created&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecasecreated_73844916.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="mobile-case-created" border="0" alt="mobile-case-created" src="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecasecreated_thumb_60CF4F5F.jpg" width="324" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The case is created and the Agent can continue working it by: sending an email, calling the customer, or dispatching the case to a support queue.&lt;/p&gt;  &lt;h3&gt;Contact Details&lt;/h3&gt;  &lt;p&gt;&lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecontactview_3928D335.jpg"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" title="mobile-contact-view" border="0" alt="mobile-contact-view" src="http://blogs.dovetailsoftware.com/blogs/kmiller/mobilecontactview_thumb_54612C36.jpg" width="324" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;As long as I am blabbing on and on we recently added this contact details view which lets an Agent see a contact’s details and open cases.&lt;/p&gt;  &lt;p&gt;What do you think? Suggestions? Look and feel ?&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11852" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/ctq7kss2G0o" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/search/default.aspx">search</category><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/dovetail/default.aspx">dovetail</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/30/mobile-case-creation.aspx</feedburner:origLink></item><item><title>Dovetail Seeker 1.2 Released</title><link>http://feedproxy.google.com/~r/KevinMiller/~3/429uqz1drxA/dovetail-seeker-1-2-released.aspx</link><pubDate>Tue, 21 Jul 2009 19:14:55 GMT</pubDate><guid isPermaLink="false">5c171a62-8cd2-4aac-8f20-46c3ac3f3269:11846</guid><dc:creator>kmiller</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.dovetailsoftware.com/blogs/kmiller/comments/11846.aspx</comments><wfw:commentRss>http://blogs.dovetailsoftware.com/blogs/kmiller/commentrss.aspx?PostID=11846</wfw:commentRss><wfw:comment>http://blogs.dovetailsoftware.com/blogs/kmiller/rsscomments.aspx?PostID=11846</wfw:comment><description>&lt;p&gt;If you are not a Dovetail customer be prepared for a boring post. If you are a fan or our search product. Be prepared to be rocked! &lt;/p&gt;  &lt;p&gt;My last &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/09/dovetail-seeker-update.aspx"&gt;couple&lt;/a&gt; of &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/14/dovetail-seeker-update-part-deux.aspx"&gt;posts&lt;/a&gt; have been talking about the cool stuff coming out in the next version of Dovetail Seeker? Well, the next version of Dovetail Seeker is here. I hope you enjoy it. &lt;/p&gt;  &lt;p&gt;I’d love to know how you are using Seeker in your organization below or if you prefer off-line.&lt;/p&gt;  &lt;hr /&gt;   &lt;h2&gt;&lt;span style="mso-fareast-font-family:'Times New Roman';"&gt;&lt;font size="5"&gt;&lt;font color="#365f91"&gt;&lt;font face="Cambria"&gt;What’s new in version 1.2 &lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&lt;/span&gt;&lt;/h2&gt;  &lt;h4&gt;Important Changes&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Dovetail Seeker now requires version 3.5 SP1 of the .Net framework.&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;Seek.exe has been renamed to SeekerConsole.exe &lt;/li&gt;    &lt;li&gt;Application settings are now located in the install directory within the &lt;i&gt;applicationSettings.config&lt;/i&gt; file. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;New Features&lt;/h3&gt;  &lt;p&gt;Dovetail Seeker &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/09/dovetail-seeker-update.aspx"&gt;now includes a Windows service&lt;/a&gt; for keeping your search index up to date. For more information see Seeker Windows Service.&lt;/p&gt;  &lt;p&gt;Dovetail Seeker &lt;a href="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/14/dovetail-seeker-update-part-deux.aspx"&gt;can now index Clarify views&lt;/a&gt;. Documentation updated to give examples and caveats about basing document specifications on views.&lt;/p&gt;  &lt;p&gt;The Seeker Console application can now re-index your search index. This is useful to remove content from your search index after database purge.&lt;/p&gt;  &lt;h3&gt;Bug Fixes&lt;/h3&gt;  &lt;p&gt;Seeker Web clients doing searches are now directed to avoid caching search results.&lt;/p&gt;  &lt;p&gt;Documentation added about Search Query Syntax.&lt;/p&gt;&lt;img src="http://blogs.dovetailsoftware.com/aggbug.aspx?PostID=11846" width="1" height="1"&gt;&lt;img src="http://feeds.feedburner.com/~r/KevinMiller/~4/429uqz1drxA" height="1" width="1"/&gt;</description><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/search/default.aspx">search</category><category domain="http://blogs.dovetailsoftware.com/blogs/kmiller/archive/tags/dovetail+release/default.aspx">dovetail release</category><feedburner:origLink>http://blogs.dovetailsoftware.com/blogs/kmiller/archive/2009/07/21/dovetail-seeker-1-2-released.aspx</feedburner:origLink></item></channel></rss>
