<?xml version="1.0" encoding="UTF-8"?><!--RSS generated by Windows SharePoint Services V3 RSS Generator on 04/09/2010 09:50:03--><?xml-stylesheet type="text/xsl" href="/blog/_layouts/RssXslt.aspx?List=98d5c6c7-5808-4bc4-a33a-5cd0f6350ed4" version="1.0"?><rss version="2.0"><channel><title>Blog</title><link>http://www.dotnetsolutions.co.uk/blog</link><description>RSS feed for the Posts list.</description><lastBuildDate>Sat, 04 Sep 2010 08:50:03 GMT</lastBuildDate><generator>SharePoint CKS:EBE</generator><ttl>60</ttl><image><title>Blog</title><url>http://www.dotnetsolutions.co.uk/blog/_layouts/images/homepage.gif</url><link>http://www.dotnetsolutions.co.uk/blog</link></image><item><title>Linger error</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/09/02/linger-error/</link><guid isPermaLink="False">/blog/archive/2010/09/02/linger-error/</guid><description><![CDATA[<div class="ExternalClass7484065DFA2247FDA119EA411D5CED15">
<p>One of the more significant challenges that we have faced during our last project presented itself to us about halfway through the project timeline. Our .Net Micro Framework application regularly sends messages to remote endpoints out on the internet over HTTPS/TCP. In isolation a single HTTPS request using the .Net Micro Framework was a pain free operation (even if there is no HTTPS stack out of the box). However, the problem was that after an indeterminate period of time our application would stop sending HTTP requests and would die a horrible death.</p>
<p>To confound matters further no exception were being raised and so we were not even able to catch the exception to a) gather more information or b) gracefully handle the error. Instead the board would just lock up and stop working, as the .Net Micro Framework runtime had crashed. </p>
<p>Given that we were not receiving an exception of any kind initial testing focused on the hardware that we were running on. We tested our software on both the <a href="http://www.ghielectronics.com/product/108">GHI Master Development System</a> and the <a href="http://www.devicesolutions.net/Products/TahoeII.aspx">Tahoe II board from Device Solutions Ltd</a> yet both products exhibited the same problems.</p>
<p>Focus shifted back to software, but given that no exceptions were throw and connecting to the device using the MF Deploy tool yielded no additional insight we could not ascertain the cause of the problem. Having scoured the code-base for any clues we decided to approach Microsoft with our rather odd problem. </p>
<p>After discussing the many intricacies of our application with the .Net Micro Framework team they provided us with an early build of the MF Deploy tool that was to be released with version 4 of the Framework. As soon as we started using this new version of MF deploy we started making progress.</p>
<p>The first thing that happened is we started to get an exception and stack trace information in the MF Deploy trace information. Now we had something to work from!</p>
<p>#### Exception System.Net.Sockets.SocketException - E_FAIL (1) #### <br>
#### Microsoft.SPOT.Net.SocketNative::socket [IP: 0000] #### <br>
#### System.Net.Sockets.Socket::.ctor [IP: 001f] #### <br>
#### SocketException ErrorCode = 10024</p>
<p>A brief search using <a href="http://www.red-gate.com/products/reflector/">Reflector</a> quickly led us to a brief description of the problem:</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/Lingererror_9BE2/image_2.png"><img width="438" height="349" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/Lingererror_9BE2/image_thumb.png"></a> </p>
<p>OK, so apparently we have opened too many sockets. Unfortunately; as is so often the case; this only succeeded in posing more questions than it answered.</p>
<p>Our HTTPS/TCP code opened and closed a socket on every request. Our Socket object was also wrapped in a using statement which meant that it would be disposed of after every call.</p>
<div class="csharpcode">
<pre class="alt">IPAddress address = GetHostAddress(uri);</pre>
<pre>IPEndPoint endpoint = <span class="kwrd">new</span> IPEndPoint(address, 80);</pre>
<pre class="alt"><span class="kwrd">using</span> (Socket socket = <span class="kwrd">new</span> Socket(</pre>
<pre>    AddressFamily.InterNetwork,</pre>
<pre class="alt">       SocketType.Stream, ProtocolType.Tcp))</pre>
<pre>{</pre>
<pre class="alt">    <span class="rem">//open the socket</span></pre>
<pre>    socket.Connect(endpoint);</pre>
<pre class="alt"> </pre>
<pre>    <span class="rem">//HTTP writing code removed </span></pre>
<pre class="alt">    <span class="rem">//to keep sample terse.</span></pre>
<pre>    <span class="rem">//close the socket</span></pre>
<pre class="alt">    socket.Close();</pre>
<pre><span class="rem">//dispose the socket</span></pre>
<pre class="alt">}</pre>
</div>
<p>So then why do we have too many sockets open? Another look at Reflector only served to strengthen our resolve that we had done everything correctly. The Dispose method did appear to clean up any of the native resources used by the Socket object:</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/Lingererror_9BE2/image_4.png"><img width="457" height="414" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/Lingererror_9BE2/image_thumb_1.png"></a> </p>
<p>Confused once more we approached Microsoft for an answer to our problems.</p>
<p>It was then that they informed us that by default when you close a Socket in the .Net Micro Framework it does not actually release the Socket for a further 2 minutes! This value is an option that you can set yourself with the following line of code:</p>
<div class="csharpcode">
<pre class="alt">socket.SetSocketOption(SocketOptionLevel.Tcp</pre>
<pre>                               , SocketOptionName.Linger</pre>
<pre class="alt">                               , <span class="kwrd">new</span> <span class="kwrd">byte</span>[] { 0, 0, 0, 0 });</pre>
</div>
<p> </p>
<p>So what is SocketOptionName.Linger? Assuming that it is the same as its <a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.socketoptionname.aspx">big brother equivalent in the .Net Framework</a> it is an option that is used to tell the socket to wait before closing so that any unsent data can be sent.</p>
<p>It should only be necessary to set the Linger time to 0 if you are expecting to open another Socket to the same address and port. If you are to set the Linger time to 0 then it is also recommended that you also set the NoDelay option to true so that any messages are sent immediately.</p>
<div class="csharpcode">
<pre class="alt">socket.SetSocketOption(SocketOptionLevel.Tcp</pre>
<pre>                      , SocketOptionName.NoDelay</pre>
<pre class="alt">                      , <span class="kwrd">true</span>);</pre>
</div>
<p>Complete example:
<style>
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode, .ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode pre
{margin:0em;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .rem
{color:#008000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .str
{color:#006080;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .op
{color:#0000c0;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .preproc
{color:#cc6633;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .html
{color:#800000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .attr
{color:#ff0000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .lnum
{color:#606060;}
</style>
</p>
<div class="csharpcode">
<pre class="alt">IPAddress address = GetHostAddress(uri);</pre>
<pre>IPEndPoint endpoint = <span class="kwrd">new</span> IPEndPoint(address, 80);</pre>
<pre class="alt"><span class="kwrd">using</span> (Socket socket = <span class="kwrd">new</span> Socket(</pre>
<pre>        AddressFamily.InterNetwork</pre>
<pre class="alt">       ,SocketType.Stream</pre>
<pre>       ,ProtocolType.Tcp))</pre>
<pre class="alt">{</pre>
<pre>    socket.SetSocketOption(SocketOptionLevel.Tcp</pre>
<pre class="alt">        , SocketOptionName.Linger</pre>
<pre>        , <span class="kwrd">new</span> <span class="kwrd">byte</span>[] { 0, 0, 0, 0 });</pre>
<pre class="alt">    socket.SetSocketOption(SocketOptionLevel.Tcp</pre>
<pre>        , SocketOptionName.NoDelay, <span class="kwrd">true</span>);</pre>
<pre class="alt">        </pre>
<pre>    <span class="rem">//open the socket</span></pre>
<pre class="alt">    socket.Connect(endpoint);</pre>
<pre> </pre>
<pre class="alt">    <span class="rem">//HTTP writing code removed </span></pre>
<pre>    <span class="rem">//to keep sample terse.</span></pre>
<pre class="alt"> </pre>
<pre>    <span class="rem">//close the socket</span></pre>
<pre class="alt">    socket.Close();</pre>
<pre><span class="rem">//dispose the socket</span></pre>
<pre class="alt">}</pre>
</div>
<style>
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode, .ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode pre
{margin:0em;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .rem
{color:#008000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .str
{color:#006080;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .op
{color:#0000c0;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .preproc
{color:#cc6633;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .html
{color:#800000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .attr
{color:#ff0000;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass93D8BC98AFF248C7A233EF701CCD8BEF .csharpcode .lnum
{color:#606060;}
</style>
<p>While we expecienced this problem using version 3 of the .Net Micro Framework, I am not aware whether the default behaviour has been changed in version 4.</p>
<p>This was the first (and simplest) of several intricacies in the .Net Micro Framework that we encountered during the course of this project. More in another blog post soon.</p>
<p>Author: Gavin Osborn <br>
<a href="http://twitter.com/gavinosborn" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">@gavinosborn</a> <br>
<br>
<a href="http://twitter.com/share?url=http://www.dotnetsolutions.co.uk/blog/archive/2010/09/02/Linger-error/&amp;via=dotnetsolutions&amp;related=gavinosborn&amp;text=Linger error" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">Tweet</a></p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Marcus</dc:creator><pubDate>Thu, 02 Sep 2010 11:07:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Micro Framework/">Micro Framework</category></item><item><title>Introducing the Meta Data Processor</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/08/31/introducing-the-meta-data-processor/</link><guid isPermaLink="False">/blog/archive/2010/08/31/introducing-the-meta-data-processor/</guid><description><![CDATA[<div class="ExternalClassC2903D7CBF2840EDB523F8DEF5833D47">
<p><b>This article was written from my experiences of working with version 3 of the .Net Micro Framework. Version 4 is now out and promises much – to the best of my knowledge this article is still relevant, but is as yet untested.</b></p>
<p><b>The Problem:</b></p>
<p>So you’ve been working on the .Net Micro Framework for a while. Recently you’ve added a couple of new classes to your project, implemented some new functionality and now it doesn’t compile. Your code has no syntax errors yet when you attempt to compile you get a strange non-descript build error:</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_2.png"><img width="429" height="65" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_thumb.png"></a> </p>
<p>The error gives no line of code to look at and the file it references isn’t something you recognise in your project –therefore it doesn’t appear to be a problem with your code, so what’s wrong?</p>
<p>This is one of several particularly unhelpful compile errors you can encounter from time to time when developing for the .Net Micro Framework. To find out more you need to do a little digging...</p>
<p>If you switch to the Output window and review the Build Output you will quickly notice an error that looks something like this:</p>
<a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_4.png"><img width="443" height="176" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_thumb_1.png"></a>
<p>The first thing you should notice here is that the window appears to successfully compile the project with ‘0 errors &amp; 0 warnings’. Why then does it ultimately fail?</p>
<p><b>Understanding .Net Micro Framework compilation:</b></p>
<p>Like regular .Net projects the .Net Micro Framework compilation process is a two stage process.</p>
<p>First the standard C# compiler (csc.exe) is called to compile the project into MSIL, just like any regular .Net assembly. What happens next is where the Micro Framework differs from it’s older brother; Micro Framework applications are not JIT compiled at runtime instead they are optimized at compile time by a tool called the Meta Data Processor. This optimised code is then interpreted at runtime.</p>
<p>The Meta Data Processor performs two functions.</p>
<p>1. Optimise the MSIL for the purpose of size. <br>
Our desktop machines may think nothing of an executable that is 10 MB in size but Micro Framework enabled devices are not likely to have much more than 1MB of space to store and run your application.</p>
<p>2. Optimise the code to use less runtime resources (RAM, etc). <br>
This applies various techniques such the use of a shared string table that stores class member information, text values and other common meta data used by the application.</p>
<p>Part of the optimisations above includes applying some hard internal limits to your applications. This is usually the cause of the above error. To see the more details of the compile error you need to run the MetaDataProcessor in the command prompt using the same arguments that caused it to fail. </p>
<a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_6.png"><img width="441" height="175" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_thumb_2.png"></a>
<p>You can copy the full command string (this is usually quite large) from the Build Output window (above) and paste it into your command prompt window and run it. The command prompt output should show you the same error but with greater detail: <a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_8.png"><img width="442" height="126" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/IntroducingtheMetaDataProcessor_C990/image_thumb_3.png"></a></p>
<p>In this case the maximum size of the shared string table had been exceeded.</p>
<p><b>The Solution:</b></p>
<p>The solution itself is fairly simple. These limits are on a per project/assembly basis. So to get around this problem all you need do is split your code into multiple projects. This is usually not too difficult and now that you are aware of these limitations you can start to plan ahead as you build your software project.</p>
<p><b>Other known Meta Data Processor Errors:</b></p>
<p>There are several other errors generated by the Meta Data Processor while optimising your code. These are not yet in any form of online documentation (at least none that I could find) that I have read. As a rule every one of these can be resolved by splitting up the project into multiple smaller components.</p>
<pre></pre>
<p>CLR_E_OUT_OF_RANGE: maximum size of stream 'ByteCode’ – The Micro Framework executable (.pe) files are limited to 65kb of optimised IL code each. </p>
<p>CLR_E_OUT_OF_RANGE: maximum size of stream 'MethodDef' – The number of methods defined in your assembly has exceeded the internal limit. </p>
<p>Of course, now that the latest version of the Micro Framework (including the Meta Data Processor) has been made open source the task of  hunting down the cause of these errors should be much simpler.</p>
Author: Gavin Osborn <br>
<a href="http://twitter.com/gavinosborn" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">@gavinosborn</a><br>
<br>
<a href="http://twitter.com/share?url=http://www.dotnetsolutions.co.uk/blog/archive/2010/08/31/Introducing-the-Meta-Data-Processor/&amp;via=dotnetsolutions&amp;related=gavinosborn&amp;text=Introducing the Meta Data Processor" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">Tweet</a> 
</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Marcus</dc:creator><pubDate>Tue, 31 Aug 2010 14:18:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Micro Framework/">Micro Framework</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Dev Tools/">Dev Tools</category></item><item><title>Unit Testing the .NET Micro Framework</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/08/18/unit-testing-the-net-micro-framework/</link><guid isPermaLink="False">/blog/archive/2010/08/18/unit-testing-the-net-micro-framework/</guid><description><![CDATA[<div class="ExternalClass27824EFF8E7F40A99B3FD0FE0EBA62E6">
<p>The .NET Micro Framework enables devices to be developed using the same managed C# language and Visual Studio tools we use for all our other projects. More details about the .NET Micro Framework can be found on the <a href="http://www.microsoft.com/netmf/default.mspx" target="_blank">Microsoft site</a>.</p>
<p>At Dot Net Solutions, we have a strong belief in <a href="http://www.dotnetsolutions.co.uk/agile" target="_blank">Agile</a> development and XP programming. So when we started to develop for the .NET Micro Framework, we immediately looked for its support for unit testing. However, we discovered that there was no support available. Not to be deterred from our ethos, we undertook to create our own.</p>
<p>The .NET Micro Framework supports reflection, thereby, giving the ability to execute “Test” methods. However, the .NET Micro Framework does not provide support for custom attributes, therefore, the following is not possible:</p>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode, .ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode, .ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<div class="csharpcode">
<pre class="alt">[TestMethod] <span class="rem">//no custom attributes</span></pre>
<pre><span class="kwrd">public</span> <span class="kwrd">void</span> TestStartsWith()</pre>
<pre class="alt">{</pre>
<pre>   ...</pre>
<pre class="alt">}</pre>
</div>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode, .ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<p>Instead, we used a convention based approach, requiring the word “Test” to be prefixing to all test methods names. We can then use reflection to call all public instance methods starting with “Test”.</p>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<div class="csharpcode">
<pre class="alt">Type[] types = assembly.GetTypes();</pre>
<pre><span class="kwrd">foreach</span> (var type <span class="kwrd">in</span> types)</pre>
<pre class="alt">{                </pre>
<pre>    MethodInfo[] methods = </pre>
<pre class="alt">        type.GetMethods(BindingFlags.Public</pre>
<pre>                        |BindingFlags.Instance);</pre>
<pre class="alt">    <span class="kwrd">foreach</span> (var method <span class="kwrd">in</span> methods)</pre>
<pre>    {</pre>
<pre class="alt">        <span class="kwrd">if</span> (method.Name.Length &gt;= 4 &amp;&amp; </pre>
<pre>            method.Name.Substring(0, 4) == <span class="str">&quot;Test&quot;</span>)</pre>
<pre class="alt">        {</pre>
<pre>            ...omitted </pre>
<pre class="alt">            <span class="kwrd">try</span></pre>
<pre>            {</pre>
<pre class="alt">                method.Invoke(<span class="kwrd">null</span>, <span class="kwrd">null</span>);</pre>
<pre>            }</pre>
<pre class="alt">            <span class="kwrd">catch</span> (Exception ex)</pre>
<pre>            {</pre>
<pre class="alt">                result.Status = ResultType.Fail;</pre>
<pre>                result.Exception = ex;</pre>
<pre class="alt">            }</pre>
<pre>            OnDisplayTestResult(<span class="kwrd">new</span> TestResultEventArgs </pre>
<pre class="alt">                    { TestResult = result });</pre>
<pre>        }</pre>
<pre class="alt">    }</pre>
<pre>}</pre>
</div>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<p>Using this naming convention for test methods and reflection to execute those methods provides part of the solution. The next challenge was to provide a host that would enable this approach to be used. Here the .NET Micro Framework does provide a solution. Our approach was to create a test harness project that would iterate all test methods in all test assemblies and execute them. The results are displayed in a custom emulator, which is set as the Deployment device for the test harness project.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/UnitTestingthe.NETMicroFramework_F0C1/image_4.png"><img width="244" height="128" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/UnitTestingthe.NETMicroFramework_F0C1/image_thumb_1.png"></a> </p>
<p>This emulator provides a simple user interface, allowing the number of successful test to be seen and information on any failing tests.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/UnitTestingthe.NETMicroFramework_F0C1/image_2.png"><img width="244" height="164" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/UnitTestingthe.NETMicroFramework_F0C1/image_thumb.png"></a></p>
<p>There is one critical part missing and that is the ability to “Assert” the expected outcome of a test and to manage the case where this assertion fails. A simple Assert class can be created for this with a number of static methods, such as IsTrue. This enables this common unit testing syntax, e.g. Assert.IsTrue, to be used in tests:</p>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode, .ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">void</span> TestStartsWith()</pre>
<pre>{</pre>
<pre class="alt">    <span class="kwrd">string</span> _testString = <span class="str">&quot;freakyKey&quot;</span>;</pre>
<pre>    Assert.IsTrue(!_testString.StartsWith(<span class="str">&quot;gav&quot;</span>)</pre>
<pre class="alt">        , <span class="str">&quot;The string freakyKey does not start with 'gav'&quot;</span>);</pre>
<pre>    Assert.IsTrue(_testString.StartsWith(<span class="str">&quot;freak&quot;</span>)</pre>
<pre class="alt">        , <span class="str">&quot;The string freakyKey does start with 'freak'&quot;</span>);</pre>
<pre>}</pre>
</div>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode, .ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<p>The implementation of Assert.IsTrue is shown below:</p>
<div class="csharpcode">
<pre class="alt"><span class="rem">/// &lt;summary&gt;</span></pre>
<pre><span class="rem">/// Assert whether the specified condition is true.</span></pre>
<pre class="alt"><span class="rem">/// &lt;/summary&gt;</span></pre>
<pre><span class="rem">/// &lt;param name=&quot;condition&quot;&gt;The condition to test.&lt;/param&gt;</span></pre>
<pre class="alt"><span class="rem">/// &lt;param name=&quot;message&quot;&gt;The message.&lt;/param&gt;</span></pre>
<pre><span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> IsTrue(<span class="kwrd">bool</span> condition, <span class="kwrd">string</span> message)</pre>
<pre class="alt">{</pre>
<pre>    <span class="kwrd">if</span> (!condition)</pre>
<pre class="alt">    {</pre>
<pre>        <span class="kwrd">throw</span> <span class="kwrd">new</span> AssertException(message);</pre>
<pre class="alt">    }</pre>
<pre>}</pre>
</div>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<p>We could have stopped there but how do we know that our framework does what we expect? We unit test it of course! We actually used our unit test framework... to test our unit test framework. Cool!</p>
<p>The unit test for the Assert.IsTrue method looks like this:</p>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<div class="csharpcode">
<pre class="alt"><span class="kwrd">public</span> <span class="kwrd">void</span> TestIsTrueAssertTrue()</pre>
<pre>{</pre>
<pre class="alt">    <span class="kwrd">try</span></pre>
<pre>    {</pre>
<pre class="alt">        Assert.IsTrue(<span class="kwrd">true</span></pre>
<pre>            , <span class="str">&quot;This should not throw an exception&quot;</span>);</pre>
<pre class="alt">    }</pre>
<pre>    <span class="kwrd">catch</span> (AssertException)</pre>
<pre class="alt">    {</pre>
<pre>        <span class="kwrd">throw</span> <span class="kwrd">new</span> AssertException(</pre>
<pre class="alt">        <span class="str">&quot;Assert.IsTrue should not throw an exception for true&quot;</span>);</pre>
<pre>    }</pre>
<pre class="alt">}</pre>
</div>
<style>
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{background-color:#ffffff;font-family:consolas, &quot;Courier New&quot;, courier, monospace;color:black;font-size:small;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode pre
{margin:0em;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .rem
{color:#008000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .str
{color:#006080;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .op
{color:#0000c0;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .html
{color:#800000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .attr
{color:#ff0000;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .alt
{background-color:#f4f4f4;margin:0em;width:100%;}
.ExternalClassADF651C86CC741C39C1D2F782C3FD538 .csharpcode .lnum
{color:#606060;}
</style>
<p>While the .NET Micro Framework does not provide support for unit testing out of the box, this should not deter you. The creation of a unit testing framework (and even testing that framework) can be achieved with a little effort.<br>
<br>
Author: Marcus Tillett <br>
<a href="http://twitter.com/drmarcustillett" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">@drmarcustillett</a><br>
<br>
<a href="http://twitter.com/share?url=http://www.dotnetsolutions.co.uk/blog/archive/2010/08/18/unit-testing-the-net-micro-framework/&amp;via=dotnetsolutions&amp;related=drmarcustillett&amp;text=Unit Testing the .NET Micro Framework" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">Tweet</a> </p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Marcus</dc:creator><pubDate>Wed, 18 Aug 2010 09:46:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Agile/">Agile</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Dev Tools/">Dev Tools</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Micro Framework/">Micro Framework</category></item><item><title>.NET Micro Framework Case Study</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/08/17/-net-micro-framework-case-study/</link><guid isPermaLink="False">/blog/archive/2010/08/17/-net-micro-framework-case-study/</guid><description><![CDATA[<div class="ExternalClass7FD6B96F3626493DB3153C195B2927DA">
<p>Here at Dot Net Solutions, we have been working on a project using the .NET Micro Framework for the past year. The .NET Micro Framework enables devices to be developed using the same managed C# language and Visual Studio tools we use for all our other projects.</p>
<p>More details about the .NET Micro Framework can be found on the <a href="http://www.microsoft.com/netmf/default.mspx" target="_blank">Microsoft site</a>. Much of the development and initial testing was done against the <a href="http://www.devicesolutions.net/Products/TahoeII.aspx" target="_blank">Tahoe II</a> board from Device Solutions. However, the target hardware was somewhat different from this.</p>
<p><img width="240" height="123" alt="" src="http://www.devicesolutions.net/Portals/0/Images/TahoeII-Large.png"></p>
<p>During the course of the project we discovered a number of interesting features of the .NET Micro Framework. Some of which relate specifically to version 3.0 and others that continue to be true for version 4.0. We have a number of blog posts planned to cover these soon.</p>
<p>One of the most challenging aspects of the project was the need to develop the software without access to the target hardware. This factor has been picked up by Microsoft in this recent case study, which is currently on the Micro Framework site <a href="http://www.netmf.com/TechnicalResource/Articles/10-08-16/Case_Study_from_Dot_Net_Solutions.aspx?id=4a76aa50-0df7-4fba-ad27-18a410089b62" target="_blank">Case Study from Dot Net Solutions</a>.</p>
</div>
Author: Marcus Tillett <br>
<a href="http://twitter.com/drmarcustillett" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">@drmarcustillett</a><br>
<br>
<a href="http://twitter.com/share?url=http://www.dotnetsolutions.co.uk/blog/archive/2010/08/18/-net-micro-framework-case-study/&amp;via=dotnetsolutions&amp;related=drmarcustillett&amp;text=.NET Micro Framework CaseStudy" target="_blank"><img alt="" border="0" src="http://a4.twimg.com/images/favicon.gif">Tweet</a>
<p> </p>
<div>
</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Marcus</dc:creator><pubDate>Tue, 17 Aug 2010 10:26:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Micro Framework/">Micro Framework</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Agile/">Agile</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Dev Tools/">Dev Tools</category></item><item><title>On the way home with Software + Services on the dashboard</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/08/02/on-the-way-home-with-software-+-services-on-the-dashboard/</link><guid isPermaLink="False">/blog/archive/2010/08/02/on-the-way-home-with-software-+-services-on-the-dashboard/</guid><description><![CDATA[<div class="ExternalClassC1D88D55EDC64A479A5D55CD1B0618D1">
<p>About once a week Johan sends out a company tweet about cool stuff that people were working with on Friday afternoon. I was on the way back from holiday but I did see something interesting.</p>
<p>Several months back I switched from a rival navigation system to a TomTom navigation system, and on Friday afternoon the TomTom asked me to make a U-Turn and showed exactly where to make the turn. </p>
<p>With the previous system that would mean I’d missed a turning, but the TomTom is looking ahead for me. As I crested the hill I could see the traffic jam on the opposite side of the valley. The turning point recommended was barely 50moff the tail end of the queue and a couple of turns later I was chasing down an empty B road almost parallel with the original route and picking apart what just happened.</p>
<p>Speculatively I think the following series of events occurred.</p>
<p>1) Several vehicles were stopped in that jam with TomTom devices on board</p>
<p>2)  These alerted home what was happening and TomTom updated a central database of traffic speeds</p>
<p>3) My TomTom called home to check conditions on the route </p>
<p>4) It noted that the route conditions had changed and started looking for alternate routes</p>
<p>5) It recommended a new route and validated conditions with the central server</p>
<p>6) I saved 20-30 minutes in a traffic jam (which would have increased my frustration and my fuel consumption)</p>
<p>7) I got home happy</p>
<p>Microsoft and Gold Partners such as Dot Net Solutions frequently talk about how a Software + Services approach enhances systems design and introduces new business capabilities. It’s right here in my little story. By sharing data about where I am and how fast I’m moving I enable TomTom to calculate more accurate, live traffic data. The services infrastructure enables them to aggregate this data and sell it back to me in a useful format. The Software on my device uses that data when available to optimize my route</p>
<p>I traded personal data and cash for anonymised data and a program that gave me a better experience. It’s clear that TomTom get a lot out of the arrangement as well – they’re not entirely a ‘device’ company they’re a data services company that gives them an edge when people are just evaluating the devices, and gives them a long term relationship with their customers with repeat income.</p>
<p>What data will your customers give you? Can we help you process that data live and make it available to them?</p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\john</dc:creator><pubDate>Mon, 02 Aug 2010 13:38:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Design/">Design</category></item></channel></rss>