<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" 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/"><channel><title>Hadi Hariri</title><link>http://devlicio.us/blogs/hadi_hariri/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Zen Coding and ReSharper PowerToys</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/11/zen-coding-and-resharper-powertoys.aspx</link><pubDate>Thu, 11 Mar 2010 11:25:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55858</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=55858</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/11/zen-coding-and-resharper-powertoys.aspx#comments</comments><description>&lt;p&gt;Yesterday the &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;&amp;nbsp;&lt;a href="http://twitter.com/resharper"&gt;Twitter Account&lt;/a&gt; tweeted about a Zen Coding Plug-in available as a PowerToy. If you&amp;rsquo;re not familiar with Zen Coding, &lt;a href="http://vimeo.com/7405114"&gt;check out this link&lt;/a&gt;. I received a couple of emails from people asking about the PowerToys and what exactly they were, and to be honest, I wasn&amp;rsquo;t really surprised. I don&amp;rsquo;t think many have actually heard of them. So I decided to follow &lt;a href="http://www.hanselman.com/"&gt;Hanselman&amp;rsquo;s&lt;/a&gt; advice of minimizing key strokes, thus the post.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;What are they?&lt;/h4&gt;
&lt;p&gt;The Power Toys are a series of plug-ins that have been written by the ReSharper developer team, and have been used in fact internally as samples of ReSharper&amp;rsquo;s API. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Where can I get them and how do I install them?&lt;/h4&gt;
&lt;p&gt;You can download the PowerToys for ReSharper 5 from the Early Access Program page (for previous versions, see What next?), which is &lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+5.0+Nightly+Builds"&gt;here&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_41FBCBC7.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_38AF6AB9.png" border="0" height="272" width="527" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Unless there&amp;rsquo;s some API change, there are normally compatible from one build to the next, but just to be safe, download the one corresponding to the nightly build you have. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_34756D27.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_36EE7918.png" border="0" height="340" width="479" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;They are packaged up in a zip file that contains MSI installers for each individual plug-in, as well as a PowerToys Pack which includes them all (and you can pick and choose which one you want during the installation process). Best option is to just pick the full pack. Each MSI is also suffixed with a version, 8 corresponding to Visual Studio 2005, 9 to 2008 and 10 to 2010. &lt;/p&gt;
&lt;p&gt;The zip file also contains another zip with the source code, which you can compile and install, if you don&amp;rsquo;t want to use an installer. If you&amp;rsquo;re doing this, compile them and place them under the %Program files%\&lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt;\ReSharper\Bin\Plugins folder. Normally best to create a folder for each plug-in (If you&amp;rsquo;re just interested in having the source but prefer to use the MSI, the installer will also install the source for you).&lt;/p&gt;
&lt;p&gt;Once you install them, they should appear as plug-ins under the ReSharper menu:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7D2B9393.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_19D4E2DC.png" border="0" height="350" width="426" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you can see from the list, there are quite a few goodies in there, not only Zen Coding! &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;What next? &lt;/h4&gt;
&lt;p&gt;The PowerToys are not only valuable in terms of the functionality they provide, but also serve as an example of how to write ReSharper plug-ins and interact with the ReSharper API, but they&amp;rsquo;ve never been released passed Early Access Programs. That is one reason 4.5 PowerToys are not available. &lt;/p&gt;
&lt;p&gt;However, we want to change that. We not only want to make them available, but also to document them and offer them as a true OSS project, where the developer community can contribute to them, be it with additional features, bug fixes or providing completely new plug-ins. &lt;/p&gt;
&lt;p&gt;This is something that I personally think would be valuable for the community. If you like this idea or have other suggestions, please feel free to give me feedback. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55858" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category></item><item><title>Profiling Apps 1 of N: The MVC ActionLink</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/09/profiling-apps-1-of-n-the-mvc-actionlink.aspx</link><pubDate>Tue, 09 Mar 2010 20:34:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55802</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=55802</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/09/profiling-apps-1-of-n-the-mvc-actionlink.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m starting a new series of blogs posts on profiling, where we&amp;rsquo;ll try and cover common bottlenecks and how to identify them in your applications. However, before delving deeper into the subject, let me make a small but important observation:&lt;/p&gt;
&lt;p align="center"&gt;&lt;i&gt;Your bottleneck is probably not your for loop&lt;/i&gt;&lt;/p&gt;
&lt;p align="left"&gt;Now, replace that &lt;i&gt;for loop &lt;/i&gt;with &lt;i&gt;switch statement&lt;/i&gt;, an older version of some outdated algorithm that you feel needs optimizing, or that retched collection of classes that would perform better if you were using an array to loop through them, and you&amp;rsquo;ll end up with the same observation.&lt;/p&gt;
&lt;h3&gt;Premature Optimization&lt;/h3&gt;
&lt;p align="left"&gt;When dealing with business applications, it is unusual for major performance problems to be pinpointed down to specific portions of code or a concrete implementation of an algorithm. Usually most of the issues are bottlenecks at the data level, network level or purely down to how a business decision is made. &lt;/p&gt;
&lt;p&gt;Whether we use an ORM or use SQL directly, incorrectly formulated queries are one of the most predominant causes of bad performance. Not understanding concepts such as Lazy or Eager loading when using an ORM can be disastrous to the performance of an application, and are usually portrayed as &amp;ldquo;ORM XYZ sucks at performance&amp;rdquo;.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Network bandwidth and latency are other issues; when dealing with web applications for instance, having large pages (i.e. ViewState) or rendering Javascript directly without using script files, are a common problem for performance penalties. Making heavy calls to the server when very little information is required (i.e. UpdatePanel used incorrectly) are again main causes for concern. &lt;/p&gt;
&lt;p&gt;In many cases, design decisions we make early can affect the performance of our applications, and it is important to identify these concerns and address them correctly. Using an ORM, &lt;a href="http://nhprof.com"&gt;profiling it&lt;/a&gt;, understanding how Ajax really works and not worrying about &lt;a href="http://jquery.org"&gt;working with Javascript&lt;/a&gt;, or using an &lt;a href="http://nservicebus.com"&gt;asynchronous architecture&lt;/a&gt; when dealing with long running business processes are many ways to avoid bad performance in the long run. &lt;/p&gt;
&lt;p&gt;On the other hand, what we shouldn&amp;rsquo;t do is focus on micro-optimizations, on trying to make the most efficient, yet completely undecipherable algorithm to calculate the probability of winning money when buying lottery tickets, when the underlying problem is a bottleneck caused by a bad query. This kind of approach is often referred to as Premature Optimization, and can be disastrous for a project. &lt;/p&gt;
&lt;h3&gt;When it does boil down to code&lt;/h3&gt;
&lt;p&gt;Having said all that, there are times when we need better performance after having eliminated all the obvious causes, and need to discover why something is not performing as well as it should be. Of course, these concerns are greater when the nature of our application demands highly optimized code. In these cases, it is crucial to understand how things work in order to solve the problem. As a old-school boy, before we had managed libraries and drag-n-drop, I&amp;rsquo;m also a firm believer that it is always important to understand how things work under the covers, even if it is to just improve one self&amp;#39;s knowledge. &lt;/p&gt;
&lt;p&gt;Therefore, in these series of blog posts about performance, I&amp;rsquo;m going to focus on the latter, examining the details of code and how some things can perform better than others. So given the disclaimer, let&amp;rsquo;s get down to business. &lt;/p&gt;
&lt;p&gt;In order to do performance tuning, you need to use a tool. Setting stopwatches doesn&amp;rsquo;t work, because as &lt;a href="http://www.devspace.com/"&gt;Christian Gross&lt;/a&gt; so rightly pointed out during one of his talks, and I semi-quote: &amp;lsquo;if you&amp;rsquo;re using a stopwatch, you think you know where the bottleneck is. Most of the time, you&amp;rsquo;re wrong&amp;rsquo;.&amp;nbsp; If you are setting using a manual approach of setting calling Start and Stop, trying to time something, you&amp;rsquo;re assuming you know that the performance problem is located in a particular point, and many times it is not that point. So you end up having to place these kind of diagnostic codes in various places in your code, and soon it becomes a maintenance nightmare. Fortunately, there are tools that can profile your application in a non-invasive manner. When talking about SQL profiling, there&amp;rsquo;s &lt;a href="http://nhprof.com"&gt;NHProfiler&lt;/a&gt; for instance. When it comes to code performance profiling, the two most known ones are &lt;a href="http://www.red-gate.com/products/index.htm"&gt;ANT Profiler&lt;/a&gt; and &lt;a href="http://www.jetbrains.com/dottrace"&gt;dotTrace&lt;/a&gt;. I&amp;rsquo;m going to be using dotTrace. I used it before joining &lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt; and continue to use it now that I&amp;rsquo;m at JetBrains. I&amp;rsquo;ll be using &lt;a href="http://www.jetbrains.net/confluence/display/NetProf/4.0+Nightly+Builds"&gt;version 4.0&lt;/a&gt; which is currently (at the time of writing this post), in &lt;a href="http://www.jetbrains.net/confluence/display/NetProf/4.0+Nightly+Builds"&gt;Early Access Program&lt;/a&gt; and with Beta being released very soon. &lt;/p&gt;
&lt;h3&gt;To Express or not Express&lt;/h3&gt;
&lt;p&gt;Those that are familiar with it ASP.NET MVC know it relies heavily on the use of strings in many areas. For instance, when defining ActionLinks, you write&lt;/p&gt;
&lt;p align="center"&gt;Html.ActionLink(&amp;ldquo;Home&amp;rdquo;, &amp;ldquo;Index&amp;rdquo;, &amp;ldquo;Home&amp;rdquo;)&lt;/p&gt;
&lt;p align="left"&gt;where the first parameter is the link text, the second the Action and the third parameter is the Controller. The problem with this of course is that if you type either the second or third parameter incorrectly, you won&amp;rsquo;t know until runtime. Even if you build your views it won&amp;rsquo;t help. &lt;/p&gt;
&lt;p align="left"&gt;An alternative is to use Expression based Html Helpers (&lt;a href="http://hadihariri.com/blogengine/post/2010/01/20/ASPNET-Support-in-ReSharper-5.aspx"&gt;another option&lt;/a&gt; is to use &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; of course :)). These are strongly-typed ActionLinks that do not ship out of the box with ASP.NET MVC, but are available as a separate download in the &lt;a href="http://aspnet.codeplex.com/releases/view/39978"&gt;MVC Futures&lt;/a&gt; assembly, which can be thought of as a kind of sandbox for Microsoft to play with. Some of the functionalities in this library have eventually made it to the main core, such as &lt;i&gt;RenderPartial&lt;/i&gt;, which was in fact there from pretty much the early Previews of MVC 1, and didn&amp;rsquo;t get all the excitement until it made it into the core in version 2. Other functionality, including the expression based ActionLinks haven&amp;rsquo;t made it in yet. When using these helpers, the previous link would be: &lt;/p&gt;
&lt;p align="center"&gt;Html.ActionLink&amp;lt;HomeController&amp;gt;( a =&amp;gt; a.Index, &amp;ldquo;Home&amp;rdquo;)&lt;/p&gt;
&lt;p align="left"&gt;In principle this looks good, and begs the question of why it is not in the main core. Well I don&amp;rsquo;t know the exact reason, but one could potentially be due to it&amp;rsquo;s performance. Several people have talked about the difference in terms of rendering when using this version as opposed to the standard string based one. You can find one of those &lt;a href="http://codeclimber.net.nz/archive/2009/04/17/the-performances-implications-of-the-expression-tree-based-actionlink-helper.aspx"&gt;posts here&lt;/a&gt;. What I thought I&amp;rsquo;d do, is actually see how much difference in speed there is between one and the other. &lt;/p&gt;
&lt;h3&gt;The Project&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m using a very simple project for this profiling. It&amp;rsquo;s your standard ASP.NET MVC 2 application. On Index page, I&amp;rsquo;ve added two blocks of code:&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:23dd89a5-1ba6-4e74-9e95-9d4c09d76120" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#000000;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;for&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; (&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;int&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; i = &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;0&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i &amp;lt; &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;1000&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i++)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;= Html.ActionLink(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Link &amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; + i, &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Index&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;)&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e8bc64;"&gt;br&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;for&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; (&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;int&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; i = &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;0&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i &amp;lt; &lt;/span&gt;&lt;span style="color:#6897bb;"&gt;1000&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;; i++)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;= Html.ActionLink&amp;lt;&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;HomeController&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;gt;(a =&amp;gt; a.Index(), &lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Link &amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; + i)&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#e8bc64;"&gt;br&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; /&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;&amp;lt;%&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;%&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p align="left"&gt;The first &lt;i&gt;for &lt;/i&gt;loop will render out 1000 links using the string based ActionLink version, whereas the second loop will do the same using the expression-based one. &lt;/p&gt;
&lt;p align="left"&gt;What we want to do now is run this and see how long it takes for each loop to complete. &lt;/p&gt;
&lt;h3&gt;Setting up dotTrace Profiler&lt;/h3&gt;
&lt;p&gt;Working with &lt;a href="http://www.jetbrains.com/dottrace"&gt;dotTrace&lt;/a&gt; is as easy as it gets. There are two ways to profile an application: Standalone or integrated within Visual Studio. In the case of the former, you can start up dotTrace outside of Visual Studio and point to an application to profile. On the other hand if you have it integrated inside Visual Studio, then all you need to do is click on the Profile menu option: &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_1B563413.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4C093BBE.png" border="0" height="150" width="312" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Once we do that, we get a dialog box that provides us a series of options, mainly to do with the type of profiling we are going to perform. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_1E3B72F9.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4358BD65.png" border="0" height="225" width="330" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Since we&amp;rsquo;re profiling a web application, we can either use the Development Server or Internet Information Server. In our case we&amp;rsquo;re going to use the former. dotTrace will automatically pick up the server settings as well as fill out the physical path for our application. &lt;/p&gt;
&lt;p&gt;Next come the profiling options. The basic settings are Profiling Type and Meter Kind. The first parameter indicates how profiling will take place. It can be:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sampling: dotTrace will do frequent analysis of calls stacks. It&amp;rsquo;s the least intrusive, has very little impact on performance, but gives approximate timing. &lt;/li&gt;
&lt;li&gt;Tracing: dotTrace receives notifications from the CLR on entry/exit of methods. More precise timing and call information. &lt;/li&gt;
&lt;li&gt;Line-by-Line: dotTrace logs times for every statement in methods. Most precise but also has higher impact on performance. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tracing is normally the recommended option. Meter Kind defines how dotTrace logs the time: CPU instruction or Performance counter (uses the Windows API and samples are hardware independent). &lt;/p&gt;
&lt;h3&gt;Profiling our application&lt;/h3&gt;
&lt;p&gt;Once we have everything setup, we can start profiling our app. dotTrace will launch a small panel that allows us to control data sampling. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_19954272.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_45D1C956.png" border="0" height="194" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;dotTrace does not by default however launch the browser. In order to do so, we need to either click on the WebDev server and Open in Browser or just type the URL directly in the browser. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2399BDD0.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_349DEBB3.png" border="0" height="103" width="193" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;The next step is to perform the operations we want to profile and then click on GetSnapshot. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_45A21996.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_51C393BD.png" border="0" height="268" width="372" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Since in our case, having rendered the &lt;i&gt;Index &lt;/i&gt;action performs these operations, once the page has been loaded, we can click on GetSnapshot and have the profiler launched. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2F8B8837.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_08AD4C2A.png" border="0" height="293" width="430" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to get into all of the details of dotTrace in this first post because otherwise it would never end;&amp;nbsp; we&amp;rsquo;ll cover some of the aspects in future posts. For now, lets focus on our performance test at hand which is the difference between the two types of ActionLinks (string and expression based). &lt;/p&gt;
&lt;p&gt;The easiest way to find what we are looking for is to use the&amp;hellip;you guessed it, Find feature. Ctrl+F will bring up a dialog box similar to ReSharper&amp;rsquo;s Type location. We can then type ActionLink to filter the list of functions down to the ones that interest us&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_248E5B55.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_54D5300B.png" border="0" height="83" width="467" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;We can see that there are two versions, as expected. Let&amp;rsquo;s drill in to the second one first, the string based one. Hitting Enter will find the first location. We can then press F3 until we find the one that interests us. Remember, Site.Master and other references to this call also exist. We&amp;rsquo;re specifically looking for the loop, the one with 1000 calls&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_39502E08.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_00955E2E.png" border="0" height="171" width="546" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;We can see that the &lt;i&gt;ActionLink&lt;/i&gt; call takes 121ms for 1000 calls. Drilling in, we can see exactly where the time is spent, and 104ms of that is calling &lt;i&gt;GenerateUrl&lt;/i&gt;. Now let&amp;rsquo;s take a look at the Expression based ActionLink&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_45BD8F8A.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_56B197A0.png" border="0" height="116" width="542" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;For the same 1000 calls it takes 140ms, which is an increase of approximately 17%. Diving in once again, we can see that 6ms of this is in the parsing of the expression tree, &lt;i&gt;GetRouteValuesFromExpression. &lt;/i&gt;What this function does is merely analyze the expression to extract the ActionName from the parameter. The ControllerName it already has since it&amp;rsquo;s the concrete type the generic method is invoked with, returning both values in a &lt;i&gt;RouteValueDictionary&lt;/i&gt;. As such it then needs to call &lt;i&gt;GenerateRouteLink &lt;/i&gt;as opposed to &lt;i&gt;GenerateLink &lt;/i&gt;since the former takes a &lt;i&gt;RouteValueDictionary &lt;/i&gt;as a parameter, whereas the latter takes strings indicating the controller and action. They ultimately both call &lt;i&gt;GenerateUrl&lt;/i&gt;. &lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;From the results, the difference between the two calls is not that significant for 1000 links. As the number of links increment, the difference between the two does not change significantly. For instance, rendering 10.000 links, has a difference of 50ms between one version and another. What&amp;rsquo;s interesting that having run the same profiling on previous
releases, the difference in time was nearly double, so there seems to
have been improvement in this area. And as we can see, sometimes what might seem a performance problem, isn&amp;#39;t necessarily one.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55802" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Profiling/default.aspx">Profiling</category></item><item><title>MSpec Live Templates</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/01/mspec-live-templates.aspx</link><pubDate>Mon, 01 Mar 2010 15:07:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55580</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=55580</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/03/01/mspec-live-templates.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using MSpec (&lt;a href="http://github.com/machine/machine.specifications"&gt;Machine.Specifications&lt;/a&gt;), you&amp;rsquo;ve no doubt run into the verbosity of it. Here&amp;rsquo;s a typical specification in MSpec&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3ce97efd-5c56-4b7e-b368-f1899582fb49" class="wlWriterEditableSmartContent"&gt;
&lt;div style="border:#000080 1px solid;color:#000;font-family:&amp;#39;Courier New&amp;#39;, Courier, Monospace;font-size:10pt;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt; &lt;ol style="background:#000000;margin:0 0 0 2.5em;padding:0 0 0 5px;"&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;[&lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;Subject&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;(&lt;/span&gt;&lt;span style="color:#a5c25c;"&gt;&amp;quot;Registering as new a usergroup&amp;quot;&lt;/span&gt;&lt;span style="color:#ffffff;"&gt;)]&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#cc7832;"&gt;class&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="color:#ffc66d;"&gt;when_requesting_registration_page&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;Establish&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; context = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;Because&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; of = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="color:#6897bb;"&gt;It&lt;/span&gt;&lt;span style="color:#ffffff;"&gt; should_display_blank_registration_form = () =&amp;gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;{&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color:#ffffff;"&gt;};&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style="color:#ffffff;"&gt;}&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The code is usually divided into three areas, the &lt;i&gt;Establish &lt;/i&gt;that defines the context, &lt;i&gt;Because &lt;/i&gt;which is defined as the action to take, and finally one or more benefits that are defined as &lt;i&gt;It&lt;/i&gt; sections. Having this layout makes it easier to understand specifications and both the console runner as well as ReSharper&amp;rsquo;s MSpec runner remove underscores and provide a nice formatting. &lt;/p&gt;
&lt;h3&gt;Live Templates&lt;/h3&gt;
&lt;p&gt;However when it comes to typing all this in, well all those brackets and symbols become tiring. For that I normally use &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; Live Templates. If you&amp;rsquo;re not familiar with these, think of them as code snippets that allow interaction. Each template is uniquely identified by a shortcut, which is a series of characters. To invoke it, you simply type the characters and hit TAB. It then inserts some code. Up to this point it&amp;rsquo;s like a normal snippet. The twist however is that you can then TAB through placeholders and define values (I&amp;rsquo;ll cover&amp;nbsp; Live Templates and all the possibilities it allows in a future post). &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2B76B94F.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_1BF3A780.png" border="0" height="186" width="397" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;What I&amp;rsquo;ve been using for a while are some Live Templates for MSpec that allow me to define specifications with a little less effort. The first one is for empty specifications, which is useful for defining scenarios for features and then later proceeding to implement them, named &lt;i&gt;espec&lt;/i&gt;. The second one is for the specifications and implementation, named &lt;i&gt;spec&lt;/i&gt;. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7C6457AA.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5EA2CCEB.png" border="0" height="305" width="394" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;To install them, the easiest way is to just open up Live Templates (ReSharper menu) and Import the &lt;a href="http://hadihariri.com/Downloads/mspecbasiclivetemplate.xml"&gt;following file&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; .   &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_76E5C139.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_272C95F0.png" border="0" height="186" width="335" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Obviously these are just two simple versions and can be expanded on. For instance, if you use Behaviors in MSpec, you could write an additional one for that. Feel free to use them for your own needs. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55580" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/MSpec/default.aspx">MSpec</category></item><item><title>Technological shortcomings driving business needs</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/02/15/technological-shortcomings-driving-business-needs.aspx</link><pubDate>Mon, 15 Feb 2010 13:41:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55405</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=55405</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/02/15/technological-shortcomings-driving-business-needs.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Recent conversation I had with someone the other day:&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Jack&lt;/b&gt;: Yes, but we can&amp;rsquo;t do it like that. The business does not work that way.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: Why does it not work that way? &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Jack&lt;/b&gt;: It&amp;rsquo;s a fundamental aspect of the business. We can&amp;rsquo;t change that.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: And I accept that, but have you thought about why it is like that? &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Jack&lt;/b&gt;: Well because it&amp;rsquo;s not viable. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: Why is it not viable ?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Jack&lt;/b&gt;: It would cause too much havoc. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Me&lt;/b&gt;: Why would it cause too much havoc?&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Jack&lt;/b&gt;: Well because the software doesn&amp;rsquo;t allow it. &lt;/p&gt;
&lt;p&gt;Reading this script, one would think that it is quite absurd, yet this situation is quite common. &lt;/p&gt;
&lt;h3&gt;Updating a legacy system&lt;/h3&gt;
&lt;p&gt;Jack in this case was a developer, that is working on re-designing an existing system. But Jack could be anyone. In fact, many times, Jack is a user of the system. &lt;/p&gt;
&lt;p&gt;Users are many times accustomed to having software impose the way they do their job. They have to accommodate their process to that of the way the software they are using functions. What then happens is that they become used to this way of working to the point that they actually change their process, to work with the system, many times attempting to make their own life easier. &lt;/p&gt;
&lt;p&gt;The problem is of course that these changes have an impact on the business. At times this influences productivity, at other times revenue, or even how dealing with customers is handled, ultimately jeopardizing the business or its potential.&lt;/p&gt;
&lt;p&gt;When the time comes to develop a new system, what was considered an impediment has now become a fundamental pillar of how the business should work. As such, the user no longer thinks of how he/she would ideally want to do his/her job and have the software adapt to that, but lets his/her requirements be driven by technology. &lt;/p&gt;
&lt;p&gt;Of course, all this become even more vicious when new users join the scene. They are not aware of the real reasons behind certain workings and assume that that is how it is meant to be, no questions asked. &lt;/p&gt;
&lt;h3&gt;Focus on the customer, not the software&lt;/h3&gt;
&lt;p&gt;It is very important for us to analyze the true needs of our users, to make them look beyond existing systems and offer them the possibility of describing how &lt;i&gt;they&lt;/i&gt; would want to work if they had a blank sheet of paper and could start from scratch. If we have the opportunity to re-design an existing system, let&amp;rsquo;s make sure we base it on the users needs, not the existing software. &lt;/p&gt;
&lt;p&gt;Upgrading existing systems is not about making them use the latest, greatest and most shiny technology. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55405" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Design/default.aspx">Design</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Architecture/default.aspx">Architecture</category></item><item><title>ASP.NET Support in ReSharper 5</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/01/20/asp-net-support-in-resharper-5.aspx</link><pubDate>Wed, 20 Jan 2010 17:04:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:55082</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=55082</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/01/20/asp-net-support-in-resharper-5.aspx#comments</comments><description>&lt;p&gt;Although I mentioned briefly in the past some of the new features ASP.NET MVC features &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; 5 supports, I thought it would be a good idea to sum up the main ones in a single post and go into a little bit more detail on them. &lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;ASP.NET&lt;/h3&gt;
&lt;p&gt;ReSharper &amp;lsquo;s support for ASP.NET is not restricted only to MVC.In fact, most of the new features are for general ASP.NET, be it WebForms (also known as Traditional, Classic, For Historical Purposes Only?) or MVC. &lt;/p&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;Go to File Member&lt;/h4&gt;
&lt;p&gt;As part of the code navigation features of ReSharper, you have the possibility to locate a file member, be it a method, property, class, etc. very easily by using the the &lt;i&gt;Go To File Member&lt;/i&gt; (Alt+\) option. You can search instantly and hit Enter to navigate to the specific one. [For the record, I&amp;rsquo;m using the Visual Studio Keyboard Scheme. If you&amp;rsquo;re using IntelliJ (why?) go to the web site and download the &lt;a href="http://www.jetbrains.com/resharper/documentation/documentation.html"&gt;PDF mapping files&lt;/a&gt;.]&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_5EB46561.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_497639EC.png" border="0" height="229" width="447" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Notice how it it looks for anything that matches the characters introduced, so for instance typing &amp;ldquo;Exc&amp;rdquo; would give us all those with the word &amp;ldquo;Exception&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_453C3C5A.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_75831110.png" border="0" height="193" width="452" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Well you now have this functionality in ASPX, ASCX, ASAX and Web.config files also as of ReSharper 5!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_4DFC1ED9.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_44BFE398.png" border="0" height="371" width="357" /&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The same goes for the File Structure tool Window (Ctrl+Alt+F). &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_5981B64B.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_7EFB0DDF.png" border="0" height="354" width="466" /&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Go To Related Files&lt;/h4&gt;
&lt;p&gt;Many times, an ASPX has references to other files, such as Cascading Style Sheets, Javascript Files, Master Pages and User Controls. You can now navigate to these files efficiently by using the Go To Related Files (Ctrl+Alt+F7)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_5593A014.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_34DCB0A2.png" border="0" height="251" width="669" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Master Pages&lt;/h4&gt;
&lt;p&gt;Version 5 also adds support for Master and Content Pages. To begin with, we have added support for navigation. Using &lt;i&gt;Go To Declaration (&lt;/i&gt;Ctrl+Left Mouse) on the &lt;i&gt;ContentPlaceHolderID&lt;/i&gt; will take you from the Content Form/Page to the corresponding ContentPlaceHolder of the Master Page&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_27F234B7.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5760A383.png" border="0" height="81" width="660" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_49ADE77B.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_7341B2AE.png" border="0" height="155" width="662" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you are in the Master Page, you can navigate to all its inheritors (Shift+Alt+F12)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7E1E93F6.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_22CFAB6E.png" border="0" height="269" width="459" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;You can also create content place holders from usage. When defining a &lt;i&gt;ContentPlaceHolderID &lt;/i&gt;that does not exist, you have the option to create it in the Master Page (Alt+Enter)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_4901DEF9.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_3C2788DB.png" border="0" height="148" width="668" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Last but not least, in a page that uses a master page, you can generate content place holders by pressing Alt+Ins&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_3CD03F05.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5010F5A4.png" border="0" height="250" width="201" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;which in turn will bring up a dialog box for you to pick and choose what you want&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_543ACD69.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_514568B6.png" border="0" height="236" width="425" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;User Controls &lt;/h4&gt;
&lt;p&gt;You can now navigate to user controls as well as automatically import the correct references. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_26A987D9.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4C33053A.png" border="0" height="187" width="504" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;File Generation&lt;/h4&gt;
&lt;p&gt;There are new code generation options for ASP.NET with version 5. By pressing Alt+Ins in the Solution Explorer, we are presented with a popup menu&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_28B660D5.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_789BE986.png" border="0" height="576" width="311" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;where you can choose from a selection of items to generate. You can also access this menu from anywhere (not only in the Solution Explorer) by now pressing Ctrl+Alt+Ins. This is actually an awesome new addition to ReSharper 5 (Ctrl+Alt+Ins) and it removes even more friction when create new items!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_154538CF.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5A115D03.png" border="0" height="185" width="409" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re asked for a name (which is the base minimum required to create an item) and If the item selected requires more information, then we&amp;rsquo;ll be prompted accordingly. For example, when creating a WebForm with Master Page, it&amp;rsquo;s convenient to specify which Master Page we want to use. In this case, once the page has been created, we&amp;rsquo;ll be given a chance to provide this information&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_220F6920.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_6094B6C6.png" border="0" height="113" width="505" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;I have to say, that I love Ctrl+Alt+Ins in ReSharper 5. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Refactoring and Assistance&lt;/h4&gt;
&lt;p&gt;In terms of Refactoring and Coding Assistance there are a few new features. One of them is the auto-update of ending tags. If you have for instance a &lt;i&gt;div&lt;/i&gt; tag, and want to change it to &lt;i&gt;span&lt;/i&gt;, as you start typing &lt;i&gt;span&lt;/i&gt;, the end tag is automatically updated to reflect the changes you&amp;rsquo;re making live. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_04D99B49.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_3A8EE0A3.png" border="0" height="431" width="251" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you have a series of elements that you want to surround within a tag, you can easily do this by selecting all the elements and choosing Surround with Template (Ctrl+E,U)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_2ABF25D2.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_21EF1D86.png" border="0" height="225" width="365" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_6C95E553.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_7D9A1336.png" border="0" height="174" width="131" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_28FE3431.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_079E8E95.png" border="0" height="101" width="369" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ASP.NET MVC &lt;/h3&gt;
&lt;p&gt;ReSharper 5 treats ASP.NET MVC as a first class citizen. As such, it now has knowledge of concepts such as Views, Controllers and Action. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Navigate to View&lt;/h4&gt;
&lt;p&gt;For those of you working with ASP.NET MVC, you might have noticed that Views are now underlined in Actions&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_77AF49D0.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_043CF6ED.png" border="0" height="118" width="430" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;When you click on the View with Ctrl+Left Mouse, you&amp;rsquo;ll be presented with a dropdown menu&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_6D2E75B0.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_79BC22CC.png" border="0" height="87" width="437" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Here you have two options. The first is to navigate to the source for the &lt;i&gt;View &lt;/i&gt;method (navigation to external sources is another new feature of ReSharper 5). The second option is to go to the View. Although you can navigate to the View in Visual Studio by right-clicking and selecting &lt;i&gt;Go To View&lt;/i&gt;, one advantage the underlining adds is that it serves as hint for non-existent views, as you can see in the action below, which doesn&amp;rsquo;t have a corresponding View file. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_49B1D14B.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5CF287EA.png" border="0" height="118" width="380" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;View discovery also works with named Views. If a named view exists, the string literal will be underlined&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_061A2029.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_64BA7A8C.png" border="0" height="111" width="380" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;On the other hand, if it doesn&amp;rsquo;t exist, it will be highlighted as an error, once again providing you the benefit of discovering any missing views earlier on. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7B994C08.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_485D129F.png" border="0" height="129" width="373" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;Action Links&lt;/h4&gt;
&lt;p&gt;Those of us who have worked with ASP.NET MVC applications, know the problems with using strings when defining ActionLinks. Not only do you run into issues when refactoring, but misspelling an action or controller causes unnecessary pain. Some of us, including myself, have often resorted to using the expression based Actions available in the MVC Futures library. &lt;/p&gt;
&lt;p&gt;ReSharper 5 now provides Intellisense, preventing you from mistyping Actions and Controllers&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_73C13399.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_04592E88.png" border="0" height="143" width="550" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Similar to named Views, if you define a non-existing Action, you will get it highlighted. The difference here is that by pressing Alt+Enter, ReSharper will create the Action for you (create based on usage)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_0163C9D5.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_37854224.png" border="0" height="131" width="550" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_55171D23.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_4CB347CC.png" border="0" height="138" width="549" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And much like Views, you can now navigate to Actions and Controllers from an ActionLink by choosing &lt;i&gt;Go To Declaration &lt;/i&gt;(Ctrl+Left Mouse) on the Action and Controller respectively. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_70F82C4E.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_02F44A0F.png" border="0" height="155" width="554" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;User Controls &lt;/h4&gt;
&lt;p&gt;Navigation is also provided for User Controls&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_78DFA8E3.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_49418A57.png" border="0" height="98" width="476" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;as well as Intellisense&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_019F8B63.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_6371CDAE.png" border="0" height="161" width="475" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Summary&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve outlined some of the main features that ReSharper 5 brings to the table in regard to ASP.NET. There are many smaller features that you can discover eventually as you play with it more. If you haven&amp;rsquo;t yet, make sure you download 5 from &lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt;. Don&amp;rsquo;t forget to follow &lt;a href="http://twitter.com/resharper"&gt;ReSharper on Twitter&lt;/a&gt; if you want tips, tricks and latest info.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=55082" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Writing plug-ins for ReSharper: Part 1 of Undefined</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2010/01/12/writing-plug-ins-for-resharper-part-1-of-undefined.aspx</link><pubDate>Tue, 12 Jan 2010 13:27:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54980</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=54980</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2010/01/12/writing-plug-ins-for-resharper-part-1-of-undefined.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt; does a lot of things, but as they say, you can&amp;rsquo;t please &lt;a href="http://twitter.com/mfeathers/status/7406170728"&gt;all the&lt;/a&gt; people all of the time. However, one the great things about ReSharper is that it is quite extensible and there are already quite a number plug-ins available. Some of the better known ones are:&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://stylecopforresharper.codeplex.com"&gt;StyleCop for ReSharper&lt;/a&gt; by &lt;a href="http://howard.vanrooijen.co.uk/blog"&gt;Howard Van Rooijen&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;- &lt;a href="http://code.google.com/p/resharper-tdd-productivity-plugin/"&gt;TDD Productivity Plugin&lt;/a&gt; by &lt;a href="http://www.lostechies.com/blogs/hex/"&gt;Eric Hexter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;- &lt;a href="http://github.com/agross/machine.specifications/tree/master/Libraries/ReSharper/"&gt;ReSharper Test Runner&lt;/a&gt; for &lt;a href="http://github.com/machine/machine.specifications"&gt;MSpec&lt;/a&gt; by &lt;a href="http://therightstuff.de/"&gt;Alexander Gro&amp;szlig;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and of course there is also the &lt;a href="http://www.jetbrains.com/resharper/plugins/"&gt;repository of plug-ins available from the JetBrains site&lt;/a&gt;, where many of these are located. &lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m no expert on writing plug-ins for ReSharper, and the authors of the previous ones leave the bar quite high, but seeing that I actually now have the time to play with them, I&amp;rsquo;ve decided to do so by sharing my experiences with you in a series of blog posts. &lt;/p&gt;
&lt;p&gt;The ReSharper API is pretty extensive and can be overwhelming as I&amp;rsquo;ve been discovering, so I want to try and take it slowly. This might mean that at times, the code is not always complete and might be missing a few checks for example, but will come in due course. &lt;/p&gt;
&lt;p&gt;Everything that I&amp;rsquo;ll cover applies to &lt;a href="http://www.jetbrains.com/resharper/beta/beta.html"&gt;version 5.0 which is currently in Beta&lt;/a&gt;. There have been some changes from previous versions so if you&amp;rsquo;re working with 4.5 some of the code might not work. &lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;The First Plug-in&lt;/h3&gt;
&lt;p&gt;I was initially intending to write a useless plug-in for the first demo that didn&amp;rsquo;t do much, but after talking to &lt;a href="http://twitter.com/orangy/"&gt;Orangy&lt;/a&gt; (aslo known as Ilya) who commented on a tweet Jeremy Skinner had posted a few days back:&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb51" alt="image_thumb51" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb51_5F00_7A64442B.png" border="0" height="238" width="473" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;we decided to use it as the first sample. &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to build up the sample over the next few series of posts, so the initial solution is not the ideal one or complete, but it will help introduce a few core concepts. Ideally this feature should be implemented as what&amp;rsquo;s known as a &lt;i&gt;QuickFix&lt;/i&gt; but we&amp;rsquo;re first going to do it as a &lt;i&gt;ContextAction&lt;/i&gt;. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ContextAction&lt;/h3&gt;
&lt;p&gt;So what exactly is a Context Action? It&amp;rsquo;s actions that can be applied based on the context (the name is quite descriptive). They shows up as items in a popup menu which is invoked using Alt+Enter (don&amp;rsquo;t use the mouse for this&amp;hellip;it&amp;rsquo;s very unproductive). &lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb4" alt="image_thumb4" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb4_5F00_7C711D27.png" border="0" height="97" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;What we want to do in this first version of the plug-in is to write a new action that makes methods that are public and not declared virtual, virtual, something NHibernate users would appreciate greatly. As mentioned previously, in this first version we&amp;rsquo;re going to add a context action. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;1. Creating a plug-in assembly&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;ReSharper plug-ins are assemblies that are located in Plugins folder (by default %programFiles%\JetBrains\ReSharper\v5.0\Bin\Plugins). Each plug-in is in it&amp;rsquo;s own folder and doesn&amp;rsquo;t require any further registration. Therefore the first step is to create a class library which will host our context action.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. Creating the Context Action Skeleton&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;In order to create a context action, we need to implement the &lt;i&gt;IContextAction &lt;/i&gt;interface. This interface has one method &lt;i&gt;IsAvailable&lt;/i&gt; which indicates to us if that particular action is available given the context, and a property of type &lt;i&gt;IBulbItem[]&lt;/i&gt; which contains a series of bulb items. Each &lt;i&gt;IBulbItem&lt;/i&gt; in turn has a property &lt;i&gt;Text&lt;/i&gt; which is the text that appears next to the item in the context dropdown, and an &lt;i&gt;Execute &lt;/i&gt;action, which is what happens when the item is selected. So as we can see, a context action can consist of more than one bulb item. An added benefit to this decoupling is the re-usability of bulb items. By implementing &lt;i&gt;IBulbItem&lt;/i&gt;, we can potentially use it in more than once place (obviously if it makes sense).&lt;/p&gt;
&lt;p&gt;Many times however, we only want one bulb item per action, and to somehow simplify the process, we can inherit from the &lt;i&gt;BulbItemImpl &lt;/i&gt;class. This class defines an abstract &lt;i&gt;Text &lt;/i&gt;property that represents the text of the bulb item, and also has an &lt;i&gt;ExecuteTransaction&lt;/i&gt; member which is where our code is executed. We&amp;rsquo;ll see the difference between this method and &lt;i&gt;Execute&lt;/i&gt; shortly.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6bd1437c-d08c-453d-8bfd-63640ee43d54" class="wlWriterSmartContent"&gt;
&lt;div style="border-bottom:#000080 1px solid;border-left:#000080 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;color:#000;font-size:10pt;border-top:#000080 1px solid;border-right:#000080 1px solid;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt;       &lt;ol style="padding-bottom:0px;margin:0px 0px 0px 2.5em;padding-left:5px;padding-right:0px;background:#000000;padding-top:0px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;class&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;MakeMethodVirtualContextActions&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;: &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;BulbItemImpl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IContextAction&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;protected&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;override&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;Action&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ITextControl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;gt; ExecuteTransaction(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ISolution&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; solution, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IProgressIndicator&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; progress)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;();&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;override&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;string&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; Text&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;get&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; { &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;(); }&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;bool&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; IsAvailable(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IUserDataHolder&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; cache)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;();&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;     &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Before implementing any of the methods, there&amp;rsquo;s one thing we need to do. ReSharper requires that context action have a constructor with a parameter that implements a &lt;i&gt;IContextActionDataProvider&lt;/i&gt;. This parameter is actually useful to use to provide information about the context as we&amp;rsquo;ll see shortly. Therefore, we need to add a constructor to the previous code (lines 6-9). Since our action is only for C#, we will use a &lt;i&gt;ICSharpContextActionDataProvider&lt;/i&gt;. We then save this provider for later use (line 3). What we&amp;rsquo;re effectively doing here of course is nothing more than dependency injection. The plumbing (passing in the correct provider) is taken care of for us by ReSharper.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8ccd7ae7-ad88-4e81-a256-4357e662b61b" class="wlWriterSmartContent"&gt;
&lt;div style="border-bottom:#000080 1px solid;border-left:#000080 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;color:#000;font-size:10pt;border-top:#000080 1px solid;border-right:#000080 1px solid;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt;       &lt;ol style="padding-bottom:0px;margin:0px 0px 0px 2.5em;padding-left:5px;padding-right:0px;background:#000000;padding-top:0px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;class&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;MakeMethodVirtualContextAction&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; : &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;BulbItemImpl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IContextAction&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;readonly&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ICSharpContextActionDataProvider&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; _provider;&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; MakeMethodVirtualContextAction(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ICSharpContextActionDataProvider&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; provider)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;_provider = provider;&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;protected&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;override&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;Action&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ITextControl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;gt; ExecuteTransaction(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ISolution&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; solution, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IProgressIndicator&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; progress)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;();&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;override&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;string&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; Text&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;get&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; { &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;(); }&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;bool&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; IsAvailable(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IUserDataHolder&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; cache)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;throw&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;new&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;NotImplementedException&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;();&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;     &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. Defining Availability&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The next step is to define when our action is available. In order to do so, we need to implement the &lt;i&gt;IsAvailable&lt;/i&gt; method. In our case, we want to convert methods that are public and not virtual, to virtual. We therefore need to identify methods that are public and not virtual. We also need to filter out static methods. In order to get access to the current context we&amp;rsquo;re in, we can use the &lt;i&gt;provider&lt;/i&gt; we injected in via the constructor. The &lt;i&gt;provider &lt;/i&gt;has a &lt;i&gt;GetSelectedElement&lt;/i&gt; method which corresponds to the element the caret is on. Since we&amp;rsquo;re interested in a method, we can invoke this function, requesting back a method declaration. If the caret is in the context of a method (i.e. header, body), it will return this information. If it&amp;rsquo;s not, it will return null.&lt;/p&gt;
&lt;p&gt;If we have a valid method declaration, the next step is to find out if it is public. We do that by invoking &lt;i&gt;GetAccessRights &lt;/i&gt;[In later series we&amp;rsquo;ll see that further checks are necessary here]. If it is public, we then need to check whether it is a static method, an override or already virtual. Based on that, we return &lt;i&gt;true&lt;/i&gt; or &lt;i&gt;false&lt;/i&gt;, indicating whether the action is available in the current context. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:08892768-5c0f-43d7-bcea-9d5c989520f2" class="wlWriterSmartContent"&gt;
&lt;div style="border-bottom:#000080 1px solid;border-left:#000080 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;color:#000;font-size:10pt;border-top:#000080 1px solid;border-right:#000080 1px solid;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt;       &lt;ol style="padding-bottom:0px;margin:0px 0px 0px 2.5em;padding-left:5px;padding-right:0px;background:#000000;padding-top:0px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;bool&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; IsAvailable(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IUserDataHolder&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; cache)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;var&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; item = _provider.GetSelectedElement&amp;lt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IMethodDeclaration&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;gt;(&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;false&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;true&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;);&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;if&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; (item != &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;null&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;var&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; accessRights = item.GetAccessRights();&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;if&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; (accessRights == &lt;/span&gt;&lt;span style="background:#000000;color:#bf82d7;"&gt;AccessRights&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;.PUBLIC &amp;amp;&amp;amp; !item.IsStatic &amp;amp;&amp;amp; !item.IsVirtual &amp;amp;&amp;amp; !item.IsOverride)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;return&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;true&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;;&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;return&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;false&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;;&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;     &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. Performing the action&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;When the action is available and the user selects it, what we need to do is make the method virtual. This is done in the &lt;i&gt;ExecuteTransaction&lt;/i&gt; method. Since we are going to modify the code, we need to make sure that the file is writable. Normally this would be done by invoking a call to a method named &lt;i&gt;EnsureWritable. &lt;/i&gt;However, inside the method &lt;i&gt;ExecuteTransaction&lt;/i&gt;, this is done for us, so we don&amp;rsquo;t have to worry about it. This is one of the differences between &lt;i&gt;ExecuteTransaction &lt;/i&gt;and &lt;i&gt;IBulbItem.Execute&lt;/i&gt;. &lt;/p&gt;
&lt;p&gt;So how do we go about modifying code in ReSharper? Well remember that refactoring code is ReSharper&amp;rsquo;s daily bread. It&amp;rsquo;s what it does. As such, there&amp;rsquo;s a ton of infrastructure in place to allow us to do modify code easily. In fact, making a method virtual is as easy as calling a method, as shown below. &lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1204f257-3604-47b1-8adc-681470f842d7" class="wlWriterSmartContent"&gt;
&lt;div style="border-bottom:#000080 1px solid;border-left:#000080 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;color:#000;font-size:10pt;border-top:#000080 1px solid;border-right:#000080 1px solid;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt;       &lt;ol style="padding-bottom:0px;margin:0px 0px 0px 2.5em;padding-left:5px;padding-right:0px;background:#000000;padding-top:0px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;protected&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;override&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;Action&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ITextControl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;gt; ExecuteTransaction(&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;ISolution&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; solution, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IProgressIndicator&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; progress)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;var&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; method = _provider.GetSelectedElement&amp;lt;&lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IMethodDeclaration&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;&amp;gt;(&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;false&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;true&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;);&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;if&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; (method != &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;null&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;)&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;method.SetVirtual(&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;true&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;);&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;return&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;null&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;;&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;}&lt;/span&gt; &lt;/li&gt;
&lt;/ol&gt;     &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. Testing the plug-in&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The only thing left to do is test that it works (writing unit tests for plug-ins is something we&amp;rsquo;ll cover in the future). One option is to copy the assembly to the plug-in folder for ReSharper and restart Visual Studio. However, in order to be able to debug it, what we can do is set the project properties to start an external program, which is non other than &lt;i&gt;devenv.exe&lt;/i&gt;, and pass as parameter to it &lt;i&gt;/ReSharper.Plugin &amp;lt;Path_to_Plugin_Assembly&amp;gt;&lt;/i&gt;, instructing ReSharper to load a specific plug-in.&lt;/p&gt;
&lt;p&gt;How does ReSharper know which classes in the assembly are context actions? The easiest way is to decorate these with the &lt;i&gt;ContextAction &lt;/i&gt;attribute&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:816a2e31-64f6-4d00-80aa-ab30a90b5de4" class="wlWriterSmartContent"&gt;
&lt;div style="border-bottom:#000080 1px solid;border-left:#000080 1px solid;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;color:#000;font-size:10pt;border-top:#000080 1px solid;border-right:#000080 1px solid;"&gt;
&lt;div style="background:#ddd;overflow:auto;"&gt;       &lt;ol style="padding-bottom:0px;margin:0px 0px 0px 2em;padding-left:5px;padding-right:0px;background:#000000;padding-top:0px;"&gt;
&lt;li&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;[&lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;ContextAction&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;(Group=&lt;/span&gt;&lt;span style="background:#000000;color:#a5c25c;"&gt;&amp;quot;C#&amp;quot;&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, Name = &lt;/span&gt;&lt;span style="background:#000000;color:#a5c25c;"&gt;&amp;quot;MakeMethodVirtual&amp;quot;&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, Description = &lt;/span&gt;&lt;span style="background:#000000;color:#a5c25c;"&gt;&amp;quot;Adds context action to make methods virtual&amp;quot;&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;)]&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;public&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#cc7832;"&gt;class&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;MakeMethodVirtualContextAction&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt; : &lt;/span&gt;&lt;span style="background:#000000;color:#ffc66d;"&gt;BulbItemImpl&lt;/span&gt;&lt;span style="background:#000000;color:#ffffff;"&gt;, &lt;/span&gt;&lt;span style="background:#000000;color:#6897bb;"&gt;IContextAction&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;{&lt;/span&gt; &lt;/li&gt;
&lt;li&gt;&amp;nbsp;&amp;nbsp; &lt;span style="background:#000000;color:#ffffff;"&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;     &lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This information is also what appears under ReSharper &amp;ndash;&amp;gt; C# &amp;ndash;&amp;gt; Context Actions&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb1" alt="image_thumb1" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb1_5F00_73A114DB.png" border="0" height="279" width="462" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Now all that&amp;rsquo;s left is to try it out. Write a new class, add a few methods and check to see it&amp;rsquo;s all working correctly.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb41" alt="image_thumb41" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb41_5F00_4C56A5D9.png" border="0" height="188" width="438" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Public static method (not available)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb5" alt="image_thumb5" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb5_5F00_5B3DD4F3.png" border="0" height="123" width="437" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Private method (not available)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="image_thumb7" alt="image_thumb7" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb7_5F00_3EE06D06.png" border="0" height="206" width="434" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Public method (option available)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:709f2834-932c-4f9c-b242-351e666e3c37" class="wlWriterSmartContent"&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:709f2834-932c-4f9c-b242-351e666e3c37" class="wlWriterSmartContent"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:905932bc-aad6-4994-8db7-63b30b97fccc" class="wlWriterSmartContent"&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:07444c36-2481-4557-b32b-f8c211b3e445" class="wlWriterSmartContent"&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:64c132f0-0ecb-48de-a052-a7760451521b" class="wlWriterSmartContent"&gt;
&lt;div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px;" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:64c132f0-0ecb-48de-a052-a7760451521b" class="wlWriterSmartContent"&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;What&amp;rsquo;s next?&lt;/h3&gt;
&lt;p&gt;In this first part we&amp;rsquo;ve seen the basics of writing plug-ins for ReSharper. In the next blog post, we&amp;rsquo;ll extend the example to also include properties and we&amp;rsquo;ll change it to be a &lt;i&gt;QuickFix&lt;/i&gt; as opposed to a context action. This means that we&amp;rsquo;ll get some nice highlighting by ReSharper telling us something can be changed (similar to when you have something named incorrectly for instance), thus being more *in your face*.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s so much more to see than what&amp;rsquo;s here, and gradually we&amp;rsquo;ll drill more into each of the different areas, examining parameters, return values, etc. Until then, Happy ReSharping (did I just coin that? Too lame?)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54980" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ReSharper/default.aspx">ReSharper</category></item><item><title>Dynamic types and ASP.NET MVC</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/12/30/dynamic-types-and-asp-net-mvc.aspx</link><pubDate>Wed, 30 Dec 2009 12:29:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54813</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>13</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=54813</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/12/30/dynamic-types-and-asp-net-mvc.aspx#comments</comments><description>&lt;p&gt;If you&amp;rsquo;re using ViewModels in your ASP.NET MVC applications, know that if working with .NET 4.0, you can now create dynamic view models. And it&amp;rsquo;s actually very simple to do. &lt;/p&gt;
&lt;p&gt;Create an ExpandoObject to represent your ViewModel:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_277CA47E.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_1316DEF3.png" border="0" height="325" width="438" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Declare your view to be of type ViewPage&amp;lt;dynamic&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_4DAE1662.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_725F2DD9.png" border="0" height="270" width="460" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And you&amp;rsquo;re done. Here&amp;rsquo;s the output:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_58C77ADF.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" alt="image" src="http://devlicious.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_304898CB.png" border="0" height="317" width="458" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re using &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;, you will get &lt;a href="http://hadihariri.com/blogengine/post/2009/11/24/Dynamic-objects-and-ReSharper.aspx"&gt;Intellisense&lt;/a&gt; once you&amp;rsquo;ve declared a property once (both in the Action as well as the View). &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54813" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>Changes as of January 2010</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/12/26/changes-as-of-january-2010.aspx</link><pubDate>Sat, 26 Dec 2009 19:08:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54767</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=54767</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/12/26/changes-as-of-january-2010.aspx#comments</comments><description>&lt;p&gt;It&amp;rsquo;s with a bittersweet feeling that I write this post. As of January, I will no longer be with &lt;a href="http://www.imeta.co.uk"&gt;iMeta Technologies&lt;/a&gt;. During my time there, I&amp;rsquo;ve been involved in some awesome projects, had the privilege of working with some very smart and talented people, and made some great friends. I wish them all the best success in the future. &lt;/p&gt;
&lt;p&gt;As of January, I&amp;#39;m starting a new job. I&amp;rsquo;m going to go back to working from home, something I did for 8 years prior to joining iMeta, so for me it feels like home (pun intended). I have to admit that as much as I liked the office buzz and enjoyed every minute of working with &lt;a href="http://blogs.imeta.co.uk/sstrong/Default.aspx"&gt;Steve&lt;/a&gt; and his eternal ramblings on &lt;a href="http://blogs.imeta.co.uk/sstrong/archive/2009/12/16/823.aspx"&gt;expression trees&lt;/a&gt;, I am happy to not have to face morning and afternoon commutes.&lt;/p&gt;
&lt;p&gt;So what&amp;rsquo;s my new job? Well it comes as no surprise to many to say that I&amp;rsquo;ve been a fan of a tool called ReSharper for quite some time. I&amp;rsquo;ve been a member of the &lt;a href="http://www.jetbrains.com/devnet/academy/index.jsp"&gt;JetBrains Academy&lt;/a&gt; for a few years and have collaborated with JetBrains at various conference booths. We&amp;rsquo;ve now decided to formalize the relationship. &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m very excited to announce that as of January I will be joining &lt;a href="http://www.jetbrains.com"&gt;JetBrains&lt;/a&gt;. My primary role will be to help promote their products on the .NET side, which include ReSharper, dotTrace, as well as cross-platform tools such as TeamCity, YouTrack or WebIDE. As part of my job, I&amp;rsquo;ll be doing screen casts, blogging, and not only about using the tools, but also focusing on best practices, boosting productivity, etc. As a company that firmly believes in OSS, it also means that I&amp;rsquo;ll be increasing my participation in OSS projects and actually get to code on things I enjoy! &lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll be active in the community, continuing to speak at conferences and events, as well as serve as a liaison for JetBrains. I&amp;rsquo;ll continue to blog on &lt;a href="http://hadihariri.com"&gt;my own site&lt;/a&gt; as well as &lt;a href="http://devlicio.us/blogs/hadi_hariri"&gt;devlicious&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;As far as Twitter, we&amp;rsquo;ll be pushing the Tool-Specific Twitter accounts for &lt;a href="http://twitter.com/resharper"&gt;ReSharper&lt;/a&gt; and &lt;a href="http://twitter.com/dottrace"&gt;dotTrace&lt;/a&gt;, so make sure you follow them! You can contact me via my own &lt;a href="http://twitter.com/hhariri"&gt;twitter feed&lt;/a&gt;, and of course, don&amp;rsquo;t forget Ilya, also known as &lt;a href="http://twitter.com/orangy"&gt;Orangy&lt;/a&gt;, ReSharper PM!&lt;/p&gt;
&lt;p&gt;With that, all that&amp;rsquo;s left to say is Happy New Year and we&amp;rsquo;ll talk in 2010! And don&amp;rsquo;t start 2010 without &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54767" width="1" height="1"&gt;</description></item><item><title>Dynamic objects and ReSharper</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/24/dynamic-objects-and-resharper.aspx</link><pubDate>Tue, 24 Nov 2009 19:41:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54109</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=54109</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/24/dynamic-objects-and-resharper.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you might have heard by now, C# 4.0 (or is it just 4?&amp;hellip;) comes with a new keyword: &lt;b&gt;dynamic&lt;/b&gt;. This means that you could do something like the following:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_08E6464A.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_20314ABB.png" border="0" height="82" width="480" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Simply put, ExpandoObject is a class that allows you to add and remove members at runtime. This allows us to call methods that are resolved at runtime. As such, the previous code will compile. &lt;/p&gt;
&lt;p&gt;Just as you can declare methods, you can also declare properties:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_0AF31F46.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_5435C441.png" border="0" height="85" width="477" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This no doubt can come in handy when working with ViewModels and ASP.NET MVC. &lt;/p&gt;
&lt;p&gt;However, there is one minor problem with dynamic objects: you lose intellisense, which means that if in your view, instead of typing &lt;i&gt;dynaCustomer.FirstName&lt;/i&gt;, you type &lt;i&gt;dynaCustomer.FristName&lt;/i&gt;, you won&amp;rsquo;t get any errors until you run the app. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_3FCFFEB6.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_0FC5AD35.png" border="0" height="172" width="472" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;And that&amp;rsquo;s where ReSharper can help:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_7A8781BF.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_23AF19FE.png" border="0" height="230" width="468" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;This is the same code, but with ReSharper activated inside Visual Studio 2010! I typed the &lt;i&gt;FirstName &lt;/i&gt;property for the first time. After that, I have full intellisense support for it. The same would apply to methods:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_14B7C517.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" alt="image" src="http://devlicio.us/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/hadi_5F00_hariri/image_5F00_thumb_5F00_727FB990.png" border="0" height="173" width="470" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;That puts &lt;i&gt;dynamic &lt;/i&gt;into perspective. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54109" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category></item><item><title>Getting your OSS binaries with Horn</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/23/getting-your-oss-binaries-with-horn.aspx</link><pubDate>Mon, 23 Nov 2009 08:54:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:54037</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=54037</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/23/getting-your-oss-binaries-with-horn.aspx#comments</comments><description>&lt;p&gt;Recently &lt;a href="http://devlicio.us/blogs/billy_mccafferty"&gt;Billy McCafferty&lt;/a&gt; &lt;a href="http://devlicio.us/blogs/billy_mccafferty/archive/2009/10/29/the-horn-project-bringing-quot-apt-get-install-quot-to-net-projects.aspx"&gt;wrote a post&lt;/a&gt; on Horn, a package manager that &lt;a href="http://thesoftwaresimpleton.blogspot.com/"&gt;Paul Cowan&lt;/a&gt; and &lt;a href="http://www.davetheninja.net/"&gt;Dave the Ninja&lt;/a&gt; have developed, similar to the idea of Ruby&amp;rsquo;s Gem. Although it&amp;rsquo;s a step in the right direction, it does have issues. To be able to use it, you need to download Horn and build it. But not only that, you also need to install Subversion, Git, Powershell, Rake, PSake, Cake, Fake&amp;hellip;and a whole slew of SCM&amp;rsquo;s and build tools. Why? Because Horn builds from source. As such, it needs to access the SCM a specific project uses, download the files locally and run the build script. Since OSS projects are free to choose what build script they use, that also adds to the complexity. Some are happy with MSBuild, which isn&amp;rsquo;t normally an issue since it&amp;rsquo;s part of every .NET install. However, others use Rake, which in turn requires Ruby. You get the picture&amp;hellip;&lt;/p&gt;
&lt;p&gt;Although this isn&amp;rsquo;t necessarily an issue for some people, for others, it is. Forgetting for a moment scenarios such as those imposed by IT departments on corporate networks (permissions to install software, firewall, etc..), there are many that are not too comfortable with building from source, something beyond running an MSBuild file or compiling a VS solution inside the IDE. &lt;/p&gt;
&lt;h3&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3&gt;Welcome to Horn Server-Side&lt;/h3&gt;
&lt;p&gt;In order to ease some of these concerns, the Horn team developed a server-side solution. A service now takes care of figuring out all dependencies and building packages and since it does this on a scheduled basis, it saves you the time of having to wait for a project to be built. This also saves you from having to install anything on your machine, including SCM&amp;rsquo;s and build tools. In fact, you don&amp;rsquo;t need to install anything if you don&amp;rsquo;t want to. For you to interact with this server, Dave built an ASP.NET MVC application that shows all the OSS packages in their respective categories. For each package there is normally the official released version and the trunk. &lt;a href="http://www.imeta.com"&gt;iMeta&lt;/a&gt; has gracefully offered to host the server up in clouds. &lt;a href="http://hornget.net"&gt;Go see for yourself&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;If you prefer a command line version, I hacked one together in a morning and it&amp;rsquo;s available from the Horn repository. This allows you to issue commands like: &lt;/p&gt;
&lt;p&gt;&lt;i&gt;horn-get &amp;ndash;u &lt;/i&gt;&lt;a href="http://hornget.net"&gt;&lt;i&gt;http://hornget.net&lt;/i&gt;&lt;/a&gt;&lt;i&gt; &amp;ndash;c orm &amp;ndash;d nhibernate-2.1 &lt;/i&gt;&lt;/p&gt;
&lt;p&gt;which will download NHibernate 2.1 zip for you with the necessary binaries. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Take a look, experiment and &lt;a href="http://groups.google.com/group/horn-development"&gt;provide feedback to the Horn team&lt;/a&gt;. There is still room for improvement, but no doubt, Horn is helping remove some of the barriers in the adoption of Open Source. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=54037" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Tools/default.aspx">Tools</category></item><item><title>var improves readability</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/20/var-improves-readability.aspx</link><pubDate>Fri, 20 Nov 2009 07:12:08 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53798</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>26</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=53798</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/11/20/var-improves-readability.aspx#comments</comments><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Countless times I’ve heard the argument that you should use the &lt;strong&gt;var &lt;/strong&gt;keyword with caution, that it decreases readability of your code, or &lt;a href="http://weblogs.asp.net/stevewellens/archive/2009/11/19/can-the-c-var-keyword-be-misused.aspx"&gt;how it can be misused&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;The example given in the linked post is: &lt;/p&gt;  &lt;pre class="csharpcode"&gt;    var Data = GetData(); &lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;According to the blog post, &lt;em&gt;GetData &lt;/em&gt;returns a &lt;em&gt;DataTable&lt;/em&gt;, something not inherently apparent. The problem however is due to the naming conventions used by the developer. &lt;/p&gt;

&lt;p&gt;Firstly, &lt;em&gt;GetData &lt;/em&gt;is a method indicating that it returns Data. The problem is, pretty much anything is Data. There has to be a more precise definition of what it is the method is actually doing. By this, I don’t mean you should necessarily rename the method to &lt;em&gt;GetDataTable&lt;/em&gt;, since this doesn’t help. This just indicates what type it is returning, not what the method is doing. It would be an appropriate name if the domain of the problem were somehow about types, but in a business scenario, it doesn’t provide much value. &lt;/p&gt;

&lt;p&gt;The second issue and just as important, is the variable name, &lt;em&gt;data&lt;/em&gt;. Again, it is not descriptive enough. What is &lt;em&gt;data&lt;/em&gt;? What kind of information does it hold? Is it a &lt;em&gt;car&lt;/em&gt;? Is it many &lt;em&gt;cars&lt;/em&gt;? &lt;/p&gt;

&lt;p&gt;By using var, you are forcing yourself to think more about how you name methods and variables, instead of relying on the type system to improve readability, something that is more an implementation detail. Using the var keyword is not about being lazy, quite the contrary. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53798" width="1" height="1"&gt;</description></item><item><title>It’s all about the delivery</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/10/29/it-s-all-about-the-delivery.aspx</link><pubDate>Thu, 29 Oct 2009 20:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:53205</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=53205</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/10/29/it-s-all-about-the-delivery.aspx#comments</comments><description>&lt;p&gt;   &lt;br /&gt;The Dependency Inversion Principle states:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dd&gt;&lt;i&gt;A. High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/i&gt;&lt;/dd&gt;&lt;dd&gt;&lt;i&gt;B. Abstractions should not depend upon details. Details should depend upon abstractions.&lt;/i&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;  &lt;br /&gt;(Source WikiPedia).   &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codinghorror.com/blog/archives/001225.html"&gt;Throw that at a terrible programmer&lt;/a&gt;, and all you&amp;rsquo;ll get is a terrible programmer that is annoyed and hates you. So true!&lt;/p&gt;
&lt;p&gt;Take the following method:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintHelloMessage()&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Hello&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Now ask a developer to add a new method to print the message &amp;lsquo;Goodbye&amp;rsquo;. Do you think he would do:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintGoodbyeMessage()&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&lt;span class="str"&gt;&amp;quot;Goodbye&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;/pre&gt;
&lt;p&gt;
  &lt;br /&gt;or:&lt;/p&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;pre class="csharpcode"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; PrintMessage(&lt;span class="kwrd"&gt;string&lt;/span&gt; message)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(message);&lt;br /&gt;        }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;Most likely, he&amp;rsquo;d do the latter. Why? Because he realizes he&amp;rsquo;s gaining a benefit by passing a parameter to a method. He knows that if tomorrow you ask him for a &amp;ldquo;Good Afternoon&amp;rdquo; message, he won&amp;rsquo;t have to write a new method. &lt;/p&gt;
&lt;p&gt;What is Dependency Injection? It&amp;rsquo;s one way of complying with the Dependency Inversion Principle. However, when you think about it, what does it boil down to? Passing a parameter to a method, which happens to be a constructor. It seems simple enough doesn&amp;rsquo;t it? Yet, it&amp;rsquo;s hard for people to understand it. Why? because they don&amp;rsquo;t see the value in it. &lt;/p&gt;
&lt;p&gt;Explaining a principle to someone without them understanding the benefits and values they get out of it is useless, and that is why concepts such as Dependency Injection or Inversion of Control seem overly complex to the vast majority of developers (believe it or not, those of us that use these things are still a very big minority). It&amp;rsquo;s complex because they haven&amp;rsquo;t been explained the values of it. They&amp;rsquo;ve just been thrown some definition and they are expected to understand that it&amp;rsquo;s bad for one class to create an instance of another class it uses. &lt;/p&gt;
&lt;p&gt;Present a developer with the following code:&lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; AuthServices&lt;/pre&gt;
&lt;pre&gt;    {&lt;/pre&gt;
&lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AuthUser(&lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password)&lt;/pre&gt;
&lt;pre&gt;        {&lt;/pre&gt;
&lt;pre class="alt"&gt;            var authDAL = &lt;span class="kwrd"&gt;new&lt;/span&gt; AuthDAL();&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;            var user = authDAL.GetUserByUsername(username);&lt;/pre&gt;
&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (user != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;            {&lt;/pre&gt;
&lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; ...&lt;/pre&gt;
&lt;pre&gt;            }&lt;/pre&gt;
&lt;pre class="alt"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;pre&gt;        }&lt;/pre&gt;
&lt;pre class="alt"&gt;    }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;and ask them how they&amp;rsquo;d go about testing this code without having access to a database. Ask them how they&amp;rsquo;d go about changing AuthDAL for some fake DAL that doesn&amp;rsquo;t really connect to a database. &lt;/p&gt;
&lt;p&gt;They&amp;rsquo;ll probably come up with the solution of passing the AuthDAL class in as a parameter, and eventually realizing that multiple methods will use the same class, they&amp;rsquo;ll pass it in via the constructor and set it as an instance field. As long as their AuthDAL has virtual methods, they can create any fake DAL that overrides those methods and returns some dummy value. They might argue that they don&amp;rsquo;t want virtual methods. And that&amp;rsquo;s fine. Tell them to define the parameter as an interface. In fact, they probably have already heard of a principle that says that you should program to an interface and not a class. They&amp;rsquo;ll eventually end up with this code:&lt;/p&gt;
&lt;pre class="csharpcode"&gt;  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; AuthServices&lt;br /&gt;    {&lt;br /&gt;        IAuthDAL authDAL;&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; AuthServices(IAuthDAL authDAL)&lt;br /&gt;        {&lt;br /&gt;            _authDAL = authDAL;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AuthUser(&lt;span class="kwrd"&gt;string&lt;/span&gt; username, &lt;span class="kwrd"&gt;string&lt;/span&gt; password)&lt;br /&gt;        {&lt;br /&gt;            var user = _authDAL.GetUserByUsername(username);&lt;br /&gt;&lt;br /&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (user != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                &lt;span class="kwrd"&gt;if&lt;/span&gt; ...&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;
&lt;p&gt;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And voila! You have Dependency Injection via Constructor. &lt;/p&gt;
&lt;p&gt;Once they *get* that, then explain to them other benefits, you know the real benefits they get from doing this: decoupled code, easy maintenance, promotion of SRP, etc.&amp;nbsp; and then throw the principle in their face:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;dl&gt;&lt;dd&gt;&lt;dl&gt;&lt;dd&gt;&lt;i&gt;A. High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/i&gt; &lt;/dd&gt;&lt;dd&gt;&lt;i&gt;B. Abstractions should not depend upon details. Details should depend upon abstractions.&lt;/i&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/dd&gt;&lt;/dl&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;And they&amp;rsquo;ll see how it all makes sense. &lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s not about throwing or not throwing books. It&amp;rsquo;s about showing people how something can help them, how they get value of it. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=53205" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/hadi_hariri/archive/tags/Design/default.aspx">Design</category></item><item><title>Joined the tasty bites</title><link>http://devlicio.us/blogs/hadi_hariri/archive/2009/10/14/joined-the-tasty-bites.aspx</link><pubDate>Wed, 14 Oct 2009 08:29:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:52655</guid><dc:creator>Hadi Hariri</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devlicio.us/blogs/hadi_hariri/rsscomments.aspx?PostID=52655</wfw:commentRss><comments>http://devlicio.us/blogs/hadi_hariri/archive/2009/10/14/joined-the-tasty-bites.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Last week I was invited to join &lt;a href="http://devlicio.us"&gt;devlcio.us&lt;/a&gt;, part of &lt;a href="http://codebetter.com"&gt;codebetter.com&lt;/a&gt; blog network. Unfortunately with all the travelling I&amp;rsquo;ve not had a chance to even do my first blog post or thank both &lt;a href="http://devlicio.us/blogs/casey/"&gt;Jak&lt;/a&gt; and Brendan for the invitation, and seeing I&amp;rsquo;m currently stuck at Franfurt Airport on a 5 hour layover, it&amp;rsquo;s a better time than any.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll still be blogging on my &lt;a href="http://hadihariri.com"&gt;regular&lt;/a&gt; &lt;a href="http://blogs.imeta.co.uk/hhariri"&gt;sites&lt;/a&gt;, and as always, any non-technical off-topic posts will remain exclusively on &lt;a href="http://hadihariri.com"&gt;my own site&lt;/a&gt;. &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=52655" width="1" height="1"&gt;</description></item></channel></rss>