<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" version="2.0">
  <channel>
    <title>Chris Tacke - OpenNETCF</title>
    <link>http://blog.opennetcf.com/ctacke/</link>
    <description>Bringing Managed Code to the Embedded World</description>
    <copyright>Chris Tacke</copyright>
    <lastBuildDate>Thu, 18 Oct 2012 16:47:16 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>ctacke@opennetcf.com</managingEditor>
    <webMaster>ctacke@opennetcf.com</webMaster>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=b18aad81-44ec-47d3-b2b4-0f2b01c22ed5</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,b18aad81-44ec-47d3-b2b4-0f2b01c22ed5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A new customer came to me late last week with an interesting problem.  They have
hundreds of Motorola/Symbol MC70 barcode scanners in the field and occasionally the
flash memory on the devices gets corrupted.  
</p>
        <p>
The current “solution” these guys are using involves removing the flash chips from
the board, reprogramming it in a separate device, re-balling the BGA pins, and re-soldering
it to the board. That explains why they desperately want an application that can do
it.
</p>
        <p>
They know the range where the corruption occurs and wanted an application that would
allow a user to read, update and rewrite the corrupted bytes in flash.  They
had talked with five separate developers before they found me, and all 5 had agreed
that it was impossible, so naturally I took that as a challenge.
</p>
        <p>
First, there are lots of things to know about how flash access works.  Most importantly,
it’s not like RAM.  You can’t just map to it, then go about your merry way doing
32-bit reads and writes.  You can read it that way, sure, but writing is a whole
new game.  Flash is broken up into “blocks” (which aren’t even always the same
size - in the case of the MC70, the first 4 blocks are 64k long, and the rest are
256k long.) and writes must be done following this general procedure:
</p>
        <ol>
          <li>
Read the *entire* block that contains the byte you want to change into RAM</li>
          <li>
Change to flash to Lock mode (a flash register write)</li>
          <li>
Unlock the block of flash (another register write)</li>
          <li>
Change the flash to erase mode (register write)</li>
          <li>
Erase the *entire* block of flash (which writes all FF’s to it)</li>
          <li>
Change the flash to write mode (register write)</li>
          <li>
Update the RAM buffer with your changes</li>
          <li>
Write in the *entire* block block to flash</li>
          <li>
Tell the flash to commit (register write)</li>
          <li>
Wait for the flash to finish (register read)</li>
          <li>
Put the flash back into read mode (register write)</li>
        </ol>
        <p>
Oh, and if you get any of this wrong, you’ve made yourself an expensive brick. 
The only solution at that point is the de-soldering and reprogramming route, and I
don’t have that kind of hardware in my office.
</p>
        <p>
So I started writing the app Monday morning, using C# since I had to create a UI for
the editor, and on Wednesday morning this is what I delivered:
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/Raw-Flash-Access-from-a-CF-app_99E3/FlashEdit.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="FlashEdit" border="0" alt="FlashEdit" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/Raw-Flash-Access-from-a-CF-app_99E3/FlashEdit_thumb.png" width="257" height="341" />
          </a>
        </p>
        <p>
So, in just 2 days I did what was “impossible”. I not only wrote all of the flash
access code, I also wrote a hex editor control and an app UI to make use of the flash
library.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=b18aad81-44ec-47d3-b2b4-0f2b01c22ed5" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Raw Flash Access from a CF app?</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,b18aad81-44ec-47d3-b2b4-0f2b01c22ed5.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/10/18/RawFlashAccessFromACFApp.aspx</link>
      <pubDate>Thu, 18 Oct 2012 16:47:16 GMT</pubDate>
      <description>&lt;p&gt;
A new customer came to me late last week with an interesting problem.&amp;#160; They have
hundreds of Motorola/Symbol MC70 barcode scanners in the field and occasionally the
flash memory on the devices gets corrupted.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
The current “solution” these guys are using involves removing the flash chips from
the board, reprogramming it in a separate device, re-balling the BGA pins, and re-soldering
it to the board. That explains why they desperately want an application that can do
it.
&lt;/p&gt;
&lt;p&gt;
They know the range where the corruption occurs and wanted an application that would
allow a user to read, update and rewrite the corrupted bytes in flash.&amp;#160; They
had talked with five separate developers before they found me, and all 5 had agreed
that it was impossible, so naturally I took that as a challenge.
&lt;/p&gt;
&lt;p&gt;
First, there are lots of things to know about how flash access works.&amp;#160; Most importantly,
it’s not like RAM.&amp;#160; You can’t just map to it, then go about your merry way doing
32-bit reads and writes.&amp;#160; You can read it that way, sure, but writing is a whole
new game.&amp;#160; Flash is broken up into “blocks” (which aren’t even always the same
size - in the case of the MC70, the first 4 blocks are 64k long, and the rest are
256k long.) and writes must be done following this general procedure:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Read the *entire* block that contains the byte you want to change into RAM&lt;/li&gt;
&lt;li&gt;
Change to flash to Lock mode (a flash register write)&lt;/li&gt;
&lt;li&gt;
Unlock the block of flash (another register write)&lt;/li&gt;
&lt;li&gt;
Change the flash to erase mode (register write)&lt;/li&gt;
&lt;li&gt;
Erase the *entire* block of flash (which writes all FF’s to it)&lt;/li&gt;
&lt;li&gt;
Change the flash to write mode (register write)&lt;/li&gt;
&lt;li&gt;
Update the RAM buffer with your changes&lt;/li&gt;
&lt;li&gt;
Write in the *entire* block block to flash&lt;/li&gt;
&lt;li&gt;
Tell the flash to commit (register write)&lt;/li&gt;
&lt;li&gt;
Wait for the flash to finish (register read)&lt;/li&gt;
&lt;li&gt;
Put the flash back into read mode (register write)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Oh, and if you get any of this wrong, you’ve made yourself an expensive brick.&amp;#160;
The only solution at that point is the de-soldering and reprogramming route, and I
don’t have that kind of hardware in my office.
&lt;/p&gt;
&lt;p&gt;
So I started writing the app Monday morning, using C# since I had to create a UI for
the editor, and on Wednesday morning this is what I delivered:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/Raw-Flash-Access-from-a-CF-app_99E3/FlashEdit.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="FlashEdit" border="0" alt="FlashEdit" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/Raw-Flash-Access-from-a-CF-app_99E3/FlashEdit_thumb.png" width="257" height="341" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
So, in just 2 days I did what was “impossible”. I not only wrote all of the flash
access code, I also wrote a hex editor control and an app UI to make use of the flash
library.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=b18aad81-44ec-47d3-b2b4-0f2b01c22ed5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=67312375-71e4-4712-95e8-57309b595c2c</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,67312375-71e4-4712-95e8-57309b595c2c.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A customer recently contacted me with a <a href="http://www.opennetcf.com/Products/Padarn.aspx" target="_blank">Padarn
Web Server</a> problem.  They wanted users to be able to download data files
from their device to a client browser, but they were running out of device memory
when the file got large (38MB in their case, but the size would be completely hardware
and environment dependent).
</p>
        <p>
What you have to understand is that Padarn caches your Page’s response in memory until
such time as you either tell it to Flush explicitly, or until the Page has full rendered
(in Padarn’s view) at which point it will call Flush for you.
</p>
        <p>
For a large file, it’s going to be bad to try to hold the entire thing in memory before
pushing it across the wire, so the strategy would be to read the local file in packets,
then send those packets across to the client using <font style="background-color: #cccccc">Response.BinaryWrite</font>.
</p>
        <p>
Now <font style="background-color: #cccccc">BinaryWrite</font> simply puts the data
into the memory cache, so you have to actually tell Padarn to send it across the wire
by calling Flush.  The issue there, though, is that on the first Flush, Padarn
has to assemble and send the payload header to the client, and part of that header
is the total length of the content.  If you haven’t explicitly set the content
length, Padarn has no idea how big it might be, so it defaults to the length what
it has in the buffer, and sends the header.  The browser then decodes that header
and expects a length of only that first packet.
</p>
        <p>
The solution is to set the <font style="background-color: #cccccc">Response.ContentLength</font> property <em>before</em> you
send any data.  Padarn will use your override value when it sends it to the client,
and all will be well.
</p>
        <p>
Here’s a quick example of a page that I used to send a 1.1GB media file from a page
request with no problem.  You might want to tune the packet size based on device
memory and speed, but 64k worked pretty well for my test.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">class</span> LargeFileDownload
: Page</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">protected</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> Render(HtmlTextWriter
writer)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> var
largeFilePath = <span style="color: #006080">@"D:\Media\Movies\short_circuit.mp4"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> var
packetSize = 0x10000; <span style="color: #008000">// 64k packets</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>
              <span style="color: #0000ff">using</span>(var
stream = <span style="color: #0000ff">new</span> FileStream(</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> largeFilePath, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> FileMode.Open, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> FileAccess.Read))</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> var
toSend = stream.Length;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> var
packet = <span style="color: #0000ff">new</span><span style="color: #0000ff">byte</span>[packetSize];</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span>
              <span style="color: #008000">//
set the response content length</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span> Response.ContentLength
= toSend;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span>
              <span style="color: #008000">//
set the content type as a binary stream</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> Response.ContentType
= <span style="color: #006080">"application/octet-stream"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span>
              <span style="color: #008000">//
set the filename so the browser doesn't try to render it</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span> Response.AppendHeader(<span style="color: #006080">"Content-Disposition"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span>
              <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"attachment;
filename={0}"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum24"> 24:</span> Path.GetFileName(largeFilePath)));</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum25"> 25:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum26"> 26:</span>
              <span style="color: #008000">//
send the content in packets</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum27"> 27:</span>
              <span style="color: #0000ff">while</span> (toSend
&gt; 0)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum28"> 28:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum29"> 29:</span> var
actual = stream.Read(packet, 0, packetSize);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum30"> 30:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum31"> 31:</span>
              <span style="color: #0000ff">if</span> (!Response.IsClientConnected)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum32"> 32:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum33"> 33:</span> Debug.WriteLine(</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum34"> 34:</span>
              <span style="color: #006080">"Client
disconnected. Aborting file send."</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum35"> 35:</span>
              <span style="color: #0000ff">return</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum36"> 36:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum37"> 37:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum38"> 38:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum39"> 39:</span> Debug.WriteLine(</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum40"> 40:</span>
              <span style="color: #0000ff">string</span>.Format(<span style="color: #006080">"Sending
{0} bytes. {1} to go."</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum41"> 41:</span> actual,
toSend));</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum42"> 42:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum43"> 43:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum44"> 44:</span>
              <span style="color: #0000ff">if</span> (actual
== packetSize)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum45"> 45:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum46"> 46:</span> Response.BinaryWrite(packet);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum47"> 47:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum48"> 48:</span>
              <span style="color: #0000ff">else</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum49"> 49:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum50"> 50:</span>
              <span style="color: #008000">//
partial packet, so crop</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum51"> 51:</span> var
last = <span style="color: #0000ff">new</span><span style="color: #0000ff">byte</span>[actual];</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum52"> 52:</span> Array.Copy(packet,
last, actual);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum53"> 53:</span> Response.BinaryWrite(packet);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum54"> 54:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum55"> 55:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum56"> 56:</span>
              <span style="color: #008000">//
send the packet acrtoss the wire</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum57"> 57:</span> Response.Flush();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum58"> 58:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum59"> 59:</span> toSend
-= actual;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum60"> 60:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum61"> 61:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum62"> 62:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum63"> 63:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=67312375-71e4-4712-95e8-57309b595c2c" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Sending large files to a client in Padarn</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,67312375-71e4-4712-95e8-57309b595c2c.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/10/04/SendingLargeFilesToAClientInPadarn.aspx</link>
      <pubDate>Thu, 04 Oct 2012 18:03:37 GMT</pubDate>
      <description>&lt;p&gt;
A customer recently contacted me with a &lt;a href="http://www.opennetcf.com/Products/Padarn.aspx" target="_blank"&gt;Padarn
Web Server&lt;/a&gt; problem.&amp;#160; They wanted users to be able to download data files
from their device to a client browser, but they were running out of device memory
when the file got large (38MB in their case, but the size would be completely hardware
and environment dependent).
&lt;/p&gt;
&lt;p&gt;
What you have to understand is that Padarn caches your Page’s response in memory until
such time as you either tell it to Flush explicitly, or until the Page has full rendered
(in Padarn’s view) at which point it will call Flush for you.
&lt;/p&gt;
&lt;p&gt;
For a large file, it’s going to be bad to try to hold the entire thing in memory before
pushing it across the wire, so the strategy would be to read the local file in packets,
then send those packets across to the client using &lt;font style="background-color: #cccccc"&gt;Response.BinaryWrite&lt;/font&gt;.
&lt;/p&gt;
&lt;p&gt;
Now &lt;font style="background-color: #cccccc"&gt;BinaryWrite&lt;/font&gt; simply puts the data
into the memory cache, so you have to actually tell Padarn to send it across the wire
by calling Flush.&amp;#160; The issue there, though, is that on the first Flush, Padarn
has to assemble and send the payload header to the client, and part of that header
is the total length of the content.&amp;#160; If you haven’t explicitly set the content
length, Padarn has no idea how big it might be, so it defaults to the length what
it has in the buffer, and sends the header.&amp;#160; The browser then decodes that header
and expects a length of only that first packet.
&lt;/p&gt;
&lt;p&gt;
The solution is to set the &lt;font style="background-color: #cccccc"&gt;Response.ContentLength&lt;/font&gt; property &lt;em&gt;before&lt;/em&gt; you
send any data.&amp;#160; Padarn will use your override value when it sends it to the client,
and all will be well.
&lt;/p&gt;
&lt;p&gt;
Here’s a quick example of a page that I used to send a 1.1GB media file from a page
request with no problem.&amp;#160; You might want to tune the packet size based on device
memory and speed, but 64k worked pretty well for my test.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; font-size: 8pt; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; LargeFileDownload
: Page&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Render(HtmlTextWriter
writer)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; var
largeFilePath = &lt;span style="color: #006080"&gt;@&amp;quot;D:\Media\Movies\short_circuit.mp4&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; var
packetSize = 0x10000; &lt;span style="color: #008000"&gt;// 64k packets&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt;(var
stream = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileStream(&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; largeFilePath, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; FileMode.Open, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; FileAccess.Read))&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; var
toSend = stream.Length;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; var
packet = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[packetSize];&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
set the response content length&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; Response.ContentLength
= toSend;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
set the content type as a binary stream&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; Response.ContentType
= &lt;span style="color: #006080"&gt;&amp;quot;application/octet-stream&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
set the filename so the browser doesn't try to render it&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; Response.AppendHeader(&lt;span style="color: #006080"&gt;&amp;quot;Content-Disposition&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;&amp;quot;attachment;
filename={0}&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt; 24:&lt;/span&gt; Path.GetFileName(largeFilePath)));&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt; 25:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt; 26:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
send the content in packets&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt; 27:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;while&lt;/span&gt; (toSend
&amp;gt; 0)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt; 28:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt; 29:&lt;/span&gt; var
actual = stream.Read(packet, 0, packetSize);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt; 30:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt; 31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!Response.IsClientConnected)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt; 32:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt; 33:&lt;/span&gt; Debug.WriteLine(&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt; 34:&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;Client
disconnected. Aborting file send.&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt; 35:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt; 36:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt; 37:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt; 38:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt; 39:&lt;/span&gt; Debug.WriteLine(&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt; 40:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;&amp;quot;Sending
{0} bytes. {1} to go.&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt; 41:&lt;/span&gt; actual,
toSend));&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt; 42:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt; 43:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt; 44:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (actual
== packetSize)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt; 45:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum46"&gt; 46:&lt;/span&gt; Response.BinaryWrite(packet);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum47"&gt; 47:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum48"&gt; 48:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum49"&gt; 49:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum50"&gt; 50:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
partial packet, so crop&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum51"&gt; 51:&lt;/span&gt; var
last = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[actual];&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum52"&gt; 52:&lt;/span&gt; Array.Copy(packet,
last, actual);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum53"&gt; 53:&lt;/span&gt; Response.BinaryWrite(packet);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum54"&gt; 54:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum55"&gt; 55:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum56"&gt; 56:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
send the packet acrtoss the wire&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum57"&gt; 57:&lt;/span&gt; Response.Flush();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum58"&gt; 58:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum59"&gt; 59:&lt;/span&gt; toSend
-= actual;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum60"&gt; 60:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum61"&gt; 61:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum62"&gt; 62:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum63"&gt; 63:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=67312375-71e4-4712-95e8-57309b595c2c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Padarn</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There’s no doubt in my mind that code libraries and frameworks are fantastic for saving
time and work, after all I want to spend time solving my business problem, not writing
infrastructure.  Nowhere is this more true than it is with <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank">Object-Relational
Mapping</a>, or ORM, libraries.  
</p>
        <p>
Broadly speaking, if you’re still writing application code that requires that you
also write SQL, you’re wasting your time.  Wasting time thinking about SQL syntax. 
Wasting time writing it.  Wasting time testing, debugging and maintaining it.
</p>
        <p>
I believe this so much, but was so dissatisfied with any existing ORM offering, that <a href="http://orm.codeplex.com/" target="_blank">I
wrote my own ORM</a>. It wasn’t a trivial task, but I have something that does exactly
what I need, on the platforms I need, and does it at a speed that I consider more
than acceptable.  Occasionally I hit a data storage requirement that ORMs, even
my own, aren’t so good at.  
</p>
        <p>
ORM usage is usually viewed as one of two approaches: code first or data first. 
With the code-first approach, a developer defines the storage entity classes and the
ORM generates a backing database from them.  With data first, the developer feeds
a database into the ORM or an ORM tool, and it then generates the entity classes for
you.  
</p>
        <p>
But this doesn’t cover all scenarios – which is something no ORM that I’m aware of
seems to acknowledge.  Consider the following use-case (and this is a real-world
use case that I had to design for, not some mental exercise).
</p>
        <p>
I have an application that allows users to define storage for data at run time in
a completely ad-hoc manner.  They get to choose what data items they want to
save, but even those data items are dynamically available so they are available only
at run time.
</p>
        <p>
So we need to store effectively a flat table of data with an unknown set of columns. 
The column names and data types are unknown until after the application is running
on the user’s machine.
</p>
        <p>
So the entities are neither data first nor code first.  I’ve not thought of a
catchy term for these types of scenarios, so for now I’ll just call it “user first”
since the user has the idea of what they want to store and we have to accommodate
that.  This is why I created support in the OpenNETCF ORM for the DynamicEntity.
</p>
        <p>
Let’s assume that the user decides they wanted to store a FirstName and LastName for
a person.  For convenience, we also want to to store a generated ID for the Person
entities that get stored.
</p>
        <p>
At run time, we generate some FieldAttributes that define the Person:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
fieldList = <span style="color: #0000ff">new</span> List&lt;FieldAttribute&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> FieldName
= <span style="color: #006080">"ID"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> IsPrimaryKey
= <span style="color: #0000ff">true</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> DataType
= System.Data.DbType.Int32</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> });</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> FieldName
= <span style="color: #006080">"FirstName"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> DataType
= System.Data.DbType.String</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> });</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> fieldList.Add(<span style="color: #0000ff">new</span> FieldAttribute()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> FieldName
= <span style="color: #006080">"LastName"</span>,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span> DataType
= System.Data.DbType.String,</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span> AllowsNulls
= <span style="color: #0000ff">false</span></pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> });</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And then we create and register a DynamicEntityDefinition with the DataStore:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
definition = <span style="color: #0000ff">new</span> DynamicEntityDefinition(</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #006080">"Person"</span>, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> fieldList, </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> KeyScheme.Identity);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> store.RegisterDynamicEntity(definition);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Now, any time we want to store an entity instance, we simply create a DynamicEntity
and pass that to the Insert method, just like any other Entity instance, and the ORM
handles storage for us.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
entity = <span style="color: #0000ff">new</span> DynamicEntity(<span style="color: #006080">"Person"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> entity.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"John"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> entity.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Doe"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> store.Insert(entity);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> entity
= <span style="color: #0000ff">new</span> DynamicEntity(<span style="color: #006080">"Person"</span>);</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> entity.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"Jim"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> entity.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Smith"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> store.Insert(entity);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
The rest of the CRUD operations are similar, we simply have to name the definition
type where appropriate.  FOr example, retrieving looks like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
people = store.Select(<span style="color: #006080">"Person"</span>)</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Updating like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
person = people.First();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> person.Fields[<span style="color: #006080">"FirstName"</span>]
= <span style="color: #006080">"Joe"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> person.Fields[<span style="color: #006080">"LastName"</span>]
= <span style="color: #006080">"Satriani"</span>;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> store.Update(person);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And Deleting like this
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> store.Delete(<span style="color: #006080">"Person"</span>,
people.First().Fields[<span style="color: #006080">"ID"</span>]);</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
We’re no longer bound by the either-or box of traditional ORM thinking, and it leads
to offering users some really interesting and powerful capabilities that before were
relegated to only those who wanted to abandon an ORM and hand-roll the logic.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF ORM: Dynamic Entities</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/10/01/OpenNETCFORMDynamicEntities.aspx</link>
      <pubDate>Mon, 01 Oct 2012 21:36:12 GMT</pubDate>
      <description>&lt;p&gt;
There’s no doubt in my mind that code libraries and frameworks are fantastic for saving
time and work, after all I want to spend time solving my business problem, not writing
infrastructure.&amp;#160; Nowhere is this more true than it is with &lt;a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank"&gt;Object-Relational
Mapping&lt;/a&gt;, or ORM, libraries.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Broadly speaking, if you’re still writing application code that requires that you
also write SQL, you’re wasting your time.&amp;#160; Wasting time thinking about SQL syntax.&amp;#160;
Wasting time writing it.&amp;#160; Wasting time testing, debugging and maintaining it.
&lt;/p&gt;
&lt;p&gt;
I believe this so much, but was so dissatisfied with any existing ORM offering, that &lt;a href="http://orm.codeplex.com/" target="_blank"&gt;I
wrote my own ORM&lt;/a&gt;. It wasn’t a trivial task, but I have something that does exactly
what I need, on the platforms I need, and does it at a speed that I consider more
than acceptable.&amp;#160; Occasionally I hit a data storage requirement that ORMs, even
my own, aren’t so good at.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
ORM usage is usually viewed as one of two approaches: code first or data first.&amp;#160;
With the code-first approach, a developer defines the storage entity classes and the
ORM generates a backing database from them.&amp;#160; With data first, the developer feeds
a database into the ORM or an ORM tool, and it then generates the entity classes for
you.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
But this doesn’t cover all scenarios – which is something no ORM that I’m aware of
seems to acknowledge.&amp;#160; Consider the following use-case (and this is a real-world
use case that I had to design for, not some mental exercise).
&lt;/p&gt;
&lt;p&gt;
I have an application that allows users to define storage for data at run time in
a completely ad-hoc manner.&amp;#160; They get to choose what data items they want to
save, but even those data items are dynamically available so they are available only
at run time.
&lt;/p&gt;
&lt;p&gt;
So we need to store effectively a flat table of data with an unknown set of columns.&amp;#160;
The column names and data types are unknown until after the application is running
on the user’s machine.
&lt;/p&gt;
&lt;p&gt;
So the entities are neither data first nor code first.&amp;#160; I’ve not thought of a
catchy term for these types of scenarios, so for now I’ll just call it “user first”
since the user has the idea of what they want to store and we have to accommodate
that.&amp;#160; This is why I created support in the OpenNETCF ORM for the DynamicEntity.
&lt;/p&gt;
&lt;p&gt;
Let’s assume that the user decides they wanted to store a FirstName and LastName for
a person.&amp;#160; For convenience, we also want to to store a generated ID for the Person
entities that get stored.
&lt;/p&gt;
&lt;p&gt;
At run time, we generate some FieldAttributes that define the Person:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
fieldList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;FieldAttribute&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; IsPrimaryKey
= &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; DataType
= System.Data.DbType.Int32&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; DataType
= System.Data.DbType.String&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; fieldList.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FieldAttribute()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; FieldName
= &lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; DataType
= System.Data.DbType.String,&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; AllowsNulls
= &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; });&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And then we create and register a DynamicEntityDefinition with the DataStore:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
definition = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntityDefinition(&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; fieldList, &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; KeyScheme.Identity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; store.RegisterDynamicEntity(definition);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now, any time we want to store an entity instance, we simply create a DynamicEntity
and pass that to the Insert method, just like any other Entity instance, and the ORM
handles storage for us.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
entity = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntity(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;John&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Doe&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; store.Insert(entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; entity
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DynamicEntity(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Jim&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; entity.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Smith&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; store.Insert(entity);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
The rest of the CRUD operations are similar, we simply have to name the definition
type where appropriate.&amp;#160; FOr example, retrieving looks like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
people = store.Select(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Updating like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
person = people.First();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; person.Fields[&lt;span style="color: #006080"&gt;&amp;quot;FirstName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Joe&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; person.Fields[&lt;span style="color: #006080"&gt;&amp;quot;LastName&amp;quot;&lt;/span&gt;]
= &lt;span style="color: #006080"&gt;&amp;quot;Satriani&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; store.Update(person);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And Deleting like this
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; store.Delete(&lt;span style="color: #006080"&gt;&amp;quot;Person&amp;quot;&lt;/span&gt;,
people.First().Fields[&lt;span style="color: #006080"&gt;&amp;quot;ID&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
We’re no longer bound by the either-or box of traditional ORM thinking, and it leads
to offering users some really interesting and powerful capabilities that before were
relegated to only those who wanted to abandon an ORM and hand-roll the logic.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=56ea4c4d-1eb9-4b1b-9e3d-cc46fdb8286c" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=ad8038f9-cce5-47b6-b2ee-c7d7ab625edd</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,ad8038f9-cce5-47b6-b2ee-c7d7ab625edd.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
You don’t have to be a developer to create useful, customized applications for maintenance
workers.  See what’s happening on the vehicle in real time, see it how you want
and get it done in seconds.  Take a look at the new Transit and <a href="http://solution-family.com/Industries/TransitandTelematics.aspx" target="_blank">Telematics
hands-on lab for Solution Family</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ad8038f9-cce5-47b6-b2ee-c7d7ab625edd" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Drag and Drop Transit and Telematics Maintenance apps</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,ad8038f9-cce5-47b6-b2ee-c7d7ab625edd.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/09/26/DragAndDropTransitAndTelematicsMaintenanceApps.aspx</link>
      <pubDate>Wed, 26 Sep 2012 00:09:57 GMT</pubDate>
      <description>&lt;p&gt;
You don’t have to be a developer to create useful, customized applications for maintenance
workers.&amp;#160; See what’s happening on the vehicle in real time, see it how you want
and get it done in seconds.&amp;#160; Take a look at the new Transit and &lt;a href="http://solution-family.com/Industries/TransitandTelematics.aspx" target="_blank"&gt;Telematics
hands-on lab for Solution Family&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ad8038f9-cce5-47b6-b2ee-c7d7ab625edd" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Solution Family</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=dc421899-a284-4e51-9d9e-e5ca98354a36</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,dc421899-a284-4e51-9d9e-e5ca98354a36.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve recently started refactoring a customer’s code base for a working application. 
They recognize the need to make their code more extensible and maintainable so I’m
helping to massage the existing code into something that they will be able to continue
shipping and upgrading for years to come without ending up backed into a corner.
</p>
        <p>
One of my first suggestions was to start eliminating the abundance of static variables
in the code base.  In this case, static classes and methods abound, and it looks
like it was used as a quick-and-dirty mechanism to provide singleton behavior. 
Now I’m not going to go into depth on why an actual singleton might have been better,
or the pitfalls of all of these statics.  Write-ups on that kind of thing about
in books and on line.
</p>
        <p>
Instead, let’s look at what it means to migrate from a static, an instance or a singleton
over to using a DI container, <a href="http://ioc.codeplex.com/" target="_blank">specifically
OpenNETCF’s IoC framework</a>.
</p>
        <p>
First, let’s look at a “service” class that exposes a single integer and how we might
consume it.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">class</span> MyStaticService</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span>
              <span style="color: #0000ff">int</span> MyValue
= 1;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And how we’d get a value from it:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
staticValue = MyStaticService.MyValue;</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Simple enough.  Some of the down sides here are:
</p>
        <ul>
          <li>
There’s no way to protect the Field value from unwanted changes</li>
          <li>
To use the value, I have to have a reference to the assembly containing the class</li>
          <li>
It’s really hard to mock and cannot be moved into an interface</li>
        </ul>
        <p>
Now let’s move that from a static to an instance Field in a constructed class:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">class</span> MyInstanceService</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">public</span> MyInstanceService()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> MyValue
= 1;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">int</span> MyValue
{ get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Now we have to create the class instance and later retrieve the value.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
service = <span style="color: #0000ff">new</span> MyInstanceService();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #008000">//
and at a later point....</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> var
instanceValue = service.MyValue;</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
We’ve got some benefit from doing this.  We can now control access to the underlying
value, making the setter protected or private, and we’re able to do bounds checking,
etc.  All good things.  Still, there are downsides:
</p>
        <ul>
          <li>
I have to keep track of the instance I created, passing it between consumers or maintaining
a reachable reference</li>
          <li>
I have no protection from multiple copies being created</li>
          <li>
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)</li>
        </ul>
        <p>
Well let’s see what a Singleton pattern buys us:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">class</span> MySingletonService</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">private</span>
              <span style="color: #0000ff">static</span> MySingletonService
m_instance;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #0000ff">private</span> MySingletonService()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> MyValue
= 1;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">static</span> MySingletonService
Instance</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span> get</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span>
              <span style="color: #0000ff">if</span> (m_instance
== <span style="color: #0000ff">null</span>)</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum15"> 15:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum16"> 16:</span> m_instance
= <span style="color: #0000ff">new</span> MySingletonService();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum17"> 17:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum18"> 18:</span>
              <span style="color: #0000ff">return</span> m_instance;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum19"> 19:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum20"> 20:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum21"> 21:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum22"> 22:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">int</span> MyValue
{ get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum23"> 23:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
And now the consumer code:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span> var
singleTonValue = MySingletonService.Instance.MyValue;</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
That looks nice from a consumer perspective.  Very clean.  I’m not overly
thrilled about having the Instance accessor property, but it’s not all that painful. 
Still, there are drawbacks:
</p>
        <ul>
          <li>
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)</li>
          <li>
If I want to mock this or swap implementations, I’ll got to go all over my code base
replacing the calls to the new instance (or implement a factory).</li>
        </ul>
        <p>
How would all of this look with a DI container?
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">interface</span> IService</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">int</span> MyValue
{ get; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span>
              <span style="color: #0000ff">class</span> MyDIService
: IService</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum8"> 8:</span>
              <span style="color: #0000ff">public</span> MyDIService()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum9"> 9:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum10"> 10:</span> MyValue
= 1;</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum11"> 11:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum12"> 12:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum13"> 13:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">int</span> MyValue
{ get; set; }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum14"> 14:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Note that the class is interface-based and we register the instance with the DI container
by *interface* type.  This allows us to pull it back out of the container later
by that interface type.  The consumer doesn’t need to know anything about the
actual implementation.
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #008000">//
Note that the Services collection holds (conceptually) singletons. Only one instance
per registered type is allowed.</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span>
              <span style="color: #008000">//
If you need multiple instances, use the Items collection, which requires a unique
identifier string key for each instance</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span> RootWorkItem.Services.AddNew&lt;MyDIService,
IService&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span>  </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span>
              <span style="color: #008000">//
and at a later point....</span>
            </pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> var
diValue = RootWorkItem.Services.Get&lt;IService&gt;().MyValue;</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Mocks, implementation changes based on environment (like different hardware) and testing
become very easy.  Plug-in and run-time feature additions based on configuration
or license level also are simplified.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=dc421899-a284-4e51-9d9e-e5ca98354a36" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>On Software Development: Moving from statics or instances to a DI container</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,dc421899-a284-4e51-9d9e-e5ca98354a36.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/09/17/OnSoftwareDevelopmentMovingFromStaticsOrInstancesToADIContainer.aspx</link>
      <pubDate>Mon, 17 Sep 2012 18:07:54 GMT</pubDate>
      <description>&lt;p&gt;
I’ve recently started refactoring a customer’s code base for a working application.&amp;#160;
They recognize the need to make their code more extensible and maintainable so I’m
helping to massage the existing code into something that they will be able to continue
shipping and upgrading for years to come without ending up backed into a corner.
&lt;/p&gt;
&lt;p&gt;
One of my first suggestions was to start eliminating the abundance of static variables
in the code base.&amp;#160; In this case, static classes and methods abound, and it looks
like it was used as a quick-and-dirty mechanism to provide singleton behavior.&amp;#160;
Now I’m not going to go into depth on why an actual singleton might have been better,
or the pitfalls of all of these statics.&amp;#160; Write-ups on that kind of thing about
in books and on line.
&lt;/p&gt;
&lt;p&gt;
Instead, let’s look at what it means to migrate from a static, an instance or a singleton
over to using a DI container, &lt;a href="http://ioc.codeplex.com/" target="_blank"&gt;specifically
OpenNETCF’s IoC framework&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
First, let’s look at a “service” class that exposes a single integer and how we might
consume it.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyStaticService&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyValue
= 1;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And how we’d get a value from it:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
staticValue = MyStaticService.MyValue;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Simple enough.&amp;#160; Some of the down sides here are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
There’s no way to protect the Field value from unwanted changes&lt;/li&gt;
&lt;li&gt;
To use the value, I have to have a reference to the assembly containing the class&lt;/li&gt;
&lt;li&gt;
It’s really hard to mock and cannot be moved into an interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Now let’s move that from a static to an instance Field in a constructed class:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyInstanceService&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyInstanceService()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; MyValue
= 1;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyValue
{ get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Now we have to create the class instance and later retrieve the value.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
service = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyInstanceService();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
and at a later point....&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; var
instanceValue = service.MyValue;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
We’ve got some benefit from doing this.&amp;#160; We can now control access to the underlying
value, making the setter protected or private, and we’re able to do bounds checking,
etc.&amp;#160; All good things.&amp;#160; Still, there are downsides:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I have to keep track of the instance I created, passing it between consumers or maintaining
a reachable reference&lt;/li&gt;
&lt;li&gt;
I have no protection from multiple copies being created&lt;/li&gt;
&lt;li&gt;
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Well let’s see what a Singleton pattern buys us:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MySingletonService&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; MySingletonService
m_instance;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; MySingletonService()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; MyValue
= 1;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; MySingletonService
Instance&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt; get&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (m_instance
== &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt; 15:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt; 16:&lt;/span&gt; m_instance
= &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MySingletonService();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt; 17:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt; 18:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_instance;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt; 19:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt; 20:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt; 21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt; 22:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyValue
{ get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt; 23:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
And now the consumer code:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; var
singleTonValue = MySingletonService.Instance.MyValue;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
That looks nice from a consumer perspective.&amp;#160; Very clean.&amp;#160; I’m not overly
thrilled about having the Instance accessor property, but it’s not all that painful.&amp;#160;
Still, there are drawbacks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The consumer must have a reference to the assembly containing the class (making run-time
plug-ins very hard)&lt;/li&gt;
&lt;li&gt;
If I want to mock this or swap implementations, I’ll got to go all over my code base
replacing the calls to the new instance (or implement a factory).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
How would all of this look with a DI container?
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IService&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyValue
{ get; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyDIService
: IService&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt; 8:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MyDIService()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt; 9:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt; 10:&lt;/span&gt; MyValue
= 1;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt; 11:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt; 12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt; 13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; MyValue
{ get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt; 14:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Note that the class is interface-based and we register the instance with the DI container
by *interface* type.&amp;#160; This allows us to pull it back out of the container later
by that interface type.&amp;#160; The consumer doesn’t need to know anything about the
actual implementation.
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
Note that the Services collection holds (conceptually) singletons. Only one instance
per registered type is allowed.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
If you need multiple instances, use the Items collection, which requires a unique
identifier string key for each instance&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; RootWorkItem.Services.AddNew&amp;lt;MyDIService,
IService&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; &lt;span style="color: #008000"&gt;//
and at a later point....&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; var
diValue = RootWorkItem.Services.Get&amp;lt;IService&amp;gt;().MyValue;&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Mocks, implementation changes based on environment (like different hardware) and testing
become very easy.&amp;#160; Plug-in and run-time feature additions based on configuration
or license level also are simplified.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=dc421899-a284-4e51-9d9e-e5ca98354a36" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>Desktop Development</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=e9175221-1090-42c5-9b58-4fc0d0a46c62</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,e9175221-1090-42c5-9b58-4fc0d0a46c62.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Yes, VS 2012 <strong>will</strong> support CE development, including Compact Framework
3.9.  Support is scheduled to be released in Q1 of next year.  <a href="http://visualstudiolaunchstaging.social27.com/vs2012vle/Theater?sid=1776" target="_blank">See
this video for more details</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e9175221-1090-42c5-9b58-4fc0d0a46c62" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Windows CE, Compact Framework and Studio 2012</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,e9175221-1090-42c5-9b58-4fc0d0a46c62.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/09/12/WindowsCECompactFrameworkAndStudio2012.aspx</link>
      <pubDate>Wed, 12 Sep 2012 23:23:08 GMT</pubDate>
      <description>&lt;p&gt;
Yes, VS 2012 &lt;strong&gt;will&lt;/strong&gt; support CE development, including Compact Framework
3.9.&amp;#160; Support is scheduled to be released in Q1 of next year.&amp;#160; &lt;a href="http://visualstudiolaunchstaging.social27.com/vs2012vle/Theater?sid=1776" target="_blank"&gt;See
this video for more details&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e9175221-1090-42c5-9b58-4fc0d0a46c62" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>CE Device Development</category>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=eae63c52-1fd4-4c04-95d3-ff43c80cf25d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,eae63c52-1fd4-4c04-95d3-ff43c80cf25d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m (finally) trying to publish some better, more formal documentation for <a href="http://orm.codeplex.com" target="_blank">the
ORM</a>.  I just posted a simple example of how you can create a one-to-many
relationship between Entities and how you can get the ORM to fill in the references
when you do a Select call.  <a href="http://orm.codeplex.com/wikipage?title=Retrieving%20Data%20%28READ%29" target="_blank">Take
a look at the ORM documentation for more details</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=eae63c52-1fd4-4c04-95d3-ff43c80cf25d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM: Inserting References</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,eae63c52-1fd4-4c04-95d3-ff43c80cf25d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/09/07/ORMInsertingReferences.aspx</link>
      <pubDate>Fri, 07 Sep 2012 22:11:48 GMT</pubDate>
      <description>&lt;p&gt;
I’m (finally) trying to publish some better, more formal documentation for &lt;a href="http://orm.codeplex.com" target="_blank"&gt;the
ORM&lt;/a&gt;.&amp;#160; I just posted a simple example of how you can create a one-to-many
relationship between Entities and how you can get the ORM to fill in the references
when you do a Select call.&amp;#160; &lt;a href="http://orm.codeplex.com/wikipage?title=Retrieving%20Data%20%28READ%29" target="_blank"&gt;Take
a look at the ORM documentation for more details&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=eae63c52-1fd4-4c04-95d3-ff43c80cf25d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=1f4dce28-41f3-4109-9b55-6a8b930f5faa</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,1f4dce28-41f3-4109-9b55-6a8b930f5faa.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve just checked in new code changes and rolled a full release for <a href="http://orm.codeplex.com/" target="_blank">the
OpenNETCF ORM</a>.  The latest code changes add transaction support.  This
new release adds a load of features since the last (the last was way back in February),
most notably full support for <a href="http://sqlite.org/" target="_blank">SQLite</a> on
all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono
for Android.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1f4dce28-41f3-4109-9b55-6a8b930f5faa" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM: Transactions are now supported</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,1f4dce28-41f3-4109-9b55-6a8b930f5faa.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/29/ORMTransactionsAreNowSupported.aspx</link>
      <pubDate>Wed, 29 Aug 2012 17:12:37 GMT</pubDate>
      <description>&lt;p&gt;
I’ve just checked in new code changes and rolled a full release for &lt;a href="http://orm.codeplex.com/" target="_blank"&gt;the
OpenNETCF ORM&lt;/a&gt;.&amp;#160; The latest code changes add transaction support.&amp;#160; This
new release adds a load of features since the last (the last was way back in February),
most notably full support for &lt;a href="http://sqlite.org/" target="_blank"&gt;SQLite&lt;/a&gt; on
all of the following platforms: Windows Desktop, Windows CE, Windows Phone and Mono
for Android.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1f4dce28-41f3-4109-9b55-6a8b930f5faa" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>Desktop Development</category>
      <category>MonoDroid</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=d748ee77-80a4-42c7-9f48-967d32d31ec7</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,d748ee77-80a4-42c7-9f48-967d32d31ec7.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you needed another excuse to try out <a href="http://ioc.codeplex.com" target="_blank">IoC</a>,
here it is.  It’s now even easier to create intuitive UIs. I just checked in
a new feature to <a href="http://ioc.codeplex.com" target="_blank">the OpenNETCF.IoC.UI
assembly</a>.  Workspaces now have basic gesture support, so you get an even
on a swipe in the four primary directions (up/down/left/right).  
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d748ee77-80a4-42c7-9f48-967d32d31ec7" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF IoC: Gesture Support</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,d748ee77-80a4-42c7-9f48-967d32d31ec7.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/21/OpenNETCFIoCGestureSupport.aspx</link>
      <pubDate>Tue, 21 Aug 2012 19:44:08 GMT</pubDate>
      <description>&lt;p&gt;
If you needed another excuse to try out &lt;a href="http://ioc.codeplex.com" target="_blank"&gt;IoC&lt;/a&gt;,
here it is.&amp;#160; It’s now even easier to create intuitive UIs. I just checked in
a new feature to &lt;a href="http://ioc.codeplex.com" target="_blank"&gt;the OpenNETCF.IoC.UI
assembly&lt;/a&gt;.&amp;#160; Workspaces now have basic gesture support, so you get an even
on a swipe in the four primary directions (up/down/left/right).&amp;#160; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d748ee77-80a4-42c7-9f48-967d32d31ec7" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=83bf3273-b9e0-4ca0-9f13-168e8832ba25</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,83bf3273-b9e0-4ca0-9f13-168e8832ba25.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://orm.codeplex.com/" target="_blank">The OpenNETCF ORM</a> has supported
SQLite for a while now – ever since I needed an ORM for Android – but somehow I’d
overlooked addeing SQLite support for the Compact Framework.  That oversight
has been addressed and support is now in <a href="http://orm.codeplex.com/SourceControl/list/changesets" target="_blank">the
latest change set</a> (99274).  I’ve not yet rolled it into the Release as it
doesn’t support Dynamic Entities yet, but that’s on the way.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=83bf3273-b9e0-4ca0-9f13-168e8832ba25" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: SQLite for Compact Framework now supported</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,83bf3273-b9e0-4ca0-9f13-168e8832ba25.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/20/ORMUpdateSQLiteForCompactFrameworkNowSupported.aspx</link>
      <pubDate>Mon, 20 Aug 2012 17:07:50 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://orm.codeplex.com/" target="_blank"&gt;The OpenNETCF ORM&lt;/a&gt; has supported
SQLite for a while now – ever since I needed an ORM for Android – but somehow I’d
overlooked addeing SQLite support for the Compact Framework.&amp;#160; That oversight
has been addressed and support is now in &lt;a href="http://orm.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;the
latest change set&lt;/a&gt; (99274).&amp;#160; I’ve not yet rolled it into the Release as it
doesn’t support Dynamic Entities yet, but that’s on the way.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=83bf3273-b9e0-4ca0-9f13-168e8832ba25" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=e4195f6c-3ac3-4df3-9dba-6dc25958dc60</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,e4195f6c-3ac3-4df3-9dba-6dc25958dc60.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One limitation with using the SmartClientApplication as a basic for your IoC application
is that it locks you in to the type of Form that’s going to be displayed when your
app starts up.  In most cases that’s really not an issue, but sometimes you’d
like to decide at runtime what UI to display.  You might even want that UI to
come from a dynamically loaded DLL.
</p>
        <p>
Well I just added a new capability to the SmartClientApplication.  During the
startup process, the framework now looks in the Services collection to see if you’ve
already registered a Form deriving from the new ShellReplacement base class. 
If it finds one, that form will be shown instead of the type passed into the SmartClientApplication. 
The effectively gives you a “default” main shell form, with the ability to dynamically
load a different one based on whatever criteria you want.  We’re using it to
support vertical-specific UIs for the Solution Engine, meaning that if you have the
HVAC module installed you’ll get one UI but if you have the Telematics module installed
you’ll get another.
</p>
        <p>
The implementation details are as trivial as I could think of making them.  First,
create your new shell Form like this:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">partial</span>
              <span style="color: #0000ff">class</span> HVACMainView
: ShellReplacement</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">public</span> HVACMainView()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> InitializeComponent();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
Then register it as the replacement when your Module loads:
</p>
        <div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
          <div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum1"> 1:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">class</span> Module
: ModuleInit</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum2"> 2:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum3"> 3:</span>
              <span style="color: #0000ff">public</span>
              <span style="color: #0000ff">override</span>
              <span style="color: #0000ff">void</span> AddServices()</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum4"> 4:</span> {</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum5"> 5:</span> RootWorkItem.Services.AddNew&lt;HVACMainView,
ShellReplacement&gt;();</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum6"> 6:</span> }</pre>
            <!--CRLF-->
            <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">
              <span style="color: #606060" id="lnum7"> 7:</span> }</pre>
            <!--CRLF-->
          </div>
        </div>
        <p>
That’s all there is to it.  You can disable the feature by using the EnableShellReplacement
property (defaults to true) of the SmartClientApplication.  <a href="http://ioc.codeplex.com/SourceControl/list/changesets" target="_blank">Get
the latest change set (69942 or later) to try out the new feature</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e4195f6c-3ac3-4df3-9dba-6dc25958dc60" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>New IoC Feature: Shell Replacement</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,e4195f6c-3ac3-4df3-9dba-6dc25958dc60.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/14/NewIoCFeatureShellReplacement.aspx</link>
      <pubDate>Tue, 14 Aug 2012 20:05:29 GMT</pubDate>
      <description>&lt;p&gt;
One limitation with using the SmartClientApplication as a basic for your IoC application
is that it locks you in to the type of Form that’s going to be displayed when your
app starts up.&amp;#160; In most cases that’s really not an issue, but sometimes you’d
like to decide at runtime what UI to display.&amp;#160; You might even want that UI to
come from a dynamically loaded DLL.
&lt;/p&gt;
&lt;p&gt;
Well I just added a new capability to the SmartClientApplication.&amp;#160; During the
startup process, the framework now looks in the Services collection to see if you’ve
already registered a Form deriving from the new ShellReplacement base class.&amp;#160;
If it finds one, that form will be shown instead of the type passed into the SmartClientApplication.&amp;#160;
The effectively gives you a “default” main shell form, with the ability to dynamically
load a different one based on whatever criteria you want.&amp;#160; We’re using it to
support vertical-specific UIs for the Solution Engine, meaning that if you have the
HVAC module installed you’ll get one UI but if you have the Telematics module installed
you’ll get another.
&lt;/p&gt;
&lt;p&gt;
The implementation details are as trivial as I could think of making them.&amp;#160; First,
create your new shell Form like this:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HVACMainView
: ShellReplacement&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; HVACMainView()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; InitializeComponent();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
Then register it as the replacement when your Module loads:
&lt;/p&gt;
&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
&lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt; 1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Module
: ModuleInit&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt; 2:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt; 3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddServices()&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt; 4:&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt; 5:&lt;/span&gt; RootWorkItem.Services.AddNew&amp;lt;HVACMainView,
ShellReplacement&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt; 6:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt; 7:&lt;/span&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
That’s all there is to it.&amp;#160; You can disable the feature by using the EnableShellReplacement
property (defaults to true) of the SmartClientApplication.&amp;#160; &lt;a href="http://ioc.codeplex.com/SourceControl/list/changesets" target="_blank"&gt;Get
the latest change set (69942 or later) to try out the new feature&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e4195f6c-3ac3-4df3-9dba-6dc25958dc60" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=89513e80-677a-40db-a0bf-2a10b95224c2</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,89513e80-677a-40db-a0bf-2a10b95224c2.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’ve released version 1.0.12221 of the <a href="http://ioc.codeplex.com" target="_blank">OpenNETCF
IoC framework</a>.  Not a whole lot new going on – it was primarily bug fixes
– but binaries for all supported Platforms (Full framework, Compact Framework, Windows
Phone and Mono for Android) are included.  If you’re using it, how about showing
me some love and rating it (other than “Have not used it yet” – what kind of review
is that?).
</p>
        <p>
          <a title="http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor" href="http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor">http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor</a>
        </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=89513e80-677a-40db-a0bf-2a10b95224c2" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF IoC Update</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,89513e80-677a-40db-a0bf-2a10b95224c2.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/08/08/OpenNETCFIoCUpdate.aspx</link>
      <pubDate>Wed, 08 Aug 2012 15:38:34 GMT</pubDate>
      <description>&lt;p&gt;
I’ve released version 1.0.12221 of the &lt;a href="http://ioc.codeplex.com" target="_blank"&gt;OpenNETCF
IoC framework&lt;/a&gt;.&amp;#160; Not a whole lot new going on – it was primarily bug fixes
– but binaries for all supported Platforms (Full framework, Compact Framework, Windows
Phone and Mono for Android) are included.&amp;#160; If you’re using it, how about showing
me some love and rating it (other than “Have not used it yet” – what kind of review
is that?).
&lt;/p&gt;
&lt;p&gt;
&lt;a title="http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor" href="http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor"&gt;http://ioc.codeplex.com/releases/view/82674#ReviewsAnchor&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=89513e80-677a-40db-a0bf-2a10b95224c2" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>MonoDroid</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=0374759a-7f55-4e78-a240-bd9175e02853</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,0374759a-7f55-4e78-a240-bd9175e02853.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The Data Collector feature in our <a href="http://www.solution-family.com">Solution
Family product line</a> is one of the oldest (if not the oldest) sections of code,
and as such it's in need of a refactor to improve how it works.  We've updated
just about everything else that uses data storage to use the <a href="http://orm.codeplex.com">OpenNETCF
ORM framework</a>, but Data Collectors have languished, largely because they are complex. 
The Data Collector lets a user create an ad-hoc data collection definition that
translates into a SQL Compact Table at run time.  The problem with migrating
to ORM is that the ORM requires compile-time definitions of all Entities.  At
least that was the problem until today.
</p>
        <p>
I just checked in a new change set that supports the concept of a DynamicEntity (along
with all of the old goodness that is ORM).  Now you can create and register a
DynamicEntityDefinition with your IDataStore at run time and it will generate a table
for you in the back end.  New overloads for all of the typical CRUD commands
(Select, Update, Insert, Delete) allow you to just ask for the DynamicEntity by name
and it returns an array of DynamicEntity instances that hold the field names
and data values.
</p>
        <p>
It's in a "beta" state right now, but there's a test method in the change set that
shows general usage of all CRUD operations.  Give it a spin, and if you find
any bad behavior, <a href="http://orm.codeplex.com/workitem/list/basic">report it
on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0374759a-7f55-4e78-a240-bd9175e02853" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: Dynamic Entities</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,0374759a-7f55-4e78-a240-bd9175e02853.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/07/24/ORMUpdateDynamicEntities.aspx</link>
      <pubDate>Tue, 24 Jul 2012 19:27:45 GMT</pubDate>
      <description>&lt;p&gt;
The Data Collector&amp;nbsp;feature in our &lt;a href="http://www.solution-family.com"&gt;Solution
Family product line&lt;/a&gt; is one of the oldest (if not the oldest) sections of code,
and as such it's in need of a refactor to improve how it works.&amp;nbsp; We've updated
just about everything else that uses data storage to use the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF
ORM framework&lt;/a&gt;, but Data Collectors have languished, largely because they are complex.&amp;nbsp;
The Data Collector lets a user create an ad-hoc data&amp;nbsp;collection definition&amp;nbsp;that
translates into a SQL Compact Table at run time.&amp;nbsp; The problem with migrating
to ORM is that the ORM requires compile-time definitions of all Entities.&amp;nbsp; At
least that was the problem until today.
&lt;/p&gt;
&lt;p&gt;
I just checked in a new change set that supports the concept of a DynamicEntity (along
with all of the old goodness that is ORM).&amp;nbsp; Now you can&amp;nbsp;create and register&amp;nbsp;a
DynamicEntityDefinition with your IDataStore at run time and it will generate a table
for you in the back end.&amp;nbsp; New overloads for all of the typical CRUD commands
(Select, Update, Insert, Delete) allow you to just ask for the DynamicEntity by name
and it returns an array of&amp;nbsp;DynamicEntity instances that hold the field names
and data values.
&lt;/p&gt;
&lt;p&gt;
It's in a "beta" state right now, but there's a test method in the change set that
shows general usage of all CRUD operations.&amp;nbsp; Give it a spin, and if you find
any bad behavior, &lt;a href="http://orm.codeplex.com/workitem/list/basic"&gt;report it
on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0374759a-7f55-4e78-a240-bd9175e02853" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=652963c8-b150-43ae-a716-82c4a50f3b4f</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,652963c8-b150-43ae-a716-82c4a50f3b4f.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It was easy to miss, but <a href="http://connect.microsoft.com/VisualStudio/feedback/details/595712/no-support-for-windows-ce-and-compact-framework-development-in-vs2010" target="_blank">Microsoft
publicly announced</a> that Smart Device development projects will, in fact, be released
in Visual Studio 2012 in Q1 of 2013.  It’s not news to me, but it is to most,
and it’s way, way past due.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=652963c8-b150-43ae-a716-82c4a50f3b4f" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Smart Device projects *will* be supported in Studio 2012!</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,652963c8-b150-43ae-a716-82c4a50f3b4f.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/06/15/SmartDeviceProjectsWillBeSupportedInStudio2012.aspx</link>
      <pubDate>Fri, 15 Jun 2012 14:50:07 GMT</pubDate>
      <description>&lt;p&gt;
It was easy to miss, but &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/details/595712/no-support-for-windows-ce-and-compact-framework-development-in-vs2010" target="_blank"&gt;Microsoft
publicly announced&lt;/a&gt; that Smart Device development projects will, in fact, be released
in Visual Studio 2012 in Q1 of 2013.&amp;#160; It’s not news to me, but it is to most,
and it’s way, way past due.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=652963c8-b150-43ae-a716-82c4a50f3b4f" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>CE Device Development</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f2795a1f-678a-4855-b16c-32f915a81c96</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f2795a1f-678a-4855-b16c-32f915a81c96.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We recently needed the ability to do most-recently-updated data caching in <a href="http://www.solution-family.com/" target="_blank">our
Solution Family products</a>.  Since the products use the <a href="http://orm.codeplex.com" target="_blank">OpenNETCF
ORM Framework</a>, it only made sense to update the framework itself to include events
that fire whenever an Insert, Update or Delete occurs.  In fact I added Before
and After versions for each. While I was at it, I also added a full complement of
virtual On[Before|After][Insert|Update|Delete] methods to the DataStore base, allowing
DataStore implementers to hook into the process as well.  I’m thinking I’ll use
those at some point in the future to add some form of Trigger capabilities.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f2795a1f-678a-4855-b16c-32f915a81c96" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>ORM Update: Added events</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,f2795a1f-678a-4855-b16c-32f915a81c96.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/05/16/ORMUpdateAddedEvents.aspx</link>
      <pubDate>Wed, 16 May 2012 17:14:53 GMT</pubDate>
      <description>&lt;p&gt;
We recently needed the ability to do most-recently-updated data caching in &lt;a href="http://www.solution-family.com/" target="_blank"&gt;our
Solution Family products&lt;/a&gt;.&amp;#160; Since the products use the &lt;a href="http://orm.codeplex.com" target="_blank"&gt;OpenNETCF
ORM Framework&lt;/a&gt;, it only made sense to update the framework itself to include events
that fire whenever an Insert, Update or Delete occurs.&amp;#160; In fact I added Before
and After versions for each. While I was at it, I also added a full complement of
virtual On[Before|After][Insert|Update|Delete] methods to the DataStore base, allowing
DataStore implementers to hook into the process as well.&amp;#160; I’m thinking I’ll use
those at some point in the future to add some form of Trigger capabilities.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f2795a1f-678a-4855-b16c-32f915a81c96" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=289f8ffd-216c-4c49-978f-d6c7cf7854ef</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,289f8ffd-216c-4c49-978f-d6c7cf7854ef.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm trying my hand at making using some of our stuff a bit easier.  Today I burned
some time trying to understand the project template infrastructure and the result
was the creation of a couple VSIX files for installing IoC templates into Visual Studio.  
</p>
        <p>
          <img style="WIDTH: 499px; HEIGHT: 349px" border="0" src="http://blog.opennetcf.com/ctacke/content/binary/ioc_extensions.png" width="501" height="401" />
        </p>
        <p>
Right now it only supports desktop projects (IoC supports Windows Phone, Mono for
Android, Monotouch and Compact Framework). I've also not figured out how to actually
deploy the IoC and Extensions binaries with the templates, so when you create your
project, the References section will contain IoC references, but they'll be broken. 
Still, as a first cut it greatly simplifies setting up a new IoC UI (SmartClientApplication) or
IoC Module project.
</p>
        <p>
You can install the templates in one of three ways:
</p>
        <ul>
          <li>
Use the Extension Manager in Visual Studio (Tools -&gt; Extension Manager ; Online
Gallery ; search for 'OpenNetCF') 
</li>
          <li>
Download them via the Web from <a href="http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=User&amp;f%5B0%5D.Value=ctacke">the
online Visual Studio Gallery</a></li>
          <li>
Pull them from Source Controll over at <a href="http://ioc.codeplex.com">the IoC Project
on Codeplex</a></li>
        </ul>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=289f8ffd-216c-4c49-978f-d6c7cf7854ef" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF IoC Project Templates</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,289f8ffd-216c-4c49-978f-d6c7cf7854ef.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/04/18/OpenNETCFIoCProjectTemplates.aspx</link>
      <pubDate>Wed, 18 Apr 2012 19:04:05 GMT</pubDate>
      <description>&lt;p&gt;
I'm trying my hand at making using some of our stuff a bit easier.&amp;nbsp; Today I burned
some time trying to understand the project template infrastructure and the result
was the creation of a couple VSIX files for installing IoC templates into Visual Studio.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;img style="WIDTH: 499px; HEIGHT: 349px" border=0 src="http://blog.opennetcf.com/ctacke/content/binary/ioc_extensions.png" width=501 height=401&gt;
&lt;/p&gt;
&lt;p&gt;
Right now it only supports desktop projects (IoC supports Windows Phone, Mono for
Android, Monotouch and Compact Framework). I've also not figured out how to actually
deploy the IoC and Extensions binaries with the templates, so when you create your
project, the References section will contain IoC references, but they'll be broken.&amp;nbsp;
Still, as a first cut it greatly simplifies setting up a new IoC UI (SmartClientApplication)&amp;nbsp;or
IoC Module project.
&lt;/p&gt;
&lt;p&gt;
You can install the templates in one of three ways:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Use the Extension Manager in Visual Studio (Tools -&amp;gt; Extension Manager ; Online
Gallery ; search for 'OpenNetCF') 
&lt;li&gt;
Download them via the Web from &lt;a href="http://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=User&amp;amp;f%5B0%5D.Value=ctacke"&gt;the
online Visual Studio Gallery&lt;/a&gt; 
&lt;li&gt;
Pull them from Source Controll over at &lt;a href="http://ioc.codeplex.com"&gt;the IoC Project
on Codeplex&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=289f8ffd-216c-4c49-978f-d6c7cf7854ef" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=2eba1181-4350-4e77-ab2a-a0a1f77fdee0</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,2eba1181-4350-4e77-ab2a-a0a1f77fdee0.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blog.opennetcf.com/ctacke/2008/08/01/AnnouncingTheCABInstallerSDK.aspx">Ages
ago I created an SDK</a> that allows you to extract device CAB files and create a
replacement for <a href="http://msdn.microsoft.com/en-us/library/bb158700.aspx">wceload</a> if
you wanted (we used this on a couple customer applications).  We also tried to
sell it as an experiment in "<a href="http://blog.opennetcf.com/ctacke/2008/08/01/ValueBasedPricingASocialExperiment.aspx">value-based
pricing</a>".  Well the experiment showed, largely, that people would pay the
minimum and very, very rarely come back and pay anything more so either it was of
low value, or people are just cheap.
</p>
        <p>
At any rate, I don't feel like maintaining it internally any longer so it has become
yet another project that I've open sourced for the community at large.  <a href="http://cab.codeplex.com/">The
full download is now available over on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=2eba1181-4350-4e77-ab2a-a0a1f77fdee0" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Now on Codeplex: the OpenNETCF CAB Installer SDK</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,2eba1181-4350-4e77-ab2a-a0a1f77fdee0.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/03/30/NowOnCodeplexTheOpenNETCFCABInstallerSDK.aspx</link>
      <pubDate>Fri, 30 Mar 2012 16:55:07 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2008/08/01/AnnouncingTheCABInstallerSDK.aspx"&gt;Ages
ago I created an SDK&lt;/a&gt; that allows you to extract device CAB files and create a
replacement for &lt;a href="http://msdn.microsoft.com/en-us/library/bb158700.aspx"&gt;wceload&lt;/a&gt; if
you wanted (we used this on a couple customer applications).&amp;nbsp; We also tried to
sell it as an experiment in "&lt;a href="http://blog.opennetcf.com/ctacke/2008/08/01/ValueBasedPricingASocialExperiment.aspx"&gt;value-based
pricing&lt;/a&gt;".&amp;nbsp; Well the experiment showed, largely, that people would pay the
minimum and very, very rarely come back and pay anything more so either it was of
low value, or people are just cheap.
&lt;/p&gt;
&lt;p&gt;
At any rate, I don't feel like maintaining it internally any longer so it has become
yet another project that I've open sourced for the community at large.&amp;nbsp; &lt;a href="http://cab.codeplex.com/"&gt;The
full download is now available over on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=2eba1181-4350-4e77-ab2a-a0a1f77fdee0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>CE Device Development</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=d4274d51-f744-4f95-bf22-bb76b96d636d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,d4274d51-f744-4f95-bf22-bb76b96d636d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I just got an email in the Support inbox over at OpenNETCF asking about the libraries
support (or really lack thereof) for Wireless Networking in Windows Embedded Compact
7 (rolls off the tongue, doesn’t it?).  While this is a question about a specific
feature of the SDF, it really opens up the broader question of what our plans are
for the future of the whole product.  In fact you could say it really opens up
the question on what our general company plans and philosophy are.
</p>
        <p>
First, let’s address this specific issue, as it deserves answering and has a little
bit of a back story leading to a minor rant which is always fun.  
</p>
        <p>
The SDF supports an object model for wireless networks that is based around the Wireless
Zero Config (WZC) API.  Microsoft introduced WZC in CE 5.0 (IIRC) in an attempt
to “standardize” the way the platform and apps would communicate with the wireless
drivers, since NDIS doesn’t really have any specification for a lot of the wireless
properties.  While I applaud the spirit, WZC is convoluted at best, and was definitely
not designed to make the life of someone who has to use P/Invoke to communicate with
it any easier.  Still, it was some sort of standardization so we rolled up our
sleeves and created a managed interface for it.  
</p>
        <p>
I’ll readily admit that what we ended with isn’t ideal, but I’m a fierce self critic
and I rarely think what we do is as good as it could be.  Still it provided a
programmatic interface for something that a *lot* of people wanted and that Microsoft
had not implemented in managed code.
</p>
        <p>
Well with Compact 7 (I’ll just call it CE7) Microsoft decided that WZC wasn’t the
way to go, but instead Native WiFi was.  Painfully they didn’t follow a sensible
“deprecated but supported” track for WZC and support side-by-side, they just dropped
WZC support altogether.  That meant that we could not interface with a wireless
adapter under CE7 using our existing code base at all – it was a flat-out break.
</p>
        <p>
To make things worse, Microsoft went radio-silent for about 2 years (and still counting
– yes I’m looking at you Redmond!) on what, if any, future the Compact Framework,
or CE for that matter, might have.  The original WZC work was probably 4-6 weeks
of development and it required that we buy several devices for testing.  Believe
me, it was a real pain in the ass.  Do we (more specifically do *I*) really feel
like doing that all again for the Native WiFi interfaces?  If I do, where do
I get a CE7 device with WiFi support?  If I do all of that work, what’s the ROI
if Microsoft kills the Compact Framework?  What’s the ROI if they revive it and
implement Wireless themselves?
</p>
        <p>
It’s really difficult to answer those questions, and we’re not the only ones who are
wondering these things.  I can say, though, that we’ve very recently decided
that yes, <strong>we will </strong>continue to do both support <em>and</em> new development
for the SDF.  What that new development will entail I can’t say.  Not because
it’s some big secret, but because I can’t make those plans until Microsoft tells us
their plans (and they haven’t).  If they decide to release a new version of the
Compact Framework, I’d like to not have a load of functionality duplication between
it and the SDF.
</p>
        <p>
So, is the SDF a dead product?  No.  We will continue to support it and
have plans for feature additions.  We just don’t know exactly what those features
will be or when they will be written (confidence inspiring, I know).  
</p>
        <p>
Will we provide Wireless support for CE7?  If Microsoft does not, then yes, we
will.  Again, we don’t know if they will or not.  If they did, we don’t
know when that would be.  Ideally, though, programming for WZC and Native WiFi
should be the same, so if they don’t do it, we’ll add support that looks and feels
just like what’s in the SDF today.  If they <em>do</em> add it, I’d be inclined
to update our object model to match theirs (keeping the old stuff for compatibility
though).
</p>
        <p>
Don’t read too much into this.  Yes, I’m optimistic about the Compact Framework
and <strike>Windows CE</strike> Windows Embedded Compact but I’ve been using them
for over a decade and I’ve based a whole lot of my knowledge, business and life on
them.  I almost have to be optimistic.  But let’s face it, CE and the CF
are still great tools for delivering products.  We’re still shipping products
based on them.  Still doing new development and new installs.  Still writing
proposals for them.  
</p>
        <p>
Yes, we’ve tested the waters with Android and iOS.  We’ve even delivered finished
products for them both, but using those tolls only reinforced my feelings about the
strength and possibilities of the CF and CE and we’re still committed to using and
supporting them.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d4274d51-f744-4f95-bf22-bb76b96d636d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>The future of the Smart Device Framework</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,d4274d51-f744-4f95-bf22-bb76b96d636d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/03/06/TheFutureOfTheSmartDeviceFramework.aspx</link>
      <pubDate>Tue, 06 Mar 2012 23:25:57 GMT</pubDate>
      <description>&lt;p&gt;
I just got an email in the Support inbox over at OpenNETCF asking about the libraries
support (or really lack thereof) for Wireless Networking in Windows Embedded Compact
7 (rolls off the tongue, doesn’t it?).&amp;#160; While this is a question about a specific
feature of the SDF, it really opens up the broader question of what our plans are
for the future of the whole product.&amp;#160; In fact you could say it really opens up
the question on what our general company plans and philosophy are.
&lt;/p&gt;
&lt;p&gt;
First, let’s address this specific issue, as it deserves answering and has a little
bit of a back story leading to a minor rant which is always fun.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
The SDF supports an object model for wireless networks that is based around the Wireless
Zero Config (WZC) API.&amp;#160; Microsoft introduced WZC in CE 5.0 (IIRC) in an attempt
to “standardize” the way the platform and apps would communicate with the wireless
drivers, since NDIS doesn’t really have any specification for a lot of the wireless
properties.&amp;#160; While I applaud the spirit, WZC is convoluted at best, and was definitely
not designed to make the life of someone who has to use P/Invoke to communicate with
it any easier.&amp;#160; Still, it was some sort of standardization so we rolled up our
sleeves and created a managed interface for it.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
I’ll readily admit that what we ended with isn’t ideal, but I’m a fierce self critic
and I rarely think what we do is as good as it could be.&amp;#160; Still it provided a
programmatic interface for something that a *lot* of people wanted and that Microsoft
had not implemented in managed code.
&lt;/p&gt;
&lt;p&gt;
Well with Compact 7 (I’ll just call it CE7) Microsoft decided that WZC wasn’t the
way to go, but instead Native WiFi was.&amp;#160; Painfully they didn’t follow a sensible
“deprecated but supported” track for WZC and support side-by-side, they just dropped
WZC support altogether.&amp;#160; That meant that we could not interface with a wireless
adapter under CE7 using our existing code base at all – it was a flat-out break.
&lt;/p&gt;
&lt;p&gt;
To make things worse, Microsoft went radio-silent for about 2 years (and still counting
– yes I’m looking at you Redmond!) on what, if any, future the Compact Framework,
or CE for that matter, might have.&amp;#160; The original WZC work was probably 4-6 weeks
of development and it required that we buy several devices for testing.&amp;#160; Believe
me, it was a real pain in the ass.&amp;#160; Do we (more specifically do *I*) really feel
like doing that all again for the Native WiFi interfaces?&amp;#160; If I do, where do
I get a CE7 device with WiFi support?&amp;#160; If I do all of that work, what’s the ROI
if Microsoft kills the Compact Framework?&amp;#160; What’s the ROI if they revive it and
implement Wireless themselves?
&lt;/p&gt;
&lt;p&gt;
It’s really difficult to answer those questions, and we’re not the only ones who are
wondering these things.&amp;#160; I can say, though, that we’ve very recently decided
that yes, &lt;strong&gt;we will &lt;/strong&gt;continue to do both support &lt;em&gt;and&lt;/em&gt; new development
for the SDF.&amp;#160; What that new development will entail I can’t say.&amp;#160; Not because
it’s some big secret, but because I can’t make those plans until Microsoft tells us
their plans (and they haven’t).&amp;#160; If they decide to release a new version of the
Compact Framework, I’d like to not have a load of functionality duplication between
it and the SDF.
&lt;/p&gt;
&lt;p&gt;
So, is the SDF a dead product?&amp;#160; No.&amp;#160; We will continue to support it and
have plans for feature additions.&amp;#160; We just don’t know exactly what those features
will be or when they will be written (confidence inspiring, I know).&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Will we provide Wireless support for CE7?&amp;#160; If Microsoft does not, then yes, we
will.&amp;#160; Again, we don’t know if they will or not.&amp;#160; If they did, we don’t
know when that would be.&amp;#160; Ideally, though, programming for WZC and Native WiFi
should be the same, so if they don’t do it, we’ll add support that looks and feels
just like what’s in the SDF today.&amp;#160; If they &lt;em&gt;do&lt;/em&gt; add it, I’d be inclined
to update our object model to match theirs (keeping the old stuff for compatibility
though).
&lt;/p&gt;
&lt;p&gt;
Don’t read too much into this.&amp;#160; Yes, I’m optimistic about the Compact Framework
and &lt;strike&gt;Windows CE&lt;/strike&gt; Windows Embedded Compact but I’ve been using them
for over a decade and I’ve based a whole lot of my knowledge, business and life on
them.&amp;#160; I almost have to be optimistic.&amp;#160; But let’s face it, CE and the CF
are still great tools for delivering products.&amp;#160; We’re still shipping products
based on them.&amp;#160; Still doing new development and new installs.&amp;#160; Still writing
proposals for them.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Yes, we’ve tested the waters with Android and iOS.&amp;#160; We’ve even delivered finished
products for them both, but using those tolls only reinforced my feelings about the
strength and possibilities of the CF and CE and we’re still committed to using and
supporting them.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d4274d51-f744-4f95-bf22-bb76b96d636d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>CE Device Development</category>
      <category>Compact Framework Code</category>
      <category>OpenNETCF</category>
      <category>Rants</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=e39d2628-a149-4764-95e1-b61ca064d432</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,e39d2628-a149-4764-95e1-b61ca064d432.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've been working in the Windows Embedded space for over a decade now, and I must
say it's a far different picture today than it was in years past.  That's not
a jaded nostalgia either - Windows Embedded used to have a real annual conference
at nice venues in Las VEgas.  We has good speakers and great content. 
The teams in Redmond shared loads of info about what was going on and what was coming
down the pike.  Teams cared about what they were doing and what their customers
wanted.
</p>
        <p>
Slowly, though, it seems to have atrphied to the state that it's in today.  I
know of no one using Compact 7 in an actual product.  The Compact Framework hasn't
had an update in something like 4 years and there is absolutely no word at all what
its future might be.  The tools required to do development for non Windows Phone
devices are no longer available unless you purchase a full (expensive) MSDN subscription. 
I can usually count the number of questions that get asked in public forums and places
like Stack Overflow in a week on two hands - sometimes just one.
</p>
        <p>
Today I got what had to be one of the most telling things I've seen though. 
A sign that the people is Redmond just don't care any longer either.  For years,
Microsoft has sent out a monthly embedded newsletter - the Windows Embedded InfoBlast
- and while the quality of the contents has been in the same slow decline
as the rest of the industry, the one I received today just pegged the "I no longer
give a shit" meter.  This is exactly how it looks in Outlook for me:
</p>
        <p>
 
</p>
        <p>
          <img style="WIDTH: 1111px; HEIGHT: 1134px" border="0" src="http://blog.opennetcf.com/ctacke/content/binary/infoblast.PNG" width="1143" height="1261" />
        </p>
        <p>
Obviously either no one cared enough to even look at that before it went out, or if
the did they didn't care if anyone actually read it.  Looking at it is like looking
into the sun, but without the benefit of the warmth on your face.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e39d2628-a149-4764-95e1-b61ca064d432" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>A sign that everyone has just given up</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,e39d2628-a149-4764-95e1-b61ca064d432.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/02/24/ASignThatEveryoneHasJustGivenUp.aspx</link>
      <pubDate>Fri, 24 Feb 2012 05:44:33 GMT</pubDate>
      <description>&lt;p&gt;
I've been working in the Windows Embedded space for over a decade now, and I must
say it's a far different picture today than it was in years past.&amp;nbsp; That's not
a jaded nostalgia either - Windows Embedded used to have a real annual conference
at nice venues in Las VEgas.&amp;nbsp; We has good speakers and&amp;nbsp;great content.&amp;nbsp;
The teams in Redmond shared loads of info about what was going on and what was coming
down the pike.&amp;nbsp; Teams cared about what they were doing and what their customers
wanted.
&lt;/p&gt;
&lt;p&gt;
Slowly, though, it seems to have atrphied to the state that it's in today.&amp;nbsp; I
know of no one using Compact 7 in an actual product.&amp;nbsp; The Compact Framework hasn't
had an update in something like 4 years and there is absolutely no word at all what
its future might be.&amp;nbsp; The tools required to do development for non Windows Phone
devices are no longer available unless you purchase a full (expensive) MSDN subscription.&amp;nbsp;
I can usually count the number of questions that get asked in public forums and places
like Stack Overflow in a week on two hands - sometimes just one.
&lt;/p&gt;
&lt;p&gt;
Today I got what had to be one of the most telling things I've seen though.&amp;nbsp;
A sign that the people is Redmond just don't care any longer either.&amp;nbsp; For years,
Microsoft has sent out a monthly embedded newsletter - the Windows Embedded InfoBlast
- and while the quality of the contents has been in&amp;nbsp;the same&amp;nbsp;slow decline
as the rest of the industry, the one I received today just pegged the "I no longer
give a shit" meter.&amp;nbsp; This is exactly how it looks in Outlook for me:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;img style="WIDTH: 1111px; HEIGHT: 1134px" border=0 src="http://blog.opennetcf.com/ctacke/content/binary/infoblast.PNG" width=1143 height=1261&gt;
&lt;/p&gt;
&lt;p&gt;
Obviously either no one cared enough to even look at that before it went out, or if
the did they didn't care if anyone actually read it.&amp;nbsp; Looking at it is like looking
into the sun, but without the benefit of the warmth on your face.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e39d2628-a149-4764-95e1-b61ca064d432" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Rants</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f24d302c-c82c-4f80-b378-cb3b170afad0</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f24d302c-c82c-4f80-b378-cb3b170afad0.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In my push to get our fundamental libraries up and working on Mono for Android we've added
support for <a href="http://oncfext.codeplex.com">OpenNETCF Extensions</a> and <a href="http://ioc.codeplex.com">OpenNETCF
IoC</a>.  What that means is that now you can have a common code for a lot of
application infrastructure that works on the Compact Framework, the desktop, Windows
Phone, MonoTouch for iOS and Mono for Android.  So you can now create a
single, common code base for your applications that includes data access, event aggregation,
dependency injection and inversion of control.
</p>
        <p>
          <a href="http://ioc.codeplex.com">Get the latest code over on Codeplex.</a>
        </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f24d302c-c82c-4f80-b378-cb3b170afad0" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF IoC now supports Mono for Android (MonoDroid)</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,f24d302c-c82c-4f80-b378-cb3b170afad0.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/02/20/OpenNETCFIoCNowSupportsMonoForAndroidMonoDroid.aspx</link>
      <pubDate>Mon, 20 Feb 2012 18:36:44 GMT</pubDate>
      <description>&lt;p&gt;
In my push to get our fundamental libraries up and working on Mono for Android we've&amp;nbsp;added
support for &lt;a href="http://oncfext.codeplex.com"&gt;OpenNETCF Extensions&lt;/a&gt; and &lt;a href="http://ioc.codeplex.com"&gt;OpenNETCF
IoC&lt;/a&gt;.&amp;nbsp; What that means is that now you can have a common code for a lot of
application infrastructure that works on the Compact Framework, the desktop, Windows
Phone, MonoTouch for iOS&amp;nbsp;and Mono for Android.&amp;nbsp; So you can now create a
single, common code base for your applications that includes data access, event aggregation,
dependency injection and inversion of control.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://ioc.codeplex.com"&gt;Get the latest code over on Codeplex.&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f24d302c-c82c-4f80-b378-cb3b170afad0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Mono for Android</category>
      <category>MonoTouch</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF Extensions</category>
      <category>OpenNETCF.IoC</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=c0035aef-67d9-4e5e-a0c7-268ecc44f355</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,c0035aef-67d9-4e5e-a0c7-268ecc44f355.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've started doing work creating client applications for a few of our products to
run on Android and iOS devices.  Since I'm a huge fan of code re-use, I took
the time this week to port the <a href="http://orm.codeplex.com">OpenNETCF.ORM</a> over
to <a href="http://xamarin.com/monoforandroid">Xamarin's Mono for Android</a> using
a <a href="http://www.sqlite.org/">SQLite backing store</a> implementation. 
The biggest challenge was that SQLite doesn't support TableDirect not ResultSets,
so it took a bit of code to get running.  Still, it took only a day and a half
to get what I feel is pretty good support up and running.  I've not yet tested
it through all of the possible permutations of queries, etc, but basic, single-table
CRUD operations all test out fine.
</p>
        <p>
So now a single code base can work on the Windows Desktop, Windows CE and Android
(probably iOS and Windows Phone as well with very little work). If you're doing MonoDroid
work, give it a try.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c0035aef-67d9-4e5e-a0c7-268ecc44f355" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.ORM Now supports Xamarin Mono for Android</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,c0035aef-67d9-4e5e-a0c7-268ecc44f355.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/02/16/OpenNETCFORMNowSupportsXamarinMonoForAndroid.aspx</link>
      <pubDate>Thu, 16 Feb 2012 21:48:39 GMT</pubDate>
      <description>&lt;p&gt;
We've started doing work creating client applications for a few of our products to
run on Android and iOS devices.&amp;nbsp; Since I'm a huge fan of code re-use, I took
the time this week to port the &lt;a href="http://orm.codeplex.com"&gt;OpenNETCF.ORM&lt;/a&gt;&amp;nbsp;over
to &lt;a href="http://xamarin.com/monoforandroid"&gt;Xamarin's&amp;nbsp;Mono for Android&lt;/a&gt; using
a &lt;a href="http://www.sqlite.org/"&gt;SQLite backing store&lt;/a&gt; implementation.&amp;nbsp;
The biggest challenge was that SQLite doesn't support TableDirect not ResultSets,
so it took a bit of code to get running.&amp;nbsp; Still, it took only a day and a half
to get what I feel is pretty good support up and running.&amp;nbsp; I've not yet tested
it through all of the possible permutations of queries, etc, but basic, single-table
CRUD operations all test out fine.
&lt;/p&gt;
&lt;p&gt;
So now a single code base can work on the Windows Desktop, Windows CE and Android
(probably iOS and Windows Phone as well with very little work). If you're doing MonoDroid
work, give it a try.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c0035aef-67d9-4e5e-a0c7-268ecc44f355" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>MonoTouch</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Mono for Android</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=33482a9b-19b2-4e4e-b4ab-91e500b6c3d8</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,33482a9b-19b2-4e4e-b4ab-91e500b6c3d8.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img src="http://zlib.net/images/zlib3d-b1.png" width="290" height="152" />
        </p>
        <p>
Occasionally I'm surprised at how old software never seems to really die off. 
Take for example an old port I did of the zlib compression library to Windows CE. 
Back in probably '05 I built the original sources for the Windows CE platform. 
In '07 I created a managed wrapper for the library and some samples on how to use
that library.  I put it on the web and then pretty much forgot about it.
</p>
        <p>
Well when we migrated our web site to a new server, some old links died and this just
happened to be one of them (if you know of others, please let me know) and today I
got an email from someone asking if I still had the code.  Sure, it wasn't the
day things went down, but it still means not only was someone looking for it, the
cared enough to email me and ask.
</p>
        <p>
For those looking for it, it's got a new, hoipefully more permanent home on Codeplex:  <a href="http://zlibce.codeplex.com">http://zlibce.codeplex.com</a></p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=33482a9b-19b2-4e4e-b4ab-91e500b6c3d8" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>New home for zlib for Windows CE</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,33482a9b-19b2-4e4e-b4ab-91e500b6c3d8.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2012/02/14/NewHomeForZlibForWindowsCE.aspx</link>
      <pubDate>Tue, 14 Feb 2012 19:04:43 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img src="http://zlib.net/images/zlib3d-b1.png" width=290 height=152&gt;
&lt;/p&gt;
&lt;p&gt;
Occasionally I'm surprised at how old software never seems to really die off.&amp;nbsp;
Take for example an old port I did of the zlib compression library to Windows CE.&amp;nbsp;
Back in probably '05 I built the original sources for the Windows CE platform.&amp;nbsp;
In '07 I created a managed wrapper for the library and some samples on how to use
that library.&amp;nbsp; I put it on the web and then pretty much forgot about it.
&lt;/p&gt;
&lt;p&gt;
Well when we migrated our web site to a new server, some old links died and this just
happened to be one of them (if you know of others, please let me know) and today I
got an email from someone asking if I still had the code.&amp;nbsp; Sure, it wasn't the
day things went down, but it still means not only was someone looking for it, the
cared enough to email me and ask.
&lt;/p&gt;
&lt;p&gt;
For those looking for it, it's got a new, hoipefully more permanent home on Codeplex:&amp;nbsp; &lt;a href="http://zlibce.codeplex.com"&gt;http://zlibce.codeplex.com&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=33482a9b-19b2-4e4e-b4ab-91e500b6c3d8" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=5f1113a9-97c6-4dfb-82bb-382303108022</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,5f1113a9-97c6-4dfb-82bb-382303108022.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Lately it seems that I’m been doing a lot of posts referring to “a customer”. 
Often they are different customers, but it really sounds impersonal, so in this one
I’m going to name names and point fingers – in a friendly way, of course.
</p>
        <p>
Last week Nicolas emailed me to get some advice on the Visual Studio 2008 Forms designer
and the Compact Framework.  Specifically he wanted to know if it’s possible to
get a custom TabControl to be designable.  My assumption is that either he’s
inheriting from the stock version or they’ve created a fully custom control inheriting
from ContainerControl – I didn’t ask because in either case the answer is simple:
it’s not going to work in the designer.
</p>
        <p>
I told him that it won’t work, but in retrospect I feel I’ve short-changed him a bit. 
As a developer, I like to hear a bit more than an “abandon all hope, ye who sail here
for there be sea monsters” kind of response.  Why doesn’t it work?  More
importantly, what are my options for a workaround?
</p>
        <p>
In this case it’s interesting to note that even if he could get the designer to work
for this control, I’d recommend that he <strong><em>not</em></strong> do it. 
And they why to that recommendation is far more interesting.
</p>
        <p>
So, Nicolas, here’s the longer answer to your question.
</p>
        <p>
First, you have to understand that the Studio Designer is very, very brittle. 
Any little quirkiness tends to send it into fits, and once broke you often spend large
amounts of time unloading things, resetting the toolbox, restarting Studio or even
restarting the PC.  This is a huge time drain, so avoiding situations that break
the designer is the first order of business.
</p>
        <p>
Getting the designer working for a CF component is even worse.  CF controls often
make use of things that the desktop doesn’t even have, which the designer really hates. 
You also have to build the Controls for both versions of the CF (for Nicolas this
is important since, at least last time I was with his team, they had versions of the
application targeting CF 2.0 and CF 3.5).  A control built against CF 3.5 will
never show up in the designer of a CF 2.0 project.  There’s also a major bug
in the designer that limits CF 3.5 controls that <a href="http://blog.opennetcf.com/ctacke/2008/11/26/Studio08sToolboxAndCompactFrameworkAssemblies.aspx" target="_blank">I’ve
written about before</a>.
</p>
        <p>
For designer support you also have to maintain an XMTA file and often end up having
condition compiler statements which really make the code less readable.  Workarounds
for most of these issues exist.  You can create separate set of “designer” assemblies
that provide only stuff for the designer and minimal actual control logic.  The
problem with this is that you then have to maintain these things, which sucks up developer
time that should be spent actually solving your business problem.
</p>
        <p>
You can’t create a desktop assembly and use it for the designer because the designer
will then suck in the full .NET framework as a reference and attempt to deploy that
to the device when you want to debug.
</p>
        <p>
So if the designer is so brittle and worthless, what’s a developer to do?  Well,
my general attitude is to provide “support” only for basic Controls, and by “support”
I mean the inherent capability of the designer to show a box with the location and
bounds of your control.  No rendering.  No styling.  No collection
editing.  
</p>
        <p>
Really the designer’s primary use for me is to aid in basic layout.  I need to
put a Control on a Form, set it’s location and Size and that’s it anyway.  Anything
else is done via code, and there’s nothing wrong with this.  Embrace it as how
you must work and your life becomes much simpler.
</p>
        <p>
That’s all well and good for a simple Control, but what about a container like Nicolas
is after?  His team would like to be able to drop on a Tab control and design
each individual Tab, right?  So what are they to do?
</p>
        <p>
Well, I think they’re looking at the problem wrong to begin with.  I don’t blame
them, people have been looking at this wrong for some time, and the simple existence
of the TabControl tend to push people to look at it wrong.  In general, my recommendation
is to not use the TabControl in the first place.  
</p>
        <p>
First of all, it’s 2011.  That ass-looking TabControl would have been ok back
in 1995 (if the devices had existed then) since it looks just like the ass-looking
Windows 95 interface.  
</p>
        <p>
It’s was an ok solution in 2000 when these devices were new and people thought of
them as just “mini PCs” so extending the desktop paradigm to the device was what we
did.    Yes, we wished we could do a little more to make it pretty
by adding icons and custom drawing, but it worked and users really didn’t expect anything
more.
</p>
        <p>
But it’s 2011.  Users don’t use a stylus if they can avoid it.  They know
an elegant UI when they see one because they’ve been using a smartphone.  Just
because they have no choice in the app they use (this is an LOB app, so the user is
locked in) is no excuse to not deliver something that is actually nice to use. 
The TabControl does not meet that.  It’s tiny, it scrolls weird, and it’s ugly
with no options to make it non-ugly.  Plus it’s  Tab motif.  Name the
last mobile app you used on a phone that used tabs.  That’s what I thought. Abandon
the piece of crap.
</p>
        <p>
So what would I use?  Obviously this will be subjective, as it’s what I would
personally do given a blank slate.  Nicolas is trying to put something into an
already-existing, very large code base, so his mileage may vary, but I’m betting it
won’t be too bad, and implementing this might actually do a lot toward getting other
gains they really need like better transition time between views.
</p>
        <p>
I’d start using the <a href="http://ioc.codeplex.com/" target="_blank">OpenNETCF IoC
project</a>.  I’d split each of the existing “tabs” into individual SmartParts,
which are now fully designable since they’re just UserControls.  So there you
are – the designer requirement is solved.  I’d then place on the Form a pair
of DeckWorkspaces.  One would display the “selected” view and the other would
replace the “tabs” of old with buttons or clickable images that would be used to select
the current view.  It would look something like this in the designer for the
Form:
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="tabs" border="0" alt="tabs" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs_thumb.png" width="200" height="312" />
          </a>
        </p>
        <p>
And then the SmartPart that goes into the bottom workspace might be something like
this in the designer (well it would probably be a bit different, but you get the idea):
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs2.png">
            <img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="tabs2" border="0" alt="tabs2" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs2_thumb.png" width="244" height="76" />
          </a>
        </p>
        <p>
See, the designer works.  It meets the business requirement that it provides
a “tab-like” capability where the user selects an item across the bottom and the upper
view changes.  But now it’s not just usable with a stylus but it’s also likely
to be usable with a finger (<strong>gasp</strong>!) and aesthetically it doesn’t make
my want to poke my own eyes out.  It’s a win-win.  Plus now you can lazy-load
the views *on demand* rather than loading up every damned control on every tab when
the Form is brought up, so the user is going to be pleasantly surprised there too. 
Oh, and now it’s easy to change out “tabs” based on user rights or workflow and probably
other benefits that I’m not thinking of.
</p>
        <p>
Occasionally we’ve got to break out of the “what we know” and the “what we’ve always
done” routine and look out at the horizon.  By doing so we can often make some
simple changes and make things easier for both the developer and the user, and that
is how we make progress.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5f1113a9-97c6-4dfb-82bb-382303108022" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Compact Framework and the Visual Studio Designer</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,5f1113a9-97c6-4dfb-82bb-382303108022.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/28/CompactFrameworkAndTheVisualStudioDesigner.aspx</link>
      <pubDate>Mon, 28 Nov 2011 18:24:00 GMT</pubDate>
      <description>&lt;p&gt;
Lately it seems that I’m been doing a lot of posts referring to “a customer”.&amp;#160;
Often they are different customers, but it really sounds impersonal, so in this one
I’m going to name names and point fingers – in a friendly way, of course.
&lt;/p&gt;
&lt;p&gt;
Last week Nicolas emailed me to get some advice on the Visual Studio 2008 Forms designer
and the Compact Framework.&amp;#160; Specifically he wanted to know if it’s possible to
get a custom TabControl to be designable.&amp;#160; My assumption is that either he’s
inheriting from the stock version or they’ve created a fully custom control inheriting
from ContainerControl – I didn’t ask because in either case the answer is simple:
it’s not going to work in the designer.
&lt;/p&gt;
&lt;p&gt;
I told him that it won’t work, but in retrospect I feel I’ve short-changed him a bit.&amp;#160;
As a developer, I like to hear a bit more than an “abandon all hope, ye who sail here
for there be sea monsters” kind of response.&amp;#160; Why doesn’t it work?&amp;#160; More
importantly, what are my options for a workaround?
&lt;/p&gt;
&lt;p&gt;
In this case it’s interesting to note that even if he could get the designer to work
for this control, I’d recommend that he &lt;strong&gt;&lt;em&gt;not&lt;/em&gt;&lt;/strong&gt; do it.&amp;#160;
And they why to that recommendation is far more interesting.
&lt;/p&gt;
&lt;p&gt;
So, Nicolas, here’s the longer answer to your question.
&lt;/p&gt;
&lt;p&gt;
First, you have to understand that the Studio Designer is very, very brittle.&amp;#160;
Any little quirkiness tends to send it into fits, and once broke you often spend large
amounts of time unloading things, resetting the toolbox, restarting Studio or even
restarting the PC.&amp;#160; This is a huge time drain, so avoiding situations that break
the designer is the first order of business.
&lt;/p&gt;
&lt;p&gt;
Getting the designer working for a CF component is even worse.&amp;#160; CF controls often
make use of things that the desktop doesn’t even have, which the designer really hates.&amp;#160;
You also have to build the Controls for both versions of the CF (for Nicolas this
is important since, at least last time I was with his team, they had versions of the
application targeting CF 2.0 and CF 3.5).&amp;#160; A control built against CF 3.5 will
never show up in the designer of a CF 2.0 project.&amp;#160; There’s also a major bug
in the designer that limits CF 3.5 controls that &lt;a href="http://blog.opennetcf.com/ctacke/2008/11/26/Studio08sToolboxAndCompactFrameworkAssemblies.aspx" target="_blank"&gt;I’ve
written about before&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
For designer support you also have to maintain an XMTA file and often end up having
condition compiler statements which really make the code less readable.&amp;#160; Workarounds
for most of these issues exist.&amp;#160; You can create separate set of “designer” assemblies
that provide only stuff for the designer and minimal actual control logic.&amp;#160; The
problem with this is that you then have to maintain these things, which sucks up developer
time that should be spent actually solving your business problem.
&lt;/p&gt;
&lt;p&gt;
You can’t create a desktop assembly and use it for the designer because the designer
will then suck in the full .NET framework as a reference and attempt to deploy that
to the device when you want to debug.
&lt;/p&gt;
&lt;p&gt;
So if the designer is so brittle and worthless, what’s a developer to do?&amp;#160; Well,
my general attitude is to provide “support” only for basic Controls, and by “support”
I mean the inherent capability of the designer to show a box with the location and
bounds of your control.&amp;#160; No rendering.&amp;#160; No styling.&amp;#160; No collection
editing.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
Really the designer’s primary use for me is to aid in basic layout.&amp;#160; I need to
put a Control on a Form, set it’s location and Size and that’s it anyway.&amp;#160; Anything
else is done via code, and there’s nothing wrong with this.&amp;#160; Embrace it as how
you must work and your life becomes much simpler.
&lt;/p&gt;
&lt;p&gt;
That’s all well and good for a simple Control, but what about a container like Nicolas
is after?&amp;#160; His team would like to be able to drop on a Tab control and design
each individual Tab, right?&amp;#160; So what are they to do?
&lt;/p&gt;
&lt;p&gt;
Well, I think they’re looking at the problem wrong to begin with.&amp;#160; I don’t blame
them, people have been looking at this wrong for some time, and the simple existence
of the TabControl tend to push people to look at it wrong.&amp;#160; In general, my recommendation
is to not use the TabControl in the first place.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
First of all, it’s 2011.&amp;#160; That ass-looking TabControl would have been ok back
in 1995 (if the devices had existed then) since it looks just like the ass-looking
Windows 95 interface.&amp;#160; 
&lt;/p&gt;
&lt;p&gt;
It’s was an ok solution in 2000 when these devices were new and people thought of
them as just “mini PCs” so extending the desktop paradigm to the device was what we
did.&amp;#160;&amp;#160;&amp;#160; Yes, we wished we could do a little more to make it pretty
by adding icons and custom drawing, but it worked and users really didn’t expect anything
more.
&lt;/p&gt;
&lt;p&gt;
But it’s 2011.&amp;#160; Users don’t use a stylus if they can avoid it.&amp;#160; They know
an elegant UI when they see one because they’ve been using a smartphone.&amp;#160; Just
because they have no choice in the app they use (this is an LOB app, so the user is
locked in) is no excuse to not deliver something that is actually nice to use.&amp;#160;
The TabControl does not meet that.&amp;#160; It’s tiny, it scrolls weird, and it’s ugly
with no options to make it non-ugly.&amp;#160; Plus it’s&amp;#160; Tab motif.&amp;#160; Name the
last mobile app you used on a phone that used tabs.&amp;#160; That’s what I thought. Abandon
the piece of crap.
&lt;/p&gt;
&lt;p&gt;
So what would I use?&amp;#160; Obviously this will be subjective, as it’s what I would
personally do given a blank slate.&amp;#160; Nicolas is trying to put something into an
already-existing, very large code base, so his mileage may vary, but I’m betting it
won’t be too bad, and implementing this might actually do a lot toward getting other
gains they really need like better transition time between views.
&lt;/p&gt;
&lt;p&gt;
I’d start using the &lt;a href="http://ioc.codeplex.com/" target="_blank"&gt;OpenNETCF IoC
project&lt;/a&gt;.&amp;#160; I’d split each of the existing “tabs” into individual SmartParts,
which are now fully designable since they’re just UserControls.&amp;#160; So there you
are – the designer requirement is solved.&amp;#160; I’d then place on the Form a pair
of DeckWorkspaces.&amp;#160; One would display the “selected” view and the other would
replace the “tabs” of old with buttons or clickable images that would be used to select
the current view.&amp;#160; It would look something like this in the designer for the
Form:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="tabs" border="0" alt="tabs" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs_thumb.png" width="200" height="312" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And then the SmartPart that goes into the bottom workspace might be something like
this in the designer (well it would probably be a bit different, but you get the idea):
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs2.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="tabs2" border="0" alt="tabs2" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/f605a141814d_9C4C/tabs2_thumb.png" width="244" height="76" /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
See, the designer works.&amp;#160; It meets the business requirement that it provides
a “tab-like” capability where the user selects an item across the bottom and the upper
view changes.&amp;#160; But now it’s not just usable with a stylus but it’s also likely
to be usable with a finger (&lt;strong&gt;gasp&lt;/strong&gt;!) and aesthetically it doesn’t make
my want to poke my own eyes out.&amp;#160; It’s a win-win.&amp;#160; Plus now you can lazy-load
the views *on demand* rather than loading up every damned control on every tab when
the Form is brought up, so the user is going to be pleasantly surprised there too.&amp;#160;
Oh, and now it’s easy to change out “tabs” based on user rights or workflow and probably
other benefits that I’m not thinking of.
&lt;/p&gt;
&lt;p&gt;
Occasionally we’ve got to break out of the “what we know” and the “what we’ve always
done” routine and look out at the horizon.&amp;#160; By doing so we can often make some
simple changes and make things easier for both the developer and the user, and that
is how we make progress.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5f1113a9-97c6-4dfb-82bb-382303108022" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=b79277f3-0cbb-40a1-9305-096a19fc3495</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,b79277f3-0cbb-40a1-9305-096a19fc3495.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've published new updates to our MTConnect projects on Codeplex. Both the <a href="http://mtconnect.codeplex.com">MTConnect
SDK</a> and the <a href="http://mtcagent.codeplex.com">VirtualAgent</a> have changes
and for detailed info take a look at the change logs in the Source tabs on the project. 
Here's a high-level list of what I think the important additions are:
</p>
        <ul>
          <li>
I've added a fully working reference implementation of an MTConnect Adapter for Okuma
THINC controllers (full source is included).  If you have an Okuma machine with
a THINC-supported controller on it, you now have a simple agent and adapter you can
drop onto the machine to start publishing data immediately. I hope to find time to
put together a reference implementation for Fanuc FOCAS controllers.  If you're
interested or in need of that support, let me know and we can discuss prioritizing
it and the features you need.</li>
          <li>
I've added support for SHDR adapters.  At the [MC]2 conference in Cincinnati
there was concern that once you selected an Agent technology (either ours or the reference
MTConnect C++ Agent), then you were locked in to creating Adapters only for that Agent. 
That is no longer the case.  Our Virtual Agent now can easily consume data from
your existing C/C++ Adapters written against the reference Agent.  No changes
are required in your existing Adapters at all.</li>
        </ul>
        <p>
If you have any questions on implementation, etc, feel free to contact me.  For
more info on our entire line of MTConnect products, take a look at <a href="http://www.solution-family.com">our
web site</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=b79277f3-0cbb-40a1-9305-096a19fc3495" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>MTConnect Updates</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,b79277f3-0cbb-40a1-9305-096a19fc3495.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/23/MTConnectUpdates.aspx</link>
      <pubDate>Wed, 23 Nov 2011 17:46:09 GMT</pubDate>
      <description>&lt;p&gt;
I've published new updates to our MTConnect projects on Codeplex. Both the &lt;a href="http://mtconnect.codeplex.com"&gt;MTConnect
SDK&lt;/a&gt; and the &lt;a href="http://mtcagent.codeplex.com"&gt;VirtualAgent&lt;/a&gt; have changes
and for detailed info take a look at the change logs in the Source tabs on the project.&amp;nbsp;
Here's&amp;nbsp;a high-level list of what I think the important additions are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
I've added a fully working reference implementation of an MTConnect Adapter for Okuma
THINC controllers (full source is included).&amp;nbsp; If you have an Okuma machine with
a THINC-supported controller on it, you now have a simple agent and adapter you can
drop onto the machine to start publishing data immediately. I hope to find time to
put together a reference implementation for Fanuc FOCAS controllers.&amp;nbsp; If you're
interested or in need of that support, let me know and we can discuss prioritizing
it and the features you need.&lt;/li&gt;
&lt;li&gt;
I've added support for SHDR adapters.&amp;nbsp; At the [MC]2 conference in Cincinnati
there was concern that once you selected an Agent technology (either ours or the reference
MTConnect C++ Agent), then you were locked in to creating Adapters only for that Agent.&amp;nbsp;
That is no longer the case.&amp;nbsp; Our Virtual Agent now can easily consume data from
your existing C/C++ Adapters written against the reference Agent.&amp;nbsp; No changes
are required in your existing Adapters at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If you have any questions on implementation, etc, feel free to contact me.&amp;nbsp; For
more info on our entire line of MTConnect products, take a look at &lt;a href="http://www.solution-family.com"&gt;our
web site&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=b79277f3-0cbb-40a1-9305-096a19fc3495" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=10a9300c-a6dc-4adb-94b3-9001358b103e</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,10a9300c-a6dc-4adb-94b3-9001358b103e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So a customer asked me last week if I could provide them some managed code to allow
them to insert a certificate and a private key into the certificate store on a Windows
CE device.  A simple enough request, right?  Heh, isn’t that how they all
start?
</p>
        <p>
To be honest, I’ve done very little work with certificates in the past – basically
I’ve created certs for use with Padarn and SSL but that’s about it. So my first order
of business was to do some due diligence to try to get an idea of the scope of the
problem.  I pulled up the MSDN docs of the Compact Framework’s support for X509
stuff.  It shows that there is device support for the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store_members(v=VS.90).aspx" target="_blank">X509Store</a> as
well as the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate_members(v=VS.90).aspx" target="_blank">X509Certificate</a> so
I told them it should be pretty easy to achieve their goal.  I mean the docs
sure look like it would be easy.
</p>
        <p>
Next I needed to write a little code to familiarize myself with the object model. 
I fired up a device that most definitely has several certificates installed.
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECerts_2.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="CECerts" border="0" alt="CECerts" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECerts_thumb.png" width="444" height="189" />
          </a>
        </p>
        <p>
Then I wrote some simple code to give me an idea which of the six stores these fall
into:
</p>
        <pre class="csharp" name="code">public void DumpCertCounts() 
{ 
    Debug.WriteLine("        Current User     Local Machine");

    var userStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser); 
    var deviceStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("Root:          {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
    
    userStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("My:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count));

    userStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("CA:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
} 
</pre>
        <p>
Easy enough.  The problem was that then I actually ran the code.  This is
the output.
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="CECertDbg" border="0" alt="CECertDbg" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg_thumb.png" width="437" height="192" />
          </a>
        </p>
        <p>
Really?  Zero certificates in any store?  Was my code right?  Yes. 
Did I target the right device from the debugger?  Yes.  Alrighty, so it
seems that “existence of a class in the BCL” doesn’t necessarily mean “actual functionality
is implemented.”  This doesn’t bode well.
</p>
        <p>
Technically I don’t need to know what certificates are installed on the device for
the customer’s request, right.  Sure, it would be nice to see if a cert is there
before trying to install it, but we can always just wrap the call in a try/catch and
ignore any exception thrown when we try to install a duplicate.  Not the ideal
solution, but workable since this will be done infrequently.
</p>
        <p>
I then generated some test certs with <a href="http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.80).aspx" target="_blank">makecert.exe</a> and
pushed them to the device.  Now I needed to create code to import them, hopefully
an import works better than enumerating existing certs.  
</p>
        <p>
Let’s see, how would we bring in a cert?  How about the Import method on the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2collection_members(v=VS.90).aspx" target="_blank">X509CerticateCollection</a>? 
Oh, not supported in the CF. 
</p>
        <p>
Ah, but the Add method is, so I just need to create an X509Certificate and Add it. 
Let’s see, the X509Certifiacte class has two static methods – CreateFromCertFile and
CreateFromSignedFile.  Of course those aren’t supported in the CF.  That
would be too easy.
</p>
        <p>
How about from a constructor? Looks like the <a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate.x509certificate(v=VS.90).aspx" target="_blank">only
constructor supported</a> is the one that takes in a byte array.  What on earth
is that byte array.  Oh, the example shows that it’s easy to get by Exporting
from a certificate you already have.  How un-useful is that?
</p>
        <p>
So it appears that the entire namespace in the Compact Framework is useless. 
Actually worse than useless because I can’t create a direct replacement or I’ll end
up with naming conflicts with the existing useless garbage.
</p>
        <p>
So now I have to create the objects in the namespace and implement the methods required
to achieve “import a certificate into the device store”.  The starting point
is the C source code for the Certificates control panel applet you see above, which
ships with Platform Builder.  It’s an ugly load of P/Invoking methods that deal
with lots of pointers to structs that contains pointers to structs that contain pointers
to structs that contain…you get the idea.
</p>
        <p>
So I spent a day just getting the import of a CER file working (much easier than the
PVK import is going to be) and my exact same test code now outputs this:
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg2.png">
            <img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title="CECertDbg2" border="0" alt="CECertDbg2" src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg2_thumb.png" width="328" height="131" />
          </a>
        </p>
        <p>
See, an implementation that actually does something.  I have no idea what was
going on at Microsoft when this namespace was “implemented” or how it got out the
door.  It definitely wouldn’t pass even the most rudimentary of functional tests.
</p>
        <p>
This is a classic case of why I’d love to see the Compact Framework open/shared sourced. 
I could actually go in and fix these things.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=10a9300c-a6dc-4adb-94b3-9001358b103e" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>X509 Certificates + Compact Framework = WTF?</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,10a9300c-a6dc-4adb-94b3-9001358b103e.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/22/X509CertificatesCompactFrameworkWTF.aspx</link>
      <pubDate>Tue, 22 Nov 2011 16:41:17 GMT</pubDate>
      <description>&lt;p&gt;
So a customer asked me last week if I could provide them some managed code to allow
them to insert a certificate and a private key into the certificate store on a Windows
CE device.&amp;nbsp; A simple enough request, right?&amp;nbsp; Heh, isn’t that how they all
start?
&lt;/p&gt;
&lt;p&gt;
To be honest, I’ve done very little work with certificates in the past – basically
I’ve created certs for use with Padarn and SSL but that’s about it. So my first order
of business was to do some due diligence to try to get an idea of the scope of the
problem.&amp;nbsp; I pulled up the MSDN docs of the Compact Framework’s support for X509
stuff.&amp;nbsp; It shows that there is device support for the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store_members(v=VS.90).aspx" target=_blank&gt;X509Store&lt;/a&gt; as
well as the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate_members(v=VS.90).aspx" target=_blank&gt;X509Certificate&lt;/a&gt; so
I told them it should be pretty easy to achieve their goal.&amp;nbsp; I mean the docs
sure look like it would be easy.
&lt;/p&gt;
&lt;p&gt;
Next I needed to write a little code to familiarize myself with the object model.&amp;nbsp;
I fired up a device that most definitely has several certificates installed.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECerts_2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=CECerts border=0 alt=CECerts src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECerts_thumb.png" width=444 height=189&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Then I wrote some simple code to give me an idea which of the six stores these fall
into:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public void DumpCertCounts() 
{ 
    Debug.WriteLine("        Current User     Local Machine");

    var userStore = new X509Store(StoreName.Root, StoreLocation.CurrentUser); 
    var deviceStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("Root:          {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
    
    userStore = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.My, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("My:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count));

    userStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser); 
    deviceStore = new X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine); 
    Debug.WriteLine(string.Format("CA:            {0}              {1}", 
        userStore.Certificates.Count, 
        deviceStore.Certificates.Count)); 
} 
&lt;/pre&gt;
&lt;p&gt;
Easy enough.&amp;nbsp; The problem was that then I actually ran the code.&amp;nbsp; This is
the output.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=CECertDbg border=0 alt=CECertDbg src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg_thumb.png" width=437 height=192&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Really?&amp;nbsp; Zero certificates in any store?&amp;nbsp; Was my code right?&amp;nbsp; Yes.&amp;nbsp;
Did I target the right device from the debugger?&amp;nbsp; Yes.&amp;nbsp; Alrighty, so it
seems that “existence of a class in the BCL” doesn’t necessarily mean “actual functionality
is implemented.”&amp;nbsp; This doesn’t bode well.
&lt;/p&gt;
&lt;p&gt;
Technically I don’t need to know what certificates are installed on the device for
the customer’s request, right.&amp;nbsp; Sure, it would be nice to see if a cert is there
before trying to install it, but we can always just wrap the call in a try/catch and
ignore any exception thrown when we try to install a duplicate.&amp;nbsp; Not the ideal
solution, but workable since this will be done infrequently.
&lt;/p&gt;
&lt;p&gt;
I then generated some test certs with &lt;a href="http://msdn.microsoft.com/en-us/library/bfsktky3(v=vs.80).aspx" target=_blank&gt;makecert.exe&lt;/a&gt; and
pushed them to the device.&amp;nbsp; Now I needed to create code to import them, hopefully
an import works better than enumerating existing certs.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Let’s see, how would we bring in a cert?&amp;nbsp; How about the Import method on the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2collection_members(v=VS.90).aspx" target=_blank&gt;X509CerticateCollection&lt;/a&gt;?&amp;nbsp;
Oh, not supported in the CF. 
&lt;/p&gt;
&lt;p&gt;
Ah, but the Add method is, so I just need to create an X509Certificate and Add it.&amp;nbsp;
Let’s see, the X509Certifiacte class has two static methods – CreateFromCertFile and
CreateFromSignedFile.&amp;nbsp; Of course those aren’t supported in the CF.&amp;nbsp; That
would be too easy.
&lt;/p&gt;
&lt;p&gt;
How about from a constructor? Looks like the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate.x509certificate(v=VS.90).aspx" target=_blank&gt;only
constructor supported&lt;/a&gt; is the one that takes in a byte array.&amp;nbsp; What on earth
is that byte array.&amp;nbsp; Oh, the example shows that it’s easy to get by Exporting
from a certificate you already have.&amp;nbsp; How un-useful is that?
&lt;/p&gt;
&lt;p&gt;
So it appears that the entire namespace in the Compact Framework is useless.&amp;nbsp;
Actually worse than useless because I can’t create a direct replacement or I’ll end
up with naming conflicts with the existing useless garbage.
&lt;/p&gt;
&lt;p&gt;
So now I have to create the objects in the namespace and implement the methods required
to achieve “import a certificate into the device store”.&amp;nbsp; The starting point
is the C source code for the Certificates control panel applet you see above, which
ships with Platform Builder.&amp;nbsp; It’s an ugly load of P/Invoking methods that deal
with lots of pointers to structs that contains pointers to structs that contain pointers
to structs that contain…you get the idea.
&lt;/p&gt;
&lt;p&gt;
So I spent a day just getting the import of a CER file working (much easier than the
PVK import is going to be) and my exact same test code now outputs this:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg2.png"&gt;&lt;img style="BACKGROUND-IMAGE: none; BORDER-RIGHT-WIDTH: 0px; PADDING-LEFT: 0px; PADDING-RIGHT: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; PADDING-TOP: 0px" title=CECertDbg2 border=0 alt=CECertDbg2 src="http://blog.opennetcf.com/ctacke/content/binary/Windows-Live-Writer/X509-Certificates-in-the-Compact-Framewo_8A9B/CECertDbg2_thumb.png" width=328 height=131&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
See, an implementation that actually does something.&amp;nbsp; I have no idea what was
going on at Microsoft when this namespace was “implemented” or how it got out the
door.&amp;nbsp; It definitely wouldn’t pass even the most rudimentary of functional tests.
&lt;/p&gt;
&lt;p&gt;
This is a classic case of why I’d love to see the Compact Framework open/shared sourced.&amp;nbsp;
I could actually go in and fix these things.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=10a9300c-a6dc-4adb-94b3-9001358b103e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>Rants</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=8a41ba23-a3cc-4786-a672-f8d45c2f15be</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,8a41ba23-a3cc-4786-a672-f8d45c2f15be.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is part of my "Software Development" series. <a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx">The
TOC for the entire series can be found here</a>.
</p>
        <hr />
        <p>
Let’s start this post with a couple questions.  What is an ORM and why would
you use one?  If you don’t know the answer to both of these questions, then this
post is for you.  If you do know the answers, feel free to skip to the next post
(after I’ve created it of course).
</p>
        <p>
First, let’s look at what an ORM is. And ORM is an object-relational mapping. 
According to Wikipedia, which we all know is the infallible and definitive resource
for all knowledge, and ORM is “a <a href="http://en.wikipedia.org/wiki/Computer_programming">programming</a> technique
for converting data between incompatible <a href="http://en.wikipedia.org/wiki/Type_system">type
systems</a> in <a href="http://en.wikipedia.org/wiki/Object-oriented">object-oriented</a> programming
languages.”  Ok, what the hell does that mean?  My definition is a little
less “scholarly.”  I’d say that
</p>
        <blockquote>
          <p>
An ORM is a way to abstract your data storage into simple class objects (POCOs if
you’d like) so that you don’t have to worry about all the crap involved in actually
writing data fields, rows, tables and the like.  As a developer, I want to deal
with a “Person” class.  I don’t want to think about SQL statements.  I don’t
want to have to worry about indexes or tables or even how my “Person” gets stored
to or read from disk.  I just want to say “Save this Person instance” and have
it done.  THAT is what an ORM is.  A framework that lets me concentrate
on solving my business problem instead of spending days writing bullshit, mind-numbing,
error-prone data access layer code.
</p>
        </blockquote>
        <p>
Why would we use an ORM?  I think I’ve been fairly upfront that I consider myself
to be a lazy developer.  No, I don’t mean that I take shortcuts or do shoddy
work, I mean that I hate doing things more than once.  I hate having to write
reams of code to solve problems that have already been solved.  I’ve been writing
applications that consume data for years, and as a consequence, I’ve been writing
data access code for years.  If you’re not using an ORM, you probably know down
in your soul that this type of work flat-out sucks.  Anything that simplifies
data access to me is a win.
</p>
        <p>
Of course there are other, more tangible benefits as well.  If you’re using an
ORM, it’s often possible to swap out data stores – so maybe you could write to SQL
Server then swap a line of two in configuration and write to MySQL or an XML file. 
It also allows you to mock things or create stubs to remove data access (really handy
when someone tells you that your data access is what’s slowing things down when you’re
pretty sure it’s not).
</p>
        <p>
I can see that some of you still need convincing.  That’s good – you shouldn’t
ever just take someone’s word for it that they know what they’re doing.  Ask
for proof.  Well let’s look at a case of my own code, why I built the <a href="http://orm.codeplex.com" target="_blank">OpenNETCF
ORM</a> and how I was recently reminded why it’s a good thing.
</p>
        <p>
A couple years ago I wrote an application for a time and attendance device (i.e. a
time clock) that, not surprisingly, stored data about employees, punches, schedules,
etc.  on the device.  It also has the option to store it on a server and
synchronize the data from clock to server, but that’s not core to our discussion today. 
The point is that we were storing a fair bit of data and this was a project I did
right before I create the ORM framework.  It was, in fact, the project that made
it clear to me that I needed to write an ORM.
</p>
        <p>
Just about a month ago the customer wanted to extend the application, adding a couple
features to the time clock that required updates to how the data was stored. 
It took me very little time to realize that the existing DAL code was crap. 
Crap that I architected and wrote.  Sure, it works.  They’ve shipped thousands
of these devices and I’ve heard no complaints and had no bug reports, so functionally
it’s fine and it does exactly what was required.  Nonetheless the code is crap
and here’s why.
</p>
        <p>
First, let’s look at a table class in the DAL, like an Employee (the fat that the
DAL knows about tables is the first indication there’s a problem):
</p>
        <pre class="csharp" name="code">internal class EmployeeTable : Table 
{ 
    public override string Name { get { return "Employees"; } }

    public override ColumnInfo KeyField 
    { 
        get  
        { 
            return new ColumnInfo { Name = "EmployeeID", DataType = SqlDbType.Int }; 
        } 
    }

    internal protected override ColumnInfo[] GetColumnInfo() 
    { 
        return new ColumnInfo[] 
        { 
            KeyField, 
            new ColumnInfo { Name = "BadgeNumber", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "BasePay", DataType = SqlDbType.Money }, 
            new ColumnInfo { Name = "DateOfHire", DataType = SqlDbType.DateTime }, 
            new ColumnInfo { Name = "FirstName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "LastName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            // ... lots more column definitions ... 
        }; 
    }

    public override Index[] GetIndexDefinitions() 
    { 
        return new Index[] 
        { 
            new Index 
            { 
                Name = "IDX_EMPLOYEES_EMPLOYEEID_GUID",  
                SQL = "CREATE INDEX IDX_EMPLOYEES_EMPLOYEEID_GUID ON Employees (EmployeeID, GUID DESC)" 
            }, 
        }; 
    } 
}
</pre>
        <p>
So every table for an entity derives from Table, which looks like this (shorted a
load for brevity in this post):
</p>
        <pre class="csharp" name="code">public abstract class Table : ITable 
{ 
    internal protected abstract ColumnInfo[] GetColumnInfo();

    public abstract string Name { get; } 
    public abstract ColumnInfo KeyField { get; }

    public virtual string GetCreateTableSql() 
    { 
        // default implementation - override for different versions 
        StringBuilder sb = new StringBuilder(); 
        sb.Append(string.Format("CREATE TABLE {0} (", Name));

        ColumnInfo[] infoset = GetColumnInfo(); 
        int i; 
        for (i = 0; i &lt; (infoset.Length - 1); i++) 
        { 
            sb.Append(string.Format("{0},", infoset[i].ToColumnDeclaration())); 
        }

        sb.Append(string.Format("{0}", infoset[i].ToColumnDeclaration())); 
        sb.Append(")");

        return sb.ToString(); 
    }

    public virtual Index[] GetIndexDefinitions() 
    { 
        return null; 
    }

    public virtual IDbCommand GetInsertCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command

        return cmd; 
    }

    public IDbCommand GetUpdateCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }

    public IDbCommand GetDeleteCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }


</pre>
        <p>
Sure, I get a few bonus points for using inheritance so that each table doesn’t have
to do all of this work, but it’s still a pain.  Adding a new Table required that
I understand all of this goo, create the ColumnInfo right, know what the index stuff
is, etc.  And what happens when I need to add a field to an existing table? 
It’s not so clear.
</p>
        <p>
Now how about consuming this from the app?  When the app needs to get an Employee 
you have code like this:
</p>
        <pre class="csharp" name="code">public IEmployee[] GetAllEmployees(IDbConnection connection) 
{ 
    List<IEMPLOYEE>
list = new List<IEMPLOYEE>
(); using (SqlCeCommand command = new SqlCeCommand()) { command.CommandText = EMPLOYEES_SELECT_SQL2;
command.Connection = connection as SqlCeConnection; using (var rs = command.ExecuteResultSet(ResultSetOptions.Scrollable
| ResultSetOptions.Insensitive)) { GetEmployeeFieldOrdinals(rs, false); while (rs.Read())
{ IEmployee employee = EntityService.CreateEmployee(); employee.BadgeNumber = rs.IsDBNull(m_employeeFieldOrdinals["BadgeNumber"])
? null : rs.GetString(m_employeeFieldOrdinals["BadgeNumber"]); employee.BasePay =
rs.IsDBNull(m_employeeFieldOrdinals["EmployeeNumber"]) ? 0 : rs.GetDecimal(m_employeeFieldOrdinals["BasePay"]);
employee.DateOfHire = rs.IsDBNull(m_employeeFieldOrdinals["DateOfHire"]) ? DateTime.MinValue
: rs.GetDateTime(m_employeeFieldOrdinals["DateOfHire"]); employee.EmployeeID = rs.GetInt32(m_employeeFieldOrdinals["EmployeeID"]);
employee.FirstName = rs.GetString(m_employeeFieldOrdinals["FirstName"]); employee.LastName
= rs.GetString(m_employeeFieldOrdinals["LastName"]); string middleInitialStr = !rs.IsDBNull(m_employeeFieldOrdinals["MiddleInitial"])
? rs.GetString(m_employeeFieldOrdinals["MiddleInitial"]) : String.Empty; employee.MiddleInitial
= String.IsNullOrEmpty(middleInitialStr) ? '\0' : middleInitialStr[0]; // on and on
for another 100 lines of code) list.Add(employee); } } } return list.ToArray(); } 
</IEMPLOYEE></IEMPLOYEE></pre>
        <p>
Nevermind the fact that this could be improved a little with GetFields – the big issues
here are that you have to hard-code the SQL to get the data, then you have to parse
the results and fill out the Employee entity instance.  You do this for every
table.  You change a table, you then have to go change the SQL and every method
that touches the table.  The process is error prone, time consuming and just
not fun.  It also makes me uneasy because the test surface area needs to be big. 
How do I ensure that all places that access the table were fixed?  Unit tests
help give me some comfort, but really it has to go through full integration testing
of all features (since Employees are used by just about every feature on the clock).
</p>
        <p>
Now what would the ORM do for me here?  Without going into too much detail on
exactly how to use the ORM (we’ll look at that in another blog entry), let’s just
look at what the ORM version of things would look like.
</p>
        <p>
We’d not have any “Table” crap.  No SQL.  No building Commands and no parsing
Resultsets.  We’d just define an Entity like this:
</p>
        <pre class="csharp" name="code">[Entity] 
internal class Employee 
{ 
    [Field(IsPrimaryKey = true)] 
    public int EmployeeID { get; set; }        
    [Field] 
    public DateTime DateOfHire { get; set; } 
    [Field] 
    public string FirstName { get; set; } 
    [Field] 
    public string LastName { get; set; }

    // etc. 
}
</pre>
        <p>
Note how much cleaner this is than the Table code I had previously.  Also note
that this one class replaces *both* the Table class and the Business Object class. 
So this is much shorter.
</p>
        <p>
What about all of that create table, insert, update and delete SQL and index garbage
I had to know about, write and maintain?  Well, it’s replaced with this:
</p>
        <pre class="csharp" name="code">m_store = new DataStore(databasePath);

if (!m_store.StoreExists) 
{ 
    m_store.CreateStore(); 
}

m_store.AddType&lt;Employee&gt;(); 

</pre>
        <p>
That’s it.  Adding another Entity simply requires adding just one more line of
code – a call to AddType for the new Entity type.  In fact the ORM can auto-detect
all Entity types in an assembly with a single call if you want.  So that’s another
big win.  The base class garbage gets shifted into a framework that’s already
tested.  Less code for me to write means more time to solve my real problems
and less chance for me to add bugs.
</p>
        <p>
What about the long, ugly, unmaintainable query though?  Well that’s where the
ORM really, really pays off.  Getting all Employees becomes stupid simple.
</p>
        <pre class="csharp" name="code">var allEmployees = m_store.Select&lt;Employee&gt;();  </pre>
        <p>
Yep, that’s it. There are overloads that let you do filtering.  There are other
methods that allow you to do paging.  Creates, updates and deletes are similarly
easy.  
</p>
        <p>
Why did I create my own instead of using one that already exists?  Simple – there
isn’t one for the Compact Framework.  I also find that, like many existing IoC
frameworks, they try to be everything to everyone and end up overly complex. 
Another benefit to the OpenNETCF ORM is that it is fully supported on both the Compact
and Full Frameworks, so I can use it in desktop and device projects and not have to
cloud my brain with knowing multiple frameworks.  I even have a partial port
to Windows Phone (it just needs a little time to work around my use of TableDirect
in the SQL Compact implementation).  
</p>
        <p>
Oh, and it’s fast.  Really fast.  Since my initial target was a device with
limited resources, I wrote the code for that environment.  The SQL Compact implementation
avoids using the query parser whenever possible because experience has taught me that
as soon as you write actual SQL, you’re going to pay an order of magnitude performance
penalty (yes, it really is that bad).  It uses TableDirect whenever possible. 
It caches type info so reflection use is kept to a bare minimum.  It caches common
commands so if SQL was necessary, it at least can reuse query plans.
</p>
        <p>
So that’s why I <a href="http://orm.codeplex.com">use an ORM</a>. Doing data access
in any other way has become insanity.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8a41ba23-a3cc-4786-a672-f8d45c2f15be" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Software Development: An Intro to ORMs</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,8a41ba23-a3cc-4786-a672-f8d45c2f15be.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/21/SoftwareDevelopmentAnIntroToORMs.aspx</link>
      <pubDate>Mon, 21 Nov 2011 17:08:06 GMT</pubDate>
      <description>&lt;p&gt;
This post is part of my "Software Development" series. &lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx"&gt;The
TOC for the entire series can be found here&lt;/a&gt;.
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
Let’s start this post with a couple questions.&amp;nbsp; What is an ORM and why would
you use one?&amp;nbsp; If you don’t know the answer to both of these questions, then this
post is for you.&amp;nbsp; If you do know the answers, feel free to skip to the next post
(after I’ve created it of course).
&lt;/p&gt;
&lt;p&gt;
First, let’s look at what an ORM is. And ORM is an object-relational mapping.&amp;nbsp;
According to Wikipedia, which we all know is the infallible and definitive resource
for all knowledge, and ORM is “a &lt;a href="http://en.wikipedia.org/wiki/Computer_programming"&gt;programming&lt;/a&gt; technique
for converting data between incompatible &lt;a href="http://en.wikipedia.org/wiki/Type_system"&gt;type
systems&lt;/a&gt; in &lt;a href="http://en.wikipedia.org/wiki/Object-oriented"&gt;object-oriented&lt;/a&gt; programming
languages.”&amp;nbsp; Ok, what the hell does that mean?&amp;nbsp; My definition is a little
less “scholarly.”&amp;nbsp; I’d say that
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
An ORM is a way to abstract your data storage into simple class objects (POCOs if
you’d like) so that you don’t have to worry about all the crap involved in actually
writing data fields, rows, tables and the like.&amp;nbsp; As a developer, I want to deal
with a “Person” class.&amp;nbsp; I don’t want to think about SQL statements.&amp;nbsp; I don’t
want to have to worry about indexes or tables or even how my “Person” gets stored
to or read from disk.&amp;nbsp; I just want to say “Save this Person instance” and have
it done.&amp;nbsp; THAT is what an ORM is.&amp;nbsp; A framework that lets me concentrate
on solving my business problem instead of spending days writing bullshit, mind-numbing,
error-prone data access layer code.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Why would we use an ORM?&amp;nbsp; I think I’ve been fairly upfront that I consider myself
to be a lazy developer.&amp;nbsp; No, I don’t mean that I take shortcuts or do shoddy
work, I mean that I hate doing things more than once.&amp;nbsp; I hate having to write
reams of code to solve problems that have already been solved.&amp;nbsp; I’ve been writing
applications that consume data for years, and as a consequence, I’ve been writing
data access code for years.&amp;nbsp; If you’re not using an ORM, you probably know down
in your soul that this type of work flat-out sucks.&amp;nbsp; Anything that simplifies
data access to me is a win.
&lt;/p&gt;
&lt;p&gt;
Of course there are other, more tangible benefits as well.&amp;nbsp; If you’re using an
ORM, it’s often possible to swap out data stores – so maybe you could write to SQL
Server then swap a line of two in configuration and write to MySQL or an XML file.&amp;nbsp;
It also allows you to mock things or create stubs to remove data access (really handy
when someone tells you that your data access is what’s slowing things down when you’re
pretty sure it’s not).
&lt;/p&gt;
&lt;p&gt;
I can see that some of you still need convincing.&amp;nbsp; That’s good – you shouldn’t
ever just take someone’s word for it that they know what they’re doing.&amp;nbsp; Ask
for proof.&amp;nbsp; Well let’s look at a case of my own code, why I built the &lt;a href="http://orm.codeplex.com" target=_blank&gt;OpenNETCF
ORM&lt;/a&gt; and how I was recently reminded why it’s a good thing.
&lt;/p&gt;
&lt;p&gt;
A couple years ago I wrote an application for a time and attendance device (i.e. a
time clock) that, not surprisingly, stored data about employees, punches, schedules,
etc.&amp;nbsp; on the device.&amp;nbsp; It also has the option to store it on a server and
synchronize the data from clock to server, but that’s not core to our discussion today.&amp;nbsp;
The point is that we were storing a fair bit of data and this was a project I did
right before I create the ORM framework.&amp;nbsp; It was, in fact, the project that made
it clear to me that I needed to write an ORM.
&lt;/p&gt;
&lt;p&gt;
Just about a month ago the customer wanted to extend the application, adding a couple
features to the time clock that required updates to how the data was stored.&amp;nbsp;
It took me very little time to realize that the existing DAL code was crap.&amp;nbsp;
Crap that I architected and wrote.&amp;nbsp; Sure, it works.&amp;nbsp; They’ve shipped thousands
of these devices and I’ve heard no complaints and had no bug reports, so functionally
it’s fine and it does exactly what was required.&amp;nbsp; Nonetheless the code is crap
and here’s why.
&lt;/p&gt;
&lt;p&gt;
First, let’s look at a table class in the DAL, like an Employee (the fat that the
DAL knows about tables is the first indication there’s a problem):
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;internal class EmployeeTable : Table 
{ 
    public override string Name { get { return "Employees"; } }

    public override ColumnInfo KeyField 
    { 
        get  
        { 
            return new ColumnInfo { Name = "EmployeeID", DataType = SqlDbType.Int }; 
        } 
    }

    internal protected override ColumnInfo[] GetColumnInfo() 
    { 
        return new ColumnInfo[] 
        { 
            KeyField, 
            new ColumnInfo { Name = "BadgeNumber", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "BasePay", DataType = SqlDbType.Money }, 
            new ColumnInfo { Name = "DateOfHire", DataType = SqlDbType.DateTime }, 
            new ColumnInfo { Name = "FirstName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            new ColumnInfo { Name = "LastName", DataType = SqlDbType.NVarChar, Size = 50 }, 
            // ... lots more column definitions ... 
        }; 
    }

    public override Index[] GetIndexDefinitions() 
    { 
        return new Index[] 
        { 
            new Index 
            { 
                Name = "IDX_EMPLOYEES_EMPLOYEEID_GUID",  
                SQL = "CREATE INDEX IDX_EMPLOYEES_EMPLOYEEID_GUID ON Employees (EmployeeID, GUID DESC)" 
            }, 
        }; 
    } 
}
&lt;/pre&gt;
&lt;p&gt;
So every table for an entity derives from Table, which looks like this (shorted a
load for brevity in this post):
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public abstract class Table : ITable 
{ 
    internal protected abstract ColumnInfo[] GetColumnInfo();

    public abstract string Name { get; } 
    public abstract ColumnInfo KeyField { get; }

    public virtual string GetCreateTableSql() 
    { 
        // default implementation - override for different versions 
        StringBuilder sb = new StringBuilder(); 
        sb.Append(string.Format("CREATE TABLE {0} (", Name));

        ColumnInfo[] infoset = GetColumnInfo(); 
        int i; 
        for (i = 0; i &amp;lt; (infoset.Length - 1); i++) 
        { 
            sb.Append(string.Format("{0},", infoset[i].ToColumnDeclaration())); 
        }

        sb.Append(string.Format("{0}", infoset[i].ToColumnDeclaration())); 
        sb.Append(")");

        return sb.ToString(); 
    }

    public virtual Index[] GetIndexDefinitions() 
    { 
        return null; 
    }

    public virtual IDbCommand GetInsertCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command

        return cmd; 
    }

    public IDbCommand GetUpdateCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }

    public IDbCommand GetDeleteCommand() 
    { 
        SqlCeCommand cmd = new SqlCeCommand(); 

        // long, manual generation of the SQL and then creating the command 

        return cmd; 
    }


&lt;/pre&gt;
&lt;p&gt;
Sure, I get a few bonus points for using inheritance so that each table doesn’t have
to do all of this work, but it’s still a pain.&amp;nbsp; Adding a new Table required that
I understand all of this goo, create the ColumnInfo right, know what the index stuff
is, etc.&amp;nbsp; And what happens when I need to add a field to an existing table?&amp;nbsp;
It’s not so clear.
&lt;/p&gt;
&lt;p&gt;
Now how about consuming this from the app?&amp;nbsp; When the app needs to get an Employee&amp;nbsp;
you have code like this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public IEmployee[] GetAllEmployees(IDbConnection connection) 
{ 
    List&lt;IEMPLOYEE&gt;
list = new List&lt;IEMPLOYEE&gt;
(); using (SqlCeCommand command = new SqlCeCommand()) { command.CommandText = EMPLOYEES_SELECT_SQL2;
command.Connection = connection as SqlCeConnection; using (var rs = command.ExecuteResultSet(ResultSetOptions.Scrollable
| ResultSetOptions.Insensitive)) { GetEmployeeFieldOrdinals(rs, false); while (rs.Read())
{ IEmployee employee = EntityService.CreateEmployee(); employee.BadgeNumber = rs.IsDBNull(m_employeeFieldOrdinals["BadgeNumber"])
? null : rs.GetString(m_employeeFieldOrdinals["BadgeNumber"]); employee.BasePay =
rs.IsDBNull(m_employeeFieldOrdinals["EmployeeNumber"]) ? 0 : rs.GetDecimal(m_employeeFieldOrdinals["BasePay"]);
employee.DateOfHire = rs.IsDBNull(m_employeeFieldOrdinals["DateOfHire"]) ? DateTime.MinValue
: rs.GetDateTime(m_employeeFieldOrdinals["DateOfHire"]); employee.EmployeeID = rs.GetInt32(m_employeeFieldOrdinals["EmployeeID"]);
employee.FirstName = rs.GetString(m_employeeFieldOrdinals["FirstName"]); employee.LastName
= rs.GetString(m_employeeFieldOrdinals["LastName"]); string middleInitialStr = !rs.IsDBNull(m_employeeFieldOrdinals["MiddleInitial"])
? rs.GetString(m_employeeFieldOrdinals["MiddleInitial"]) : String.Empty; employee.MiddleInitial
= String.IsNullOrEmpty(middleInitialStr) ? '\0' : middleInitialStr[0]; // on and on
for another 100 lines of code) list.Add(employee); } } } return list.ToArray(); } 
&lt;/pre&gt;
&lt;p&gt;
Nevermind the fact that this could be improved a little with GetFields – the big issues
here are that you have to hard-code the SQL to get the data, then you have to parse
the results and fill out the Employee entity instance.&amp;nbsp; You do this for every
table.&amp;nbsp; You change a table, you then have to go change the SQL and every method
that touches the table.&amp;nbsp; The process is error prone, time consuming and just
not fun.&amp;nbsp; It also makes me uneasy because the test surface area needs to be big.&amp;nbsp;
How do I ensure that all places that access the table were fixed?&amp;nbsp; Unit tests
help give me some comfort, but really it has to go through full integration testing
of all features (since Employees are used by just about every feature on the clock).
&lt;/p&gt;
&lt;p&gt;
Now what would the ORM do for me here?&amp;nbsp; Without going into too much detail on
exactly how to use the ORM (we’ll look at that in another blog entry), let’s just
look at what the ORM version of things would look like.
&lt;/p&gt;
&lt;p&gt;
We’d not have any “Table” crap.&amp;nbsp; No SQL.&amp;nbsp; No building Commands and no parsing
Resultsets.&amp;nbsp; We’d just define an Entity like this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;[Entity] 
internal class Employee 
{ 
    [Field(IsPrimaryKey = true)] 
    public int EmployeeID { get; set; }        
    [Field] 
    public DateTime DateOfHire { get; set; } 
    [Field] 
    public string FirstName { get; set; } 
    [Field] 
    public string LastName { get; set; }

    // etc. 
}
&lt;/pre&gt;
&lt;p&gt;
Note how much cleaner this is than the Table code I had previously.&amp;nbsp; Also note
that this one class replaces *both* the Table class and the Business Object class.&amp;nbsp;
So this is much shorter.
&lt;/p&gt;
&lt;p&gt;
What about all of that create table, insert, update and delete SQL and index garbage
I had to know about, write and maintain?&amp;nbsp; Well, it’s replaced with this:
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;m_store = new DataStore(databasePath);

if (!m_store.StoreExists) 
{ 
    m_store.CreateStore(); 
}

m_store.AddType&amp;lt;Employee&amp;gt;(); 

&lt;/pre&gt;
&lt;p&gt;
That’s it.&amp;nbsp; Adding another Entity simply requires adding just one more line of
code – a call to AddType for the new Entity type.&amp;nbsp; In fact the ORM can auto-detect
all Entity types in an assembly with a single call if you want.&amp;nbsp; So that’s another
big win.&amp;nbsp; The base class garbage gets shifted into a framework that’s already
tested.&amp;nbsp; Less code for me to write means more time to solve my real problems
and less chance for me to add bugs.
&lt;/p&gt;
&lt;p&gt;
What about the long, ugly, unmaintainable query though?&amp;nbsp; Well that’s where the
ORM really, really pays off.&amp;nbsp; Getting all Employees becomes stupid simple.
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var allEmployees = m_store.Select&amp;lt;Employee&amp;gt;();&amp;nbsp; &lt;/pre&gt;
&lt;p&gt;
Yep, that’s it. There are overloads that let you do filtering.&amp;nbsp; There are other
methods that allow you to do paging.&amp;nbsp; Creates, updates and deletes are similarly
easy.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Why did I create my own instead of using one that already exists?&amp;nbsp; Simple – there
isn’t one for the Compact Framework.&amp;nbsp; I also find that, like many existing IoC
frameworks, they try to be everything to everyone and end up overly complex.&amp;nbsp;
Another benefit to the OpenNETCF ORM is that it is fully supported on both the Compact
and Full Frameworks, so I can use it in desktop and device projects and not have to
cloud my brain with knowing multiple frameworks.&amp;nbsp; I even have a partial port
to Windows Phone (it just needs a little time to work around my use of TableDirect
in the SQL Compact implementation).&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
Oh, and it’s fast.&amp;nbsp; Really fast.&amp;nbsp; Since my initial target was a device with
limited resources, I wrote the code for that environment.&amp;nbsp; The SQL Compact implementation
avoids using the query parser whenever possible because experience has taught me that
as soon as you write actual SQL, you’re going to pay an order of magnitude performance
penalty (yes, it really is that bad).&amp;nbsp; It uses TableDirect whenever possible.&amp;nbsp;
It caches type info so reflection use is kept to a bare minimum.&amp;nbsp; It caches common
commands so if SQL was necessary, it at least can reuse query plans.
&lt;/p&gt;
&lt;p&gt;
So that’s why I &lt;a href="http://orm.codeplex.com"&gt;use an ORM&lt;/a&gt;. Doing data access
in any other way has become insanity.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=8a41ba23-a3cc-4786-a672-f8d45c2f15be" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.ORM</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=c9881bdf-f2b9-444e-ae3e-fd4ab0328a67</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,c9881bdf-f2b9-444e-ae3e-fd4ab0328a67.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
REST web services are pretty straightforward and really, really common (you used one
to read this blog page).  As software gets implemented as services, it's getting
more and more common for us as developers to have to make REST calls programmatically. 
Lately I've been implementing a lot of services using Padarn on both the device and
the PC and then implementing client libraries to access those services.  In doing
so, it only made sense to create some infrastructure to make my life a little easier,
and so the RestConnector (and DigestRestConnector) was born.
</p>
        <p>
For a simple GET, such as to get the response for this page, the code is trivial:
</p>
        <p>
 
</p>
        <pre class="csharp" name="code">var connector = new RestConnector("blog.opennetcf.com");
var response = connector.Get("/ctacke");
</pre>
        <p>
Other verbs like POST and PUT are nearly as simple.
</p>
        <pre class="csharp" name="code">var response = connector.Post("/upload", myData);</pre>
        <p>
For services that require authentication, there's the DigestRestConnector that behaves
the same, except the ctor takes in a UID/PWD pair as well. The classes support the
four common verbs I use: GET, PUT, POST and DELETE. Of course since it's open-source,
feel free to extend them as you wish. 
</p>
        <p>
          <hr />
        </p>
        <p>
The <a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com"><strong><font color="#4682b4">OpenNETCF
Extensions library</font></strong></a> is a collection of extension methods and helper
classes that I find useful in a lot of different projects. It's compatible with the
Compact Framework, Tirethe full framework and Windows Phone.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c9881bdf-f2b9-444e-ae3e-fd4ab0328a67" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF Extensions: Making a REST service call</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,c9881bdf-f2b9-444e-ae3e-fd4ab0328a67.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/16/OpenNETCFExtensionsMakingARESTServiceCall.aspx</link>
      <pubDate>Wed, 16 Nov 2011 15:27:40 GMT</pubDate>
      <description>&lt;p&gt;
REST web services are pretty straightforward and really, really common (you used one
to read this blog page).&amp;nbsp; As software gets implemented as services, it's getting
more and more common for us as developers to have to make REST calls programmatically.&amp;nbsp;
Lately I've been implementing a lot of services using Padarn on both the device and
the PC and then implementing client libraries to access those services.&amp;nbsp; In doing
so, it only made sense to create some infrastructure to make my life a little easier,
and so the RestConnector (and DigestRestConnector) was born.
&lt;/p&gt;
&lt;p&gt;
For a simple GET, such as to get the response for this page, the code is trivial:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var connector = new RestConnector("blog.opennetcf.com");
var response = connector.Get("/ctacke");
&lt;/pre&gt;
&lt;p&gt;
Other verbs like POST and PUT are nearly as simple.
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var response = connector.Post("/upload", myData);&lt;/pre&gt;
&lt;p&gt;
For services that require authentication, there's the DigestRestConnector that behaves
the same, except the ctor takes in a UID/PWD pair as well. The classes support the
four common verbs I use: GET, PUT, POST and DELETE. Of course since it's open-source,
feel free to extend them as you wish. 
&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com"&gt;&lt;strong&gt;&lt;font color=#4682b4&gt;OpenNETCF
Extensions library&lt;/font&gt;&lt;/strong&gt;&lt;/a&gt; is a collection of extension methods and helper
classes that I find useful in a lot of different projects. It's compatible with the
Compact Framework, Tirethe full framework and Windows Phone.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c9881bdf-f2b9-444e-ae3e-fd4ab0328a67" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF Extensions</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=a2387b57-0ab5-4339-b5dd-90e0be2edf62</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,a2387b57-0ab5-4339-b5dd-90e0be2edf62.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Transferring data between processes in Windows CE is not difficult, and you can avoid
using passing data through the message pump using WM_COPYDATA (which I've never
considered a good idea, BTW).  Sockets and point to point queues are pretty straightforward
and well documented for IPC.  
</p>
        <p>
One mechanism that isn't well covered, and that works well for sharing larger blobs
of data, is a memory-mapped file.  The SDF contains a MemoryMappedFile class
(in the OpenNETCF.IO namespace) that allows you to use a shared memory region (in
ram or on disk - your choice) and to access it just like you would any other stream
with Write, Read and Seek.  Here's a simple example. Yes I realize my synchronization
mechanism here isn't the cleanest, but it conveys the idea with the least code.
</p>
        <p>
 
</p>
        <pre class="csharp" name="code">using System;
using System.Text;
using OpenNETCF.IO;
using OpenNETCF.Threading;
using System.Diagnostics;
using System.Reflection;
using System.IO;

namespace MMFPeer
{
    class Program
    {
        public const string SharedMapName = "MMF_PEER_NAME";
        public const long MaxMapSize = 1024;
        public const string SharedMutexName = "MMF_PEER_MUTEX";
        public const string DataReadyEventName = "MMF_PEER_DATA_READY";

        private MemoryMappedFile m_mmf;
        private NamedMutex m_mutex;
        private EventWaitHandle m_dataReady;

        private bool Sending { get; set; }

        static void Main(string[] args)
        {
            new Program().Run();
        }

        public void Run()
        {
            var processName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().GetName().CodeBase);

            // create the MMF
            m_mmf = MemoryMappedFile.CreateInMemoryMap(SharedMapName, MaxMapSize);

            // create a shared mutex
            m_mutex = new NamedMutex(false, SharedMutexName);

            // create a data-ready event
            m_dataReady = new EventWaitHandle(false, EventResetMode.ManualReset, DataReadyEventName);

            // fire up a "listener"
            new System.Threading.Thread(ReadProc)
            {
                IsBackground = true,
                Name = "MMF Peer Reader"
            }
            .Start();

            Console.WriteLine("Memory Mapped File Created.  Enter text to send to peer(s)");

            // wait for user input
            while (true)
            {
                var input = Console.ReadLine();

                if (input == null)
                {
                    Thread2.Sleep(5000);
                    input = GetMockInput();
                    Debug.WriteLine(string.Format("Platform does not have a Console installed. Sending mock data '{0}'", input));
                }

                if (input == "exit") break;

                // prefix our process name so we can tell who sent the data
                input = processName + ":" + input;

                // grab the mutex
                if (!m_mutex.WaitOne(5000, false))
                {
                    Console.WriteLine("Unable to acquire mutex.  Send Abandoned");
                    Debug.WriteLine("Unable to acquire mutex.  Send Abandoned");
                    continue;
                }

                // mark as "sending" so the listener will ignore what we send
                Sending = true;

                // create a "packet" (length + data)
                var packet = new byte[4 + input.Length];
                Buffer.BlockCopy(BitConverter.GetBytes(input.Length), 0, packet, 0, 4);
                Buffer.BlockCopy(Encoding.ASCII.GetBytes(input), 0, packet, 4, input.Length);

                // write the packet at the start
                m_mmf.Seek(0, System.IO.SeekOrigin.Begin);
                m_mmf.Write(packet, 0, packet.Length);

                // notify all clients that data is ready (manual reset events will release all waiting clients)
                m_dataReady.Set();

                // yield to allow the receiver to unblock and check the "Sending" flag
                Thread2.Sleep(1);

                // reset the event
                m_dataReady.Reset();

                // unmark "sending" 
                Sending = false;

                // release the mutex
                m_mutex.ReleaseMutex();
            }            
        }

        private int m_inputIndex = -1;
        private string[] m_inputs = new string[]
            {
                "Hello",
                "World"
            };

        private string GetMockInput()
        {
            if (++m_inputIndex &gt;= m_inputs.Length) m_inputIndex = 0;
            return m_inputs[m_inputIndex];
        }

        private void ReadProc()
        {
            var lengthBuffer = new byte[4];
            var dataBuffer = new byte[m_mmf.Length - 4];

            while (true)
            {
                // use a timeout so if the app ends, this thread can exit
                if(!m_dataReady.WaitOne(1000, false)) continue;

                // avoid receiving our own data
                if (Sending)
                {
                    // wait long enough for the sender to reset the m_dataReady flag
                    Thread2.Sleep(5);
                    continue;
                }

                // grab the mutex to prevent concurrency issues
                m_mutex.WaitOne(1000, false);

                // read from the start
                m_mmf.Seek(0, System.IO.SeekOrigin.Begin);

                // get the length
                m_mmf.Read(lengthBuffer, 0, 4);
                var length = BitConverter.ToInt32(lengthBuffer, 0);

                // get the data
                m_mmf.Read(dataBuffer, 0, length);

                // release the mutex so any other clients can receive
                m_mutex.ReleaseMutex();

                // convert to a string
                var received = Encoding.ASCII.GetString(dataBuffer, 0, length);

                Console.WriteLine("Received: " + received);
                Debug.WriteLine("Received: " + received);
            }
        }
    }
}
</pre>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=a2387b57-0ab5-4339-b5dd-90e0be2edf62" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>SDF Sample: IPC with Memory Mapped Files</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,a2387b57-0ab5-4339-b5dd-90e0be2edf62.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/15/SDFSampleIPCWithMemoryMappedFiles.aspx</link>
      <pubDate>Tue, 15 Nov 2011 18:18:09 GMT</pubDate>
      <description>&lt;p&gt;
Transferring data between processes in Windows CE is not difficult, and you can avoid
using passing data through the message pump&amp;nbsp;using WM_COPYDATA (which I've never
considered a good idea, BTW).&amp;nbsp; Sockets and point to point queues are pretty straightforward
and well documented for IPC.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
One mechanism that isn't well covered, and that works well for sharing larger blobs
of data, is a memory-mapped file.&amp;nbsp; The SDF contains a MemoryMappedFile class
(in the OpenNETCF.IO namespace) that allows you to use a shared memory region (in
ram or on disk - your choice) and to access it just like you would any other stream
with Write, Read and Seek.&amp;nbsp; Here's a simple example. Yes I realize my synchronization
mechanism here isn't the cleanest, but it conveys the idea with the least code.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;using System;
using System.Text;
using OpenNETCF.IO;
using OpenNETCF.Threading;
using System.Diagnostics;
using System.Reflection;
using System.IO;

namespace MMFPeer
{
    class Program
    {
        public const string SharedMapName = "MMF_PEER_NAME";
        public const long MaxMapSize = 1024;
        public const string SharedMutexName = "MMF_PEER_MUTEX";
        public const string DataReadyEventName = "MMF_PEER_DATA_READY";

        private MemoryMappedFile m_mmf;
        private NamedMutex m_mutex;
        private EventWaitHandle m_dataReady;

        private bool Sending { get; set; }

        static void Main(string[] args)
        {
            new Program().Run();
        }

        public void Run()
        {
            var processName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().GetName().CodeBase);

            // create the MMF
            m_mmf = MemoryMappedFile.CreateInMemoryMap(SharedMapName, MaxMapSize);

            // create a shared mutex
            m_mutex = new NamedMutex(false, SharedMutexName);

            // create a data-ready event
            m_dataReady = new EventWaitHandle(false, EventResetMode.ManualReset, DataReadyEventName);

            // fire up a "listener"
            new System.Threading.Thread(ReadProc)
            {
                IsBackground = true,
                Name = "MMF Peer Reader"
            }
            .Start();

            Console.WriteLine("Memory Mapped File Created.  Enter text to send to peer(s)");

            // wait for user input
            while (true)
            {
                var input = Console.ReadLine();

                if (input == null)
                {
                    Thread2.Sleep(5000);
                    input = GetMockInput();
                    Debug.WriteLine(string.Format("Platform does not have a Console installed. Sending mock data '{0}'", input));
                }

                if (input == "exit") break;

                // prefix our process name so we can tell who sent the data
                input = processName + ":" + input;

                // grab the mutex
                if (!m_mutex.WaitOne(5000, false))
                {
                    Console.WriteLine("Unable to acquire mutex.  Send Abandoned");
                    Debug.WriteLine("Unable to acquire mutex.  Send Abandoned");
                    continue;
                }

                // mark as "sending" so the listener will ignore what we send
                Sending = true;

                // create a "packet" (length + data)
                var packet = new byte[4 + input.Length];
                Buffer.BlockCopy(BitConverter.GetBytes(input.Length), 0, packet, 0, 4);
                Buffer.BlockCopy(Encoding.ASCII.GetBytes(input), 0, packet, 4, input.Length);

                // write the packet at the start
                m_mmf.Seek(0, System.IO.SeekOrigin.Begin);
                m_mmf.Write(packet, 0, packet.Length);

                // notify all clients that data is ready (manual reset events will release all waiting clients)
                m_dataReady.Set();

                // yield to allow the receiver to unblock and check the "Sending" flag
                Thread2.Sleep(1);

                // reset the event
                m_dataReady.Reset();

                // unmark "sending" 
                Sending = false;

                // release the mutex
                m_mutex.ReleaseMutex();
            }            
        }

        private int m_inputIndex = -1;
        private string[] m_inputs = new string[]
            {
                "Hello",
                "World"
            };

        private string GetMockInput()
        {
            if (++m_inputIndex &amp;gt;= m_inputs.Length) m_inputIndex = 0;
            return m_inputs[m_inputIndex];
        }

        private void ReadProc()
        {
            var lengthBuffer = new byte[4];
            var dataBuffer = new byte[m_mmf.Length - 4];

            while (true)
            {
                // use a timeout so if the app ends, this thread can exit
                if(!m_dataReady.WaitOne(1000, false)) continue;

                // avoid receiving our own data
                if (Sending)
                {
                    // wait long enough for the sender to reset the m_dataReady flag
                    Thread2.Sleep(5);
                    continue;
                }

                // grab the mutex to prevent concurrency issues
                m_mutex.WaitOne(1000, false);

                // read from the start
                m_mmf.Seek(0, System.IO.SeekOrigin.Begin);

                // get the length
                m_mmf.Read(lengthBuffer, 0, 4);
                var length = BitConverter.ToInt32(lengthBuffer, 0);

                // get the data
                m_mmf.Read(dataBuffer, 0, length);

                // release the mutex so any other clients can receive
                m_mutex.ReleaseMutex();

                // convert to a string
                var received = Encoding.ASCII.GetString(dataBuffer, 0, length);

                Console.WriteLine("Received: " + received);
                Debug.WriteLine("Received: " + received);
            }
        }
    }
}
&lt;/pre&gt;&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=a2387b57-0ab5-4339-b5dd-90e0be2edf62" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>SDF Samples</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=78a010ec-5513-40bc-80b5-b79de2f27ebb</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,78a010ec-5513-40bc-80b5-b79de2f27ebb.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
There has been rampant speculation for some time that Windows CE was dead and that
Microsoft was abandoning it.  The announcement that Windows 8 will run on ARM
only added fuel to it, despite the fact that Win8 is undoubtedly going to have a large,
desktop-style footprint and no capability for real-time operation.  Well, Microsoft
finally decided to tell us what many of us suspected for some time.  Windows
Embedded Compact (i.e. Windows CE) is still on their product roadmap.  It will
have a v Next, and it will be supported in newer versions of Visual Studio (well native
development will be anyway).  <a href="http://www.microsoft.com/Presspass/Features/2011/nov11/11-14RoadMap.mspx">Read
the full press release here</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=78a010ec-5513-40bc-80b5-b79de2f27ebb" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>I told you Windows CE wasn't dead</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,78a010ec-5513-40bc-80b5-b79de2f27ebb.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/14/IToldYouWindowsCEWasntDead.aspx</link>
      <pubDate>Mon, 14 Nov 2011 19:41:15 GMT</pubDate>
      <description>&lt;p&gt;
There has been rampant speculation for some time that Windows CE was dead and that
Microsoft was abandoning it.&amp;nbsp; The announcement that Windows 8 will run on ARM
only added fuel to it, despite the fact that Win8 is undoubtedly going to have a large,
desktop-style footprint and no capability for real-time operation.&amp;nbsp; Well, Microsoft
finally decided to tell us what many of us suspected for some time.&amp;nbsp; Windows
Embedded Compact (i.e. Windows CE) is still on their product roadmap.&amp;nbsp; It will
have a v Next, and it will be supported in newer versions of Visual Studio (well native
development will be anyway).&amp;nbsp; &lt;a href="http://www.microsoft.com/Presspass/Features/2011/nov11/11-14RoadMap.mspx"&gt;Read
the full press release here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=78a010ec-5513-40bc-80b5-b79de2f27ebb" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>CE Device Development</category>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=ca82515c-a2b8-4a96-99de-8ad82738887a</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,ca82515c-a2b8-4a96-99de-8ad82738887a.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
With the upcoming <a href="http://www.mtconnectconference.org/">MTConnect conference
next week</a>, we've been extremely busy getting things ready for <a href="http://www.mtconnectconference.org/event-schedule/">our
talks</a> as well as our booth on the show floor.  I think we got feature complete
(at least as far as we want for the show) today, so I'm merged all of the latest changes
into the public trees for both the <a href="http://mtconnect.codeplex.com">MTConnect Managed
SDK</a> as well as the <a href="http://mtcagent.codeplex.com">OpenNETCF Virtual
Agent</a>.  I have an updated Machine Simulator that we'll be using for the show,
but it's not quite ready for public consumption, so the release of that will have
to wait until after we get back from Cincinnati.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ca82515c-a2b8-4a96-99de-8ad82738887a" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>MTConnect Library Updates</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,ca82515c-a2b8-4a96-99de-8ad82738887a.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/04/MTConnectLibraryUpdates.aspx</link>
      <pubDate>Fri, 04 Nov 2011 22:07:11 GMT</pubDate>
      <description>&lt;p&gt;
With the upcoming &lt;a href="http://www.mtconnectconference.org/"&gt;MTConnect conference
next week&lt;/a&gt;, we've been extremely busy getting things ready for &lt;a href="http://www.mtconnectconference.org/event-schedule/"&gt;our
talks&lt;/a&gt; as well as our booth on the show floor.&amp;nbsp; I think we got feature complete
(at least as far as we want for the show) today, so I'm merged all of the latest changes
into the public trees for both the &lt;a href="http://mtconnect.codeplex.com"&gt;MTConnect&amp;nbsp;Managed
SDK&lt;/a&gt; as well as the &lt;a href="http://mtcagent.codeplex.com"&gt;OpenNETCF&amp;nbsp;Virtual
Agent&lt;/a&gt;.&amp;nbsp; I have an updated Machine Simulator that we'll be using for the show,
but it's not quite ready for public consumption, so the release of that will have
to wait until after we get back from Cincinnati.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ca82515c-a2b8-4a96-99de-8ad82738887a" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=d7f3338c-e439-450e-a15a-d81553ac25e0</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,d7f3338c-e439-450e-a15a-d81553ac25e0.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Marshaling UI access to the proper thread is a very common task in app development,
yet it still tends to be a pain in the ass.  You have to check if InvokeRequired
is true (well you probably don’t *have* to, but not doing it feels dirty to me) and
even using an <a href="http://blog.opennetcf.com/ctacke/2008/12/03/ControlInvokeWithoutExplicitDelegates.aspx" target="_blank">anonymous
delegate</a> tends to be verbose.  And then there are also the simple bugs that
are <a href="http://stackoverflow.com/questions/7989332/control-invoke-delegates-in-cf-3-5/7989489#7989489" target="_blank">not
always easy to spot</a>.
</p>
        <p>
So, like any good developer, I stole <a href="http://stackoverflow.com/questions/2367718/c-automating-the-invokerequired-code-pattern" target="_blank">someone
else’s idea</a> and put it into the <a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com">OpenNETCF
Extensions</a>.  Now, instead of doing this:
</p>
        <pre class="csharp" name="code">void MyMethod()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new EventHandler(delegate
            {
                MyMethod();
            }));
        return;
    }

    // do stuff with the UI
}</pre>
        <p>
You do this:
</p>
        <pre class="csharp" name="code">void MyMethod()
{
    Invoker.InvokeIfRequired(i =&gt;
    {
        // do stuff with the UI
    });
}</pre>
        <p>
Less code.  Less potential for error.  More readable.  What’s not to
like?
</p>
        <hr />
        <p>
The <a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com">OpenNETCF Extensions
library</a> is a collection of extension methods and helper classes that I find useful
in a lot of different projects. It's compatible with the Compact Framework, Tirethe
full framework and Windows Phone.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d7f3338c-e439-450e-a15a-d81553ac25e0" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF Extensions: Eliminating Control.Invoke</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,d7f3338c-e439-450e-a15a-d81553ac25e0.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/04/OpenNETCFExtensionsEliminatingControlInvoke.aspx</link>
      <pubDate>Fri, 04 Nov 2011 18:10:04 GMT</pubDate>
      <description>&lt;p&gt;
Marshaling UI access to the proper thread is a very common task in app development,
yet it still tends to be a pain in the ass.&amp;#160; You have to check if InvokeRequired
is true (well you probably don’t *have* to, but not doing it feels dirty to me) and
even using an &lt;a href="http://blog.opennetcf.com/ctacke/2008/12/03/ControlInvokeWithoutExplicitDelegates.aspx" target="_blank"&gt;anonymous
delegate&lt;/a&gt; tends to be verbose.&amp;#160; And then there are also the simple bugs that
are &lt;a href="http://stackoverflow.com/questions/7989332/control-invoke-delegates-in-cf-3-5/7989489#7989489" target="_blank"&gt;not
always easy to spot&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So, like any good developer, I stole &lt;a href="http://stackoverflow.com/questions/2367718/c-automating-the-invokerequired-code-pattern" target="_blank"&gt;someone
else’s idea&lt;/a&gt; and put it into the &lt;a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com"&gt;OpenNETCF
Extensions&lt;/a&gt;.&amp;#160; Now, instead of doing this:
&lt;/p&gt;
&lt;pre class="csharp" name="code"&gt;void MyMethod()
{
    if (this.InvokeRequired)
    {
        this.Invoke(new EventHandler(delegate
            {
                MyMethod();
            }));
        return;
    }

    // do stuff with the UI
}&lt;/pre&gt;
&lt;p&gt;
You do this:
&lt;/p&gt;
&lt;pre class="csharp" name="code"&gt;void MyMethod()
{
    Invoker.InvokeIfRequired(i =&amp;gt;
    {
        // do stuff with the UI
    });
}&lt;/pre&gt;
&lt;p&gt;
Less code.&amp;#160; Less potential for error.&amp;#160; More readable.&amp;#160; What’s not to
like?
&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;
The &lt;a href="http://blog.opennetcf.com/ctacke/oncfext.codeplex.com"&gt;OpenNETCF Extensions
library&lt;/a&gt; is a collection of extension methods and helper classes that I find useful
in a lot of different projects. It's compatible with the Compact Framework, Tirethe
full framework and Windows Phone.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d7f3338c-e439-450e-a15a-d81553ac25e0" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>OpenNETCF Extensions</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=165f4077-cd46-4b7c-b1b6-27ff0e714fc9</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,165f4077-cd46-4b7c-b1b6-27ff0e714fc9.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is part of my "Software Development" series. <a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx">The
TOC for the entire series can be found here</a>.
</p>
        <hr />
        <p>
In this post, we’re going to look, at a higher level, at the reasons for and benefits
of using a framework for Inversion of Control (IoC), Dependency Injection (DI) and
Service Location. I’m not going to spend a large amount of time in this blog series
describing the intimate details of what IoC, DI and Service Locators are.  <a href="http://martinfowler.com/articles/injection.html#InversionOfControl" target="_blank">Martin
Fowler did a fantastic job of it</a> and there’s no point in me just regurgitating
his work.
</p>
        <p>
Instead, I’ll give my vision of what they are and how they are relevant to how I architect
and develop solutions.  It’s important to note that I’m starting out this series
with high-level thoughts about architecture and design.  I’m not just laying
down some code, leaving the decisions about how things will interact to some arbitrary,
organic process.  This is how software development gets done.  
</p>
        <p>
You’ve got to think about not just the next step, but visualize the end point several
months, or even years out and try to connect the dots back to where you are today. 
If I implement something in a certain way today, is it going to screw me 3 months
down the road?  Spending an extra day now thinking about architecture is going
to turn into saving weeks of the customer breathing down your neck and you pull out
your hair and work late night trying to hammer a square peg into a round hole.
</p>
        <p>
So let’s look at IoC, DI and Service Location and how they’re going to help us build
better software.  Inversion of Control as a concept is something that’s really
broad.  It’s really anything that turns the older procedural way of developing
upside down (i.e. inverts program control, hence the name).  Moving from a console
app to a windowed, event-driven app is technically inversion of control, so you’ve
already been using IoC.  
</p>
        <p>
To talk about IoC as a useful concept that’s actually going to be of use, we’ll be
using some smaller units/principals of IoC.  The two we’re going to look at are
Dependency Injection, or DI, and Service Location.  Neither one is complex or
arcane, and you probably already use them to some degree.
</p>
        <p>
Let’s assume we have two arbitrary classes, <strong>A</strong> and <strong>B</strong>,
and that A uses an instance of B internally.  There are, essentially, 3 ways
that A can get the instance of B.  
</p>
        <p>
First, it can directly create it by calling new B().  While this is simple, it’s
the least preferred, and generally worst, way to do it.  By directly creating
B, A is now tightly coupled to B’s implementation.  B can’t be easily changed
out to something else.  If B is in another assembly, A has to have a reference
to it.  It’s also difficult to test A by itself.  
</p>
        <p>
The second way that A can get B is that whoever created the instance of A could pass
into it an instance of B.  Maybe through a constructor
</p>
        <pre class="csharp" name="code">var b = new B();
var a = new A(b);</pre>
        <p>
or through a property
</p>
        <pre class="csharp" name="code">var b = new B(); 
var a = new A(); 
a.B = b;</pre>
        <p>
This is called Dependency Injection. The former is constructor injection, the latter
is property injection – not so complex, eh?  This is useful because, if B is
an interface, it’s really easy to swap out the implementation passed to A and the
assembly containing A doesn’t necessarily have to have a reference to the assembly
holding the implementation of B – it only needs a reference to the interface. 
This is really nice when we want to do mocking.
</p>
        <p>
The third way that A can get B is to go get it from some central repository or “factory”.
</p>
        <pre class="csharp" name="code">B B { get; set; }

public A() 
{ 
   this.B = MyClassFactory.GetB(); 
}</pre>
        <p>
This is service location.  A doesn’t really know what B is, it lets the service
locator (MyClassFactory) resolve that.  This is really helpful for plug-in architectures
as well as for lazy loading objects.
</p>
        <p>
Generally speaking, your code should only be doing #2 (DI) and #3 (service location)
for objects of any complexity.  This is not to say that you shouldn’t ever call
the new operator in your code.  There’s obviously a grey line out there below
which it would be pretty stupid to not just use <strong>new</strong> for.  If
you need to use a simple entity class or structure, then creating one makes sense. 
If you need access to the DAL and I see you creating a DAL object in your View, you’re
fired.
</p>
        <p>
There are plenty of framework out there that provide DI and service location -  <a href="http://ninject.org/" target="_blank">Ninject</a>, <a href="http://msdn.microsoft.com/en-us/library/ff648512.aspx" target="_blank">Unity</a>, <a href="http://www.castleproject.org/" target="_blank">CastleWindsor</a>, <a href="http://structuremap.net/structuremap/" target="_blank">StructureMap</a>, <a href="http://code.google.com/p/autofac/" target="_blank">Autofac</a> –
the list goes on and on.  Instead of using one of them, however, I chose to roll
my own.  Normally I wouldn’t recommend such a drastic action – after all reinventing
the wheel isn’t usually wise – but in my case it was essentially required, so I’ll
give you the short back story.
</p>
        <p>
My team and I had been working on a large desktop application.  We had designed
it from the start using <a href="http://smartclient.codeplex.com/" target="_blank">Microsoft’s
SCSF/CAB</a> framework, which provide DI, service location and a load of other stuff. 
It turned out that we were using maybe 10% of the framework, and that the framework’s
Studio plug-ins were causing fits with some installations of Studio.  Spending
time screwing with Studio plug-ins and trying to get things to compile is a terrible
waste of manpower, so we were already getting close to jettisoning it when we decided
that we wanted the core of our app logic to be Compact Framework compatible.
</p>
        <p>
Well Microsoft’s “port” of the SCSF to the Compact Framework, called the <a href="http://mobile.codeplex.com/" target="_blank">MCSF</a>,
turns out to be a bloated, unbelievably slow, steaming pile of dog crap.  Side
note: just because something <em>compiles</em> under the Compact Framework <em>does
not</em> mean it should be used in the Compact Framework.  Well, I didn’t want
to refactor everything we’d done to some other IoC framework, plus I couldn’t find
one at the time that actually worked for the Compact Framework, so I decided to create
one.  
</p>
        <p>
I took the tack that I’d create it for the CF first, with a high emphasis on small
footprint, minimal resource usage and speed and I simply matched the SCSF object model
where our code base interfaced with it and where it made sense – in some places I
didn’t like how the SCSF had done things, so I “fixed” their mistakes.  The end
result was the <a href="http://ioc.codeplex.com" target="_blank">OpenNETCF.IoC framework</a>,
which turns out to <a href="http://blog.opennetcf.com/ctacke/2011/04/29/BenchmarkingOpenNETCFsIoCFramework.aspx" target="_blank">stack
up quite well against the other frameworks</a>.  It also has the huge benefit
of working on the Full Framework, Windows Phone 7 and MonoTouch (probably MonoDroid
as well, though I’ve not tested that). We’ll be looking at OpenNETCF.IoC in a lot
more depth in this series.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=165f4077-cd46-4b7c-b1b6-27ff0e714fc9" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Inversion of Control, Dependency Injection and Service Locators oh my!</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,165f4077-cd46-4b7c-b1b6-27ff0e714fc9.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/01/InversionOfControlDependencyInjectionAndServiceLocatorsOhMy.aspx</link>
      <pubDate>Tue, 01 Nov 2011 15:50:17 GMT</pubDate>
      <description>&lt;p&gt;
This post is part of my "Software Development" series. &lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx"&gt;The
TOC for the entire series can be found here&lt;/a&gt;.
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;
In this post, we’re going to look, at a higher level, at the reasons for and benefits
of using a framework for Inversion of Control (IoC), Dependency Injection (DI) and
Service Location. I’m not going to spend a large amount of time in this blog series
describing the intimate details of what IoC, DI and Service Locators are.&amp;nbsp; &lt;a href="http://martinfowler.com/articles/injection.html#InversionOfControl" target=_blank&gt;Martin
Fowler did a fantastic job of it&lt;/a&gt; and there’s no point in me just regurgitating
his work.
&lt;/p&gt;
&lt;p&gt;
Instead, I’ll give my vision of what they are and how they are relevant to how I architect
and develop solutions.&amp;nbsp; It’s important to note that I’m starting out this series
with high-level thoughts about architecture and design.&amp;nbsp; I’m not just laying
down some code, leaving the decisions about how things will interact to some arbitrary,
organic process.&amp;nbsp; This is how software development gets done.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
You’ve got to think about not just the next step, but visualize the end point several
months, or even years out and try to connect the dots back to where you are today.&amp;nbsp;
If I implement something in a certain way today, is it going to screw me 3 months
down the road?&amp;nbsp; Spending an extra day now thinking about architecture is going
to turn into saving weeks of the customer breathing down your neck and you pull out
your hair and work late night trying to hammer a square peg into a round hole.
&lt;/p&gt;
&lt;p&gt;
So let’s look at IoC, DI and Service Location and how they’re going to help us build
better software.&amp;nbsp; Inversion of Control as a concept is something that’s really
broad.&amp;nbsp; It’s really anything that turns the older procedural way of developing
upside down (i.e. inverts program control, hence the name).&amp;nbsp; Moving from a console
app to a windowed, event-driven app is technically inversion of control, so you’ve
already been using IoC.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
To talk about IoC as a useful concept that’s actually going to be of use, we’ll be
using some smaller units/principals of IoC.&amp;nbsp; The two we’re going to look at are
Dependency Injection, or DI, and Service Location.&amp;nbsp; Neither one is complex or
arcane, and you probably already use them to some degree.
&lt;/p&gt;
&lt;p&gt;
Let’s assume we have two arbitrary classes, &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt;,
and that A uses an instance of B internally.&amp;nbsp; There are, essentially, 3 ways
that A can get the instance of B.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
First, it can directly create it by calling new B().&amp;nbsp; While this is simple, it’s
the least preferred, and generally worst, way to do it.&amp;nbsp; By directly creating
B, A is now tightly coupled to B’s implementation.&amp;nbsp; B can’t be easily changed
out to something else.&amp;nbsp; If B is in another assembly, A has to have a reference
to it.&amp;nbsp; It’s also difficult to test A by itself.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
The second way that A can get B is that whoever created the instance of A could pass
into it an instance of B.&amp;nbsp; Maybe through a constructor
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var b = new B();
var a = new A(b);&lt;/pre&gt;
&lt;p&gt;
or through a property
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;var b = new B(); 
var a = new A(); 
a.B = b;&lt;/pre&gt;
&lt;p&gt;
This is called Dependency Injection. The former is constructor injection, the latter
is property injection – not so complex, eh?&amp;nbsp; This is useful because, if B is
an interface, it’s really easy to swap out the implementation passed to A and the
assembly containing A doesn’t necessarily have to have a reference to the assembly
holding the implementation of B – it only needs a reference to the interface.&amp;nbsp;
This is really nice when we want to do mocking.
&lt;/p&gt;
&lt;p&gt;
The third way that A can get B is to go get it from some central repository or “factory”.
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;B B { get; set; }

public A() 
{ 
   this.B = MyClassFactory.GetB(); 
}&lt;/pre&gt;
&lt;p&gt;
This is service location.&amp;nbsp; A doesn’t really know what B is, it lets the service
locator (MyClassFactory) resolve that.&amp;nbsp; This is really helpful for plug-in architectures
as well as for lazy loading objects.
&lt;/p&gt;
&lt;p&gt;
Generally speaking, your code should only be doing #2 (DI) and #3 (service location)
for objects of any complexity.&amp;nbsp; This is not to say that you shouldn’t ever call
the new operator in your code.&amp;nbsp; There’s obviously a grey line out there below
which it would be pretty stupid to not just use &lt;strong&gt;new&lt;/strong&gt; for.&amp;nbsp; If
you need to use a simple entity class or structure, then creating one makes sense.&amp;nbsp;
If you need access to the DAL and I see you creating a DAL object in your View, you’re
fired.
&lt;/p&gt;
&lt;p&gt;
There are plenty of framework out there that provide DI and service location -&amp;nbsp; &lt;a href="http://ninject.org/" target=_blank&gt;Ninject&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/ff648512.aspx" target=_blank&gt;Unity&lt;/a&gt;, &lt;a href="http://www.castleproject.org/" target=_blank&gt;CastleWindsor&lt;/a&gt;, &lt;a href="http://structuremap.net/structuremap/" target=_blank&gt;StructureMap&lt;/a&gt;, &lt;a href="http://code.google.com/p/autofac/" target=_blank&gt;Autofac&lt;/a&gt; –
the list goes on and on.&amp;nbsp; Instead of using one of them, however, I chose to roll
my own.&amp;nbsp; Normally I wouldn’t recommend such a drastic action – after all reinventing
the wheel isn’t usually wise – but in my case it was essentially required, so I’ll
give you the short back story.
&lt;/p&gt;
&lt;p&gt;
My team and I had been working on a large desktop application.&amp;nbsp; We had designed
it from the start using &lt;a href="http://smartclient.codeplex.com/" target=_blank&gt;Microsoft’s
SCSF/CAB&lt;/a&gt; framework, which provide DI, service location and a load of other stuff.&amp;nbsp;
It turned out that we were using maybe 10% of the framework, and that the framework’s
Studio plug-ins were causing fits with some installations of Studio.&amp;nbsp; Spending
time screwing with Studio plug-ins and trying to get things to compile is a terrible
waste of manpower, so we were already getting close to jettisoning it when we decided
that we wanted the core of our app logic to be Compact Framework compatible.
&lt;/p&gt;
&lt;p&gt;
Well Microsoft’s “port” of the SCSF to the Compact Framework, called the &lt;a href="http://mobile.codeplex.com/" target=_blank&gt;MCSF&lt;/a&gt;,
turns out to be a bloated, unbelievably slow, steaming pile of dog crap.&amp;nbsp; Side
note: just because something &lt;em&gt;compiles&lt;/em&gt; under the Compact Framework &lt;em&gt;does
not&lt;/em&gt; mean it should be used in the Compact Framework.&amp;nbsp; Well, I didn’t want
to refactor everything we’d done to some other IoC framework, plus I couldn’t find
one at the time that actually worked for the Compact Framework, so I decided to create
one.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
I took the tack that I’d create it for the CF first, with a high emphasis on small
footprint, minimal resource usage and speed and I simply matched the SCSF object model
where our code base interfaced with it and where it made sense – in some places I
didn’t like how the SCSF had done things, so I “fixed” their mistakes.&amp;nbsp; The end
result was the &lt;a href="http://ioc.codeplex.com" target=_blank&gt;OpenNETCF.IoC framework&lt;/a&gt;,
which turns out to &lt;a href="http://blog.opennetcf.com/ctacke/2011/04/29/BenchmarkingOpenNETCFsIoCFramework.aspx" target=_blank&gt;stack
up quite well against the other frameworks&lt;/a&gt;.&amp;nbsp; It also has the huge benefit
of working on the Full Framework, Windows Phone 7 and MonoTouch (probably MonoDroid
as well, though I’ve not tested that). We’ll be looking at OpenNETCF.IoC in a lot
more depth in this series.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=165f4077-cd46-4b7c-b1b6-27ff0e714fc9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>Inversion of Control</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=80578eaa-eee4-49c6-952e-a80c27cbc76a</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,80578eaa-eee4-49c6-952e-a80c27cbc76a.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Below is a handy table of contents for my “Software Development” series of blog posts
</p>
        <ol>
          <li>
            <a href="http://blog.opennetcf.com/ctacke/2011/10/31/OnSoftwareDevelopment.aspx" target="_blank">On
Software Development</a> (10/31/11) </li>
          <li>
            <a href="http://blog.opennetcf.com/ctacke/2011/11/01/InversionOfControlDependencyInjectionAndServiceLocatorsOhMy.aspx">Inversion
of Control, Dependency Injection and Service Locators oh my!</a> (11/1/11)</li>
          <li>
            <a href="http://blog.opennetcf.com/ctacke/2011/11/21/SoftwareDevelopmentAnIntroToORMs.aspx">An
Intro to ORMs (11/21/11)</a>
          </li>
        </ol>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=80578eaa-eee4-49c6-952e-a80c27cbc76a" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Software Development Series : TOC</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,80578eaa-eee4-49c6-952e-a80c27cbc76a.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx</link>
      <pubDate>Tue, 01 Nov 2011 15:47:50 GMT</pubDate>
      <description>&lt;p&gt;
Below is a handy table of contents for my “Software Development” series of blog posts
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2011/10/31/OnSoftwareDevelopment.aspx" target=_blank&gt;On
Software Development&lt;/a&gt; (10/31/11)&amp;nbsp;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/InversionOfControlDependencyInjectionAndServiceLocatorsOhMy.aspx"&gt;Inversion
of Control, Dependency Injection and Service Locators oh my!&lt;/a&gt; (11/1/11)&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2011/11/21/SoftwareDevelopmentAnIntroToORMs.aspx"&gt;An
Intro to ORMs (11/21/11)&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=80578eaa-eee4-49c6-952e-a80c27cbc76a" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=bdfe97f5-3476-418c-9ef2-3db936810b2d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,bdfe97f5-3476-418c-9ef2-3db936810b2d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
This post is part of my "Software Development" series.  <a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx">The
TOC for the entire series can be found here</a>.
</p>
        <p>
          <hr />
        </p>
        <p>
Developing good software is hard.  Really hard.  Sure, anyone can buy a
book on writing software or pull up some code samples and get something that compiles
and runs, but that’s not’s really developing software.  A lot of code in the
wild – I’d bet a vast majority of it – just plain sucks.
</p>
        <p>
It’s hard to point out where the blame lies.  It seems that most developers are
environmentally or institutionally destined to write bad code. Schools teach how to
write code, but not how to architect it or to follow reasonable design practices. 
In the zeal for clarity, publishers churn out books, blogs and samples that show bad
practices (when is it ever a good idea to access a data model from your UI event handler?). 
Managers and customers alike push hard to get things done now, not necessarily done
right – only to find months or years later that doing it right would have saved a
boatload of time and money.  And let’s face it – many developers are simply showing
up to work to pull a paycheck.  You know who they are.  You’ve no doubt
worked with them in the past.  You’re probably working with them now.
</p>
        <p>
I was watching Gordon Ramsay the other day and it occurred to me that he and I are
alike in our own peculiar way.  I’m not saying that I see myself as the “Gordon
Ramsay of Software Development” – hardly -   but we share a common trait. 
Just as Gordon gets angry and starts spewing colorful language when he walks into
a crap kitchen, it bothers the hell out of me to see complete idiots in my chosen
field out there just making a mess of things.  When I see bad code – not necessarily
minor errors, or code that could be refactored and made better – but just outright
shit code that should not have occurred to a developer in the first place it pisses
me off.  By the nature of my work, often getting called in only when the project
is off the rails, I see it all the time. Code that, on review, a peer or mentor should
have seen and said “Whoa!  There’s no way that’s going into our code base”. 
Code that just makes it harder for the next person to do their job.
</p>
        <p>
In an effort to simplify things for my own code, for my customers’ code as well as
anyone who is willing to listen to my ravings, I’ve spent a lot of time building,
testing, fixing and extending tools and frameworks that many of which I turn around
and give away.  This isn’t out of altruism, no, it’s largely because I’m a lazy
developer.  I hate writing the same thing twice.  When I start a project,
I don’t want to spend large amounts of time building up the same infrastructure that
every project needs. Building up a framework for handling UI navigation isn’t what
I’d call interesting, but just about every project needs it.  Handling object
dependencies and events is common.  Writing a DAL for serializing and deserializing
entities is not just drudgery, I find it’s highly susceptible to errors because you
end up doing a lot of copy and paste.
</p>
        <p>
I have these cool tools and frameworks that I use in literally every project I work
on now.  That’s great for me, but it doesn’t really help others, right? 
Without reasonable documentation or explanation, only a small handful of people are
going to go through the effort of getting the tools and trying to understand them
– even if they are deceptively simple and could potentially save you weeks of effort.  
</p>
        <p>
So I’ve decided to put together a series of blogs over the coming weeks and months
that explain, hopefully in simple terms, what these frameworks do, how to use them,
and most importantly, why they are worth using.  There’s nothing groundbreaking
here.  I didn’t invent some new way to do things.  I’ve simply appropriated
other peoples’ ideas and extended them to work in the environments that I work.
</p>
        <p>
Generally I’ll be covering the following topics and frameworks:
</p>
        <ul>
          <li>
Dependency Injection and Inversion of Control (using OpenNETCF IoC) 
</li>
          <li>
Event Aggregation (using OpenNETCF IoC) 
</li>
          <li>
Plug-in Architectures and interface-based programming (using OpenNETCF IoC) 
</li>
          <li>
Software features as services (using OpenNETCF IoC) 
</li>
          <li>
Data Access through an ORM (using OpenNETCF ORM) 
</li>
          <li>
Parameter Checking (using OpenNETCF Extensions) 
</li>
          <li>
Exposing data services over HTTP (using Padarn) 
</li>
          <li>
Whatever else I think of 
</li>
        </ul>
        <p>
If there’s a topic you’d like me to talk about, feel free to send me an email. 
I may turn on comments here and let you post ideas, but I find that when I enable
comments on my blog, I start getting more comment spam than I really want to deal
with, so if comments are turned off just drop me a line.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bdfe97f5-3476-418c-9ef2-3db936810b2d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>On Software Development</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,bdfe97f5-3476-418c-9ef2-3db936810b2d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/10/31/OnSoftwareDevelopment.aspx</link>
      <pubDate>Mon, 31 Oct 2011 16:11:24 GMT</pubDate>
      <description>&lt;p&gt;
This post is part of my "Software Development" series.&amp;nbsp; &lt;a href="http://blog.opennetcf.com/ctacke/2011/11/01/SoftwareDevelopmentSeriesTOC.aspx"&gt;The
TOC for the entire series can be found here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;
Developing good software is hard.&amp;nbsp; Really hard.&amp;nbsp; Sure, anyone can buy a
book on writing software or pull up some code samples and get something that compiles
and runs, but that’s not’s really developing software.&amp;nbsp; A lot of code in the
wild – I’d bet a vast majority of it – just plain sucks.
&lt;/p&gt;
&lt;p&gt;
It’s hard to point out where the blame lies.&amp;nbsp; It seems that most developers are
environmentally or institutionally destined to write bad code. Schools teach how to
write code, but not how to architect it or to follow reasonable design practices.&amp;nbsp;
In the zeal for clarity, publishers churn out books, blogs and samples that show bad
practices (when is it ever a good idea to access a data model from your UI event handler?).&amp;nbsp;
Managers and customers alike push hard to get things done now, not necessarily done
right – only to find months or years later that doing it right would have saved a
boatload of time and money.&amp;nbsp; And let’s face it – many developers are simply showing
up to work to pull a paycheck.&amp;nbsp; You know who they are.&amp;nbsp; You’ve no doubt
worked with them in the past.&amp;nbsp; You’re probably working with them now.
&lt;/p&gt;
&lt;p&gt;
I was watching Gordon Ramsay the other day and it occurred to me that he and I are
alike in our own peculiar way.&amp;nbsp; I’m not saying that I see myself as the “Gordon
Ramsay of Software Development” – hardly -&amp;nbsp;&amp;nbsp; but we share a common trait.&amp;nbsp;
Just as Gordon gets angry and starts spewing colorful language when he walks into
a crap kitchen, it bothers the hell out of me to see complete idiots in my chosen
field out there just making a mess of things.&amp;nbsp; When I see bad code – not necessarily
minor errors, or code that could be refactored and made better – but just outright
shit code that should not have occurred to a developer in the first place it pisses
me off.&amp;nbsp; By the nature of my work, often getting called in only when the project
is off the rails, I see it all the time. Code that, on review, a peer or mentor should
have seen and said “Whoa!&amp;nbsp; There’s no way that’s going into our code base”.&amp;nbsp;
Code that just makes it harder for the next person to do their job.
&lt;/p&gt;
&lt;p&gt;
In an effort to simplify things for my own code, for my customers’ code as well as
anyone who is willing to listen to my ravings, I’ve spent a lot of time building,
testing, fixing and extending tools and frameworks that many of which I turn around
and give away.&amp;nbsp; This isn’t out of altruism, no, it’s largely because I’m a lazy
developer.&amp;nbsp; I hate writing the same thing twice.&amp;nbsp; When I start a project,
I don’t want to spend large amounts of time building up the same infrastructure that
every project needs. Building up a framework for handling UI navigation isn’t what
I’d call interesting, but just about every project needs it.&amp;nbsp; Handling object
dependencies and events is common.&amp;nbsp; Writing a DAL for serializing and deserializing
entities is not just drudgery, I find it’s highly susceptible to errors because you
end up doing a lot of copy and paste.
&lt;/p&gt;
&lt;p&gt;
I have these cool tools and frameworks that I use in literally every project I work
on now.&amp;nbsp; That’s great for me, but it doesn’t really help others, right?&amp;nbsp;
Without reasonable documentation or explanation, only a small handful of people are
going to go through the effort of getting the tools and trying to understand them
– even if they are deceptively simple and could potentially save you weeks of effort.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
So I’ve decided to put together a series of blogs over the coming weeks and months
that explain, hopefully in simple terms, what these frameworks do, how to use them,
and most importantly, why they are worth using.&amp;nbsp; There’s nothing groundbreaking
here.&amp;nbsp; I didn’t invent some new way to do things.&amp;nbsp; I’ve simply appropriated
other peoples’ ideas and extended them to work in the environments that I work.
&lt;/p&gt;
&lt;p&gt;
Generally I’ll be covering the following topics and frameworks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Dependency Injection and Inversion of Control (using OpenNETCF IoC) 
&lt;li&gt;
Event Aggregation (using OpenNETCF IoC) 
&lt;li&gt;
Plug-in Architectures and interface-based programming (using OpenNETCF IoC) 
&lt;li&gt;
Software features as services (using OpenNETCF IoC) 
&lt;li&gt;
Data Access through an ORM (using OpenNETCF ORM) 
&lt;li&gt;
Parameter Checking (using OpenNETCF Extensions) 
&lt;li&gt;
Exposing data services over HTTP (using Padarn) 
&lt;li&gt;
Whatever else I think of 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
If there’s a topic you’d like me to talk about, feel free to send me an email.&amp;nbsp;
I may turn on comments here and let you post ideas, but I find that when I enable
comments on my blog, I start getting more comment spam than I really want to deal
with, so if comments are turned off just drop me a line.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bdfe97f5-3476-418c-9ef2-3db936810b2d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>Inversion of Control</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>OpenNETCF.ORM</category>
      <category>Padarn</category>
      <category>Patterns and Practices</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=fcc005af-caf0-4a21-87c7-be9c74c0a5df</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,fcc005af-caf0-4a21-87c7-be9c74c0a5df.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the more common question groups I see about the Smart Device Framework
really revolves around connecting to an access point.  Connecting to an Open
AP is pretty straightforward, but as soon as you need to start adding encryption,
privacy, passcodes and all that fun stuff, people tend to go off the rails. 
And I can't blame them, the WirelessZeroConfigNetworkInterface class isn't the most
intuitive interface.  What I've done in my own projects is to create a WiFiService
class that wraps all of this (and a lot of other stuff too).  I'll try to get
that full service to a publishable state in the not-too-distant future, but the core
pieces for connectivity boil down to these few methods:
</p>
        <p>
 
</p>
        <pre class="csharp" name="code">public bool ConnectToOpenNetwork(string ssid)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToNetwork(ssid, null, false, AuthenticationMode.Open, WEPStatus.WEPDisabled);
}

public bool ConnectToOpenNetwork(IAccessPoint accessPoint)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return m_wzc.AddPreferredNetwork(accessPoint);
}

public bool ConnectToWEPNetwork(string ssid, string wepKey)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToNetwork(ssid, wepKey, false, AuthenticationMode.Open, WEPStatus.WEPEnabled);
}

public bool ConnectToWEPNetwork(IAccessPoint accessPoint, string wepKey)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToWEPNetwork(accessPoint.Name, wepKey);
}

/// 
<SUMMARY>
/// This connects to a WPA network using TKIP encryption. /// 
</SUMMARY>
/// 
<param name="ssid" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPANetwork(string ssid, string passphrase) { if (!WiFiSupported)
throw new NotSupportedException("No WZC WiFi Adapter detected on this device"); return
ConnectToNetwork(ssid, passphrase, false, AuthenticationMode.WPAPSK, WEPStatus.TKIPEnabled);
} /// 
<SUMMARY>
/// This method will only connect to a WPA2 network using AES. /// If you need fallback
to WPA (using TKIP), use the overload that takes in an AccessPoint /// 
</SUMMARY>
/// 
<param name="ssid" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPA2Network(string ssid, string passphrase) { if (!WiFiSupported)
throw new NotSupportedException("No WZC WiFi Adapter detected on this device"); return
ConnectToNetwork(ssid, passphrase, false, AuthenticationMode.WPA2PSK, WEPStatus.AESEnabled);
} /// 
<SUMMARY>
/// Connects to a WPA or WPA2 (AES or TKIP) /// 
</SUMMARY>
/// 
<param name="accessPoint" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPANetwork(IAccessPoint accessPoint, string passphrase) { if
(!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on
this device"); // quick validation var valid = accessPoint.AuthenticationMode == AuthenticationMode.WPA
|| accessPoint.AuthenticationMode == AuthenticationMode.WPAPSK || accessPoint.AuthenticationMode
== AuthenticationMode.WPA2 || accessPoint.AuthenticationMode == AuthenticationMode.WPA2PSK;
if (!valid) { throw new InvalidOperationException("The provided AP is not set up for
WPA"); } return ConnectToNetwork(accessPoint.Name, passphrase, false, accessPoint.AuthenticationMode,
accessPoint.Privacy); } private bool ConnectToNetwork(string ssid, string passphrase,
bool adhoc, AuthenticationMode mode, WEPStatus encryption) { EAPParameters eap = null;
switch (mode) { case AuthenticationMode.WPA: case AuthenticationMode.WPAPSK: case
AuthenticationMode.WPA2: case AuthenticationMode.WPA2PSK: eap = new EAPParameters()
{ Enable8021x = true, EapType = EAPType.Default, EapFlags = EAPFlags.Enabled, }; break;
} // stop scanning while connecting var wasScanning = Scanning; StopScanning(); try
{ lock (m_syncRoot) { return m_wzc.AddPreferredNetwork(ssid, !adhoc, passphrase, 1,
mode, encryption, eap); } } catch (ArgumentException ae) { return false; } finally
{ if (wasScanning) StartScanning(); } } </pre>
        <p>
I apologize that the above code won't just compile right out of the box - it's got
some dependencies to other bits in the Service class, but my hope is that it at least
gives the essence of what needs to be done to get the connectvitiy you need working.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=fcc005af-caf0-4a21-87c7-be9c74c0a5df" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>SDF and WiFi: Connecting to APs</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,fcc005af-caf0-4a21-87c7-be9c74c0a5df.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/10/28/SDFAndWiFiConnectingToAPs.aspx</link>
      <pubDate>Fri, 28 Oct 2011 16:41:48 GMT</pubDate>
      <description>&lt;p&gt;
One of the more common question groups&amp;nbsp;I see about the Smart Device Framework
really revolves around connecting to an access point.&amp;nbsp; Connecting to an Open
AP is pretty straightforward, but as soon as you need to start adding encryption,
privacy, passcodes and all that fun stuff, people tend to go off the rails.&amp;nbsp;
And I can't blame them, the WirelessZeroConfigNetworkInterface class isn't the most
intuitive interface.&amp;nbsp; What I've done in my own projects is to create a WiFiService
class that wraps all of this (and a lot of other stuff too).&amp;nbsp; I'll try to get
that full service to a publishable state in the not-too-distant future, but the core
pieces for connectivity boil down to these few methods:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;public bool ConnectToOpenNetwork(string ssid)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToNetwork(ssid, null, false, AuthenticationMode.Open, WEPStatus.WEPDisabled);
}

public bool ConnectToOpenNetwork(IAccessPoint accessPoint)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return m_wzc.AddPreferredNetwork(accessPoint);
}

public bool ConnectToWEPNetwork(string ssid, string wepKey)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToNetwork(ssid, wepKey, false, AuthenticationMode.Open, WEPStatus.WEPEnabled);
}

public bool ConnectToWEPNetwork(IAccessPoint accessPoint, string wepKey)
{
    if (!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on this device");

    return ConnectToWEPNetwork(accessPoint.Name, wepKey);
}

/// 
&lt;SUMMARY&gt;
/// This connects to a WPA network using TKIP encryption. /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="ssid"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPANetwork(string ssid, string passphrase) { if (!WiFiSupported)
throw new NotSupportedException("No WZC WiFi Adapter detected on this device"); return
ConnectToNetwork(ssid, passphrase, false, AuthenticationMode.WPAPSK, WEPStatus.TKIPEnabled);
} /// 
&lt;SUMMARY&gt;
/// This method will only connect to a WPA2 network using AES. /// If you need fallback
to WPA (using TKIP), use the overload that takes in an AccessPoint /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="ssid"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPA2Network(string ssid, string passphrase) { if (!WiFiSupported)
throw new NotSupportedException("No WZC WiFi Adapter detected on this device"); return
ConnectToNetwork(ssid, passphrase, false, AuthenticationMode.WPA2PSK, WEPStatus.AESEnabled);
} /// 
&lt;SUMMARY&gt;
/// Connects to a WPA or WPA2 (AES or TKIP) /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="accessPoint"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPANetwork(IAccessPoint accessPoint, string passphrase) { if
(!WiFiSupported) throw new NotSupportedException("No WZC WiFi Adapter detected on
this device"); // quick validation var valid = accessPoint.AuthenticationMode == AuthenticationMode.WPA
|| accessPoint.AuthenticationMode == AuthenticationMode.WPAPSK || accessPoint.AuthenticationMode
== AuthenticationMode.WPA2 || accessPoint.AuthenticationMode == AuthenticationMode.WPA2PSK;
if (!valid) { throw new InvalidOperationException("The provided AP is not set up for
WPA"); } return ConnectToNetwork(accessPoint.Name, passphrase, false, accessPoint.AuthenticationMode,
accessPoint.Privacy); } private bool ConnectToNetwork(string ssid, string passphrase,
bool adhoc, AuthenticationMode mode, WEPStatus encryption) { EAPParameters eap = null;
switch (mode) { case AuthenticationMode.WPA: case AuthenticationMode.WPAPSK: case
AuthenticationMode.WPA2: case AuthenticationMode.WPA2PSK: eap = new EAPParameters()
{ Enable8021x = true, EapType = EAPType.Default, EapFlags = EAPFlags.Enabled, }; break;
} // stop scanning while connecting var wasScanning = Scanning; StopScanning(); try
{ lock (m_syncRoot) { return m_wzc.AddPreferredNetwork(ssid, !adhoc, passphrase, 1,
mode, encryption, eap); } } catch (ArgumentException ae) { return false; } finally
{ if (wasScanning) StartScanning(); } } &lt;/pre&gt;
&lt;p&gt;
I apologize that the above code won't just compile right out of the box - it's got
some dependencies to other bits in the Service class, but my hope is that it at least
gives the essence of what needs to be done to get the connectvitiy you need working.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=fcc005af-caf0-4a21-87c7-be9c74c0a5df" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
      <category>SDF Samples</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=34cb82da-3b6c-48cf-b14c-366de9c18dbd</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,34cb82da-3b6c-48cf-b14c-366de9c18dbd.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A <a href="http://stackoverflow.com/questions/7111506/c-contextmenu-remove-default-selection/">recent
question on StackOverflow</a> got me sidetracked into the context menus for Windows
CE/Windows Mobile.  The question is pretty simple - when you create a <a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.contextmenu_members(v=VS.90).aspx">ContextMenu</a>,
it automatically "selects" the first item, and the OP wanted to know how to undo that
selection.  I spent a few hours screwing around with reflection and trying to
get at the handle for the menu items so I could P/Invoke and unselect the item and
only ended up failing (though I did post the meat of my work in my original answer).
</p>
        <p>
After doing that work it occurred to me that we (OpenNETCF) used to have a PopupMenu
commercial control that we long ago pulled from our catalog.  Well I looked on
our old source control server and sure enough, it was there.  Since it was doing
no one any good sitting in a bit bucket, I added it to <a href="http://cfcontrols.codeplex.com">our
published open-source control set over on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=34cb82da-3b6c-48cf-b14c-366de9c18dbd" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>New Open-Source Control for Compact Framework: Popup Menu</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,34cb82da-3b6c-48cf-b14c-366de9c18dbd.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/26/NewOpenSourceControlForCompactFrameworkPopupMenu.aspx</link>
      <pubDate>Fri, 26 Aug 2011 18:20:00 GMT</pubDate>
      <description>&lt;p&gt;
A &lt;a href="http://stackoverflow.com/questions/7111506/c-contextmenu-remove-default-selection/"&gt;recent
question on StackOverflow&lt;/a&gt; got me sidetracked into the context menus for Windows
CE/Windows Mobile.&amp;nbsp; The question is pretty simple - when you create a &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.contextmenu_members(v=VS.90).aspx"&gt;ContextMenu&lt;/a&gt;,
it automatically "selects" the first item, and the OP wanted to know how to undo that
selection.&amp;nbsp; I spent a few hours screwing around with reflection and trying to
get at the handle for the menu items so I could P/Invoke and unselect the item and
only ended up failing (though I did post the meat of my work in my original answer).
&lt;/p&gt;
&lt;p&gt;
After doing that work it occurred to me that we (OpenNETCF) used to have a PopupMenu
commercial control that we long ago pulled from our catalog.&amp;nbsp; Well I looked on
our old source control server and sure enough, it was there.&amp;nbsp; Since it was&amp;nbsp;doing
no one any good sitting in a bit bucket, I added it to &lt;a href="http://cfcontrols.codeplex.com"&gt;our
published open-source control set over on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=34cb82da-3b6c-48cf-b14c-366de9c18dbd" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=1881b25b-e12b-4c92-9888-c943056e4440</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,1881b25b-e12b-4c92-9888-c943056e4440.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <table id="outsideTable" border="0" cellspacing="0" cellpadding="0">
          <tbody>
            <tr>
              <td colspan="3">
                <!-- OPEN INSIDE TABLE -->
                <table id="insideTable" border="0" cellspacing="0" cellpadding="0">
                  <tbody>
                    <tr>
                      <td height="190" width="496" colspan="3" align="middle">
                        <img style="DISPLAY: block" border="0" alt="[MC]2 MTConnect: Connecting Manufacturing Conference" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/email_hdr.jpg" width="600" height="190" />
                      </td>
                    </tr>
                    <tr>
                      <td width="52">
 </td>
                      <td width="496" align="left">
                        <p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px">
Since its introduction to the manufacturing industry, the MTConnect standard has been
revolutionizing the way manufacturing equipment and devices "talk" to each other on
the shop floor. Anyone in the manufacturing industry can benefit from learning about
this important standard. That's why you must attend <a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org"><span style="COLOR: #3366cc; TEXT-DECORATION: none">[MC]2
MTConnect: Connecting Manufacturing Conference</span></a>, November 8-10, 2011, in
Cincinnati, Ohio.
</p>
                        <p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px">
This conference will have something for everyone, from distributors to end users,
to manufacturing technology builders, to software developers, to C-level executives,
to professors, to students, and to anyone who just wants to really understand MTConnect.
[MC]2 <a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org/event-schedule/"><span style="COLOR: #3366cc; TEXT-DECORATION: none">offers
both business and technical tracks</span></a>, hands-on technical workshops, panel
discussions on the use and benefits of the standards, as well as a showcase of commercially
available products utilizing the <a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://mtconnect.org"><span style="COLOR: #3366cc; TEXT-DECORATION: none">MTConnect</span></a> standard.
</p>
                        <a style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" href="http://www.mtconnectconference.org/registration/">
                          <img style="DISPLAY: block" border="0" alt="Register for [MC]2 Today" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/btn_cta.jpg" width="496" height="90" />
                        </a>
                        <p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px">
Conference attendees will have the opportunity to learn from the experts to
really understand how MTConnect, as <a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mmsonline.com/articles/mtconnect-is-for-real"><span style="COLOR: #3366cc; TEXT-DECORATION: none">Modern
Machine Shop said</span></a>, is enabling tremendous productivity gains in manufacturing.
 Those attending will return with new knowledge and skills so they can engage
in a deeper dialogue on manufacturing productivity, as well as a much better understanding
on what it takes to compete in 21st century manufacturing. <a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org/registration/"><span style="COLOR: #3366cc; TEXT-DECORATION: none">Register
now!</span></a> This is an event like no other.
</p>
                      </td>
                      <td width="52">
 </td>
                    </tr>
                  </tbody>
                </table>
                <!-- CLOSE INSIDE TABLE -->
              </td>
            </tr>
            <tr>
              <td width="52">
 </td>
              <td style="BORDER-TOP: #cccccc 1px solid" height="1" width="496">
 </td>
              <td width="52">
 </td>
            </tr>
            <tr>
              <td width="52">
 </td>
              <td width="496">
                <table>
                  <tbody>
                    <tr>
                      <td valign="top" width="346" align="left">
                        <p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.5; MARGIN: 0px 0px 20px; FONT-FAMILY: Helvetica, Arial, sans-serif; COLOR: #555555; FONT-SIZE: 11px">
                          <a style="COLOR: #555555; TEXT-DECORATION: underline" href="http://www.mtconnectconference.org">
                            <span style="COLOR: #555555">[MC]2
MTConnect: Connecting Manufacturing Conference</span>
                          </a>
                          <br />
November 8-10, 2011   |   Hyatt Regency - Cincinnati, Ohio<br />
7901 Westpark Dr., McLean, VA 22102   |   703-893-2900
</p>
                      </td>
                      <td valign="top" width="150" align="right">
                        <img style="DISPLAY: block" border="0" alt="MTConnect Institute logo" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/logo_mtConnect.gif" width="140" height="47" />
                      </td>
                    </tr>
                  </tbody>
                </table>
              </td>
              <td width="52">
 </td>
            </tr>
            <!-- CLOSE FOOTER -->
          </tbody>
        </table>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1881b25b-e12b-4c92-9888-c943056e4440" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>MTConnect [MC]^2 Conference</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,1881b25b-e12b-4c92-9888-c943056e4440.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/25/MTConnectMC2Conference.aspx</link>
      <pubDate>Thu, 25 Aug 2011 02:32:09 GMT</pubDate>
      <description>&lt;table id=outsideTable border=0 cellspacing=0 cellpadding=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td colspan=3&gt;
&lt;!-- OPEN INSIDE TABLE --&gt;
&lt;table id=insideTable border=0 cellspacing=0 cellpadding=0&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td height=190 width=496 colspan=3 align=middle&gt;
&lt;img style="DISPLAY: block" border=0 alt="[MC]2 MTConnect: Connecting Manufacturing Conference" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/email_hdr.jpg" width=600 height=190&gt; 
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td width=496 align=left&gt;
&lt;p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px"&gt;
Since its introduction to the manufacturing industry, the MTConnect standard has been
revolutionizing the way manufacturing equipment and devices "talk" to each other on
the shop floor. Anyone in the manufacturing industry can benefit from learning about
this important standard. That's why you must attend &lt;a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org"&gt;&lt;span style="COLOR: #3366cc; TEXT-DECORATION: none"&gt;[MC]2
MTConnect: Connecting Manufacturing Conference&lt;/span&gt;&lt;/a&gt;, November 8-10, 2011, in
Cincinnati, Ohio.
&lt;/p&gt;
&lt;p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px"&gt;
This conference&amp;nbsp;will have something for everyone, from distributors to end users,
to manufacturing technology builders, to software developers, to C-level executives,
to professors, to students, and to anyone who just wants to really understand MTConnect.
[MC]2 &lt;a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org/event-schedule/"&gt;&lt;span style="COLOR: #3366cc; TEXT-DECORATION: none"&gt;offers
both business and technical tracks&lt;/span&gt;&lt;/a&gt;, hands-on technical workshops, panel
discussions on the use and benefits of the standards, as well as a showcase of commercially
available products utilizing the &lt;a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://mtconnect.org"&gt;&lt;span style="COLOR: #3366cc; TEXT-DECORATION: none"&gt;MTConnect&lt;/span&gt;&lt;/a&gt; standard.
&lt;/p&gt;
&lt;a style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" href="http://www.mtconnectconference.org/registration/"&gt;&lt;img style="DISPLAY: block" border=0 alt="Register for [MC]2 Today" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/btn_cta.jpg" width=496 height=90&gt;&lt;/a&gt; 
&lt;p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.4; MARGIN: 0px 0px 12px; FONT-FAMILY: Arial, sans-serif; COLOR: #555555; FONT-SIZE: 13px"&gt;
Conference attendees will have the opportunity to&amp;nbsp;learn from the experts&amp;nbsp;to
really understand how MTConnect, as&amp;nbsp;&lt;a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mmsonline.com/articles/mtconnect-is-for-real"&gt;&lt;span style="COLOR: #3366cc; TEXT-DECORATION: none"&gt;Modern
Machine Shop said&lt;/span&gt;&lt;/a&gt;,&amp;nbsp;is enabling tremendous productivity gains in manufacturing.
&amp;nbsp;Those attending will return with&amp;nbsp;new knowledge and skills so they can engage
in a deeper dialogue on manufacturing productivity, as well as a much better understanding
on what it takes to compete in 21st century manufacturing. &lt;a style="COLOR: #3366cc; TEXT-DECORATION: none" href="http://www.mtconnectconference.org/registration/"&gt;&lt;span style="COLOR: #3366cc; TEXT-DECORATION: none"&gt;Register
now!&lt;/span&gt;&lt;/a&gt; This is an event like no other.
&lt;/p&gt;
&lt;/td&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;!-- CLOSE INSIDE TABLE --&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td style="BORDER-TOP: #cccccc 1px solid" height=1 width=496&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;td width=496&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td valign=top width=346 align=left&gt;
&lt;p style="TEXT-ALIGN: left; LINE-HEIGHT: 1.5; MARGIN: 0px 0px 20px; FONT-FAMILY: Helvetica, Arial, sans-serif; COLOR: #555555; FONT-SIZE: 11px"&gt;
&lt;a style="COLOR: #555555; TEXT-DECORATION: underline" href="http://www.mtconnectconference.org"&gt;&lt;span style="COLOR: #555555"&gt;[MC]2
MTConnect: Connecting Manufacturing Conference&lt;/span&gt;&lt;/a&gt;
&lt;br&gt;
November 8-10, 2011 &amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp; Hyatt Regency - Cincinnati, Ohio&lt;br&gt;
7901 Westpark Dr., McLean, VA 22102 &amp;nbsp;&amp;nbsp;|&amp;nbsp;&amp;nbsp; 703-893-2900
&lt;/p&gt;
&lt;/td&gt;
&lt;td valign=top width=150 align=right&gt;
&lt;img style="DISPLAY: block" border=0 alt="MTConnect Institute logo" src="http://www.mtconnectconference.org/wp-content/uploads/2011/08/logo_mtConnect.gif" width=140 height=47&gt; 
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/td&gt;
&lt;td width=52&gt;
&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;!-- CLOSE FOOTER --&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=1881b25b-e12b-4c92-9888-c943056e4440" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=5d8a6a74-a5f2-435e-b6ad-1de6228fde34</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,5d8a6a74-a5f2-435e-b6ad-1de6228fde34.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
          <img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width="321" height="98" />
        </p>
        <p>
I've again refreshed <a href="http://mtconnect.codeplex.com/">OpenNETCF's MTConnect
Managed SDK</a> with a few changes.  Most of the changes are the result
of us dogfooding the SDK and making things more thread-safe and solid.  
</p>
        <p>
In preparation for the upcoming <a href="http://www.mtconnectconference.org/">MTConnect:
Connecting Manufacturing Conference </a>where we'll be both speaking and have
a booth, I'm also creating some hands-on labs and tools.  One of the tools is
a Sample Client application that consumes the Client side of the SDK.  The full
source for the sample application is also available with <a href="http://mtconnect.codeplex.com/">the
SDK download over on Codeplex</a>.
</p>
        <p>
 
</p>
        <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/mtcclient.png" />
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5d8a6a74-a5f2-435e-b6ad-1de6228fde34" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>MTConnect Client SDK Refresh</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,5d8a6a74-a5f2-435e-b6ad-1de6228fde34.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/23/MTConnectClientSDKRefresh.aspx</link>
      <pubDate>Tue, 23 Aug 2011 21:06:04 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width=321 height=98&gt;
&lt;/p&gt;
&lt;p&gt;
I've again refreshed &lt;a href="http://mtconnect.codeplex.com/"&gt;OpenNETCF's MTConnect
Managed SDK&lt;/a&gt;&amp;nbsp;with a few changes.&amp;nbsp; Most of the changes are&amp;nbsp;the result
of us dogfooding the SDK and&amp;nbsp;making things more thread-safe and solid.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
In preparation for the upcoming &lt;a href="http://www.mtconnectconference.org/"&gt;MTConnect:
Connecting Manufacturing Conference&amp;nbsp;&lt;/a&gt;where we'll be both speaking and have
a booth, I'm also creating some hands-on labs and tools.&amp;nbsp; One of the tools is
a Sample Client application that consumes the Client side of the SDK.&amp;nbsp; The full
source for the sample application is also available with &lt;a href="http://mtconnect.codeplex.com/"&gt;the
SDK download over on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/mtcclient.png"&gt;&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5d8a6a74-a5f2-435e-b6ad-1de6228fde34" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=2c5f4c4b-b98b-4c49-a0aa-d2bc7ae3d2fe</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,2c5f4c4b-b98b-4c49-a0aa-d2bc7ae3d2fe.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We've been heavily dogfooding the IoC project (and others) lately and I finally took
the time today to back-port the fixes and updates to the public code. This is being
used for a solution that runs on both the desktop and the compact framework,
so it's been heavily tested under both of those environments. <a href="http://ioc.codeplex.com">The
new release (1.0.11235) is now available on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=2c5f4c4b-b98b-4c49-a0aa-d2bc7ae3d2fe" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF.IoC: New Release</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,2c5f4c4b-b98b-4c49-a0aa-d2bc7ae3d2fe.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/23/OpenNETCFIoCNewRelease.aspx</link>
      <pubDate>Tue, 23 Aug 2011 18:23:26 GMT</pubDate>
      <description>&lt;p&gt;
We've been heavily dogfooding the IoC project (and others) lately and I finally took
the time today to back-port the fixes and updates to the public code. This is being
used for a&amp;nbsp;solution that runs on both the desktop and the compact framework,
so it's been heavily tested under both of those environments.&amp;nbsp;&lt;a href="http://ioc.codeplex.com"&gt;The
new release (1.0.11235) is now available on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=2c5f4c4b-b98b-4c49-a0aa-d2bc7ae3d2fe" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>Desktop Development</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
      <category>Patterns and Practices</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=0ed4f3cc-f196-489a-ac14-f46f39e46da3</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,0ed4f3cc-f196-489a-ac14-f46f39e46da3.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Like most people, the more projects I work on the more I find myself reusing common
bits and pieces of code. For the past year or so I've been collecting these pieces
into a library I called OpenNETCF.Extensions.  The name was becasue they originally
started as a set of extension methods that helped me to compile one code base for
Windows Phone, the Compact Framework and the full framework, but it eventually started
expanding in scope.  I added a fairly robust set of method for validation, a
set of classes for helpiing make REST clients, a class for a circular buffer (FIFO)
and generally anything I found myself using on multiple projects.
</p>
        <p>
Since many of those projects are already open-source, it started becoming a pain maintaining
a single, controlled source for these helpers.  So in an attempt to centralize
it, I've created yet one more open source project.  My plan now is to have all
of the consuming projects only use binary releases from this project.
</p>
        <p>
So, with that said, go ahead and check out the new MIT-licensed <a href="http://oncfext.codeplex.com">OpenNETCF
Extensions project over on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0ed4f3cc-f196-489a-ac14-f46f39e46da3" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Another Open Source Project: OpenNETCF Extensions</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,0ed4f3cc-f196-489a-ac14-f46f39e46da3.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/23/AnotherOpenSourceProjectOpenNETCFExtensions.aspx</link>
      <pubDate>Tue, 23 Aug 2011 17:52:23 GMT</pubDate>
      <description>&lt;p&gt;
Like most people, the more projects I work on the more I find myself reusing common
bits and pieces of code. For the past year or so I've been collecting these pieces
into a library I called OpenNETCF.Extensions.&amp;nbsp; The name was becasue they originally
started as a set of extension methods that helped me to compile one code base for
Windows Phone, the Compact Framework and the full framework, but it eventually started
expanding in scope.&amp;nbsp; I added a fairly robust set of method for validation, a
set of classes for helpiing make REST clients, a class for a circular buffer (FIFO)
and generally anything I found myself using on multiple projects.
&lt;/p&gt;
&lt;p&gt;
Since many of those projects are already open-source, it started becoming a pain maintaining
a single, controlled source for these helpers.&amp;nbsp; So in an attempt to centralize
it, I've created yet one more open source project.&amp;nbsp; My plan now is to have all
of the consuming projects only use binary releases from this project.
&lt;/p&gt;
&lt;p&gt;
So, with that said, go ahead and check out the new MIT-licensed &lt;a href="http://oncfext.codeplex.com"&gt;OpenNETCF
Extensions project over on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=0ed4f3cc-f196-489a-ac14-f46f39e46da3" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>Desktop Development</category>
      <category>OpenNETCF</category>
      <category>Windows Phone 7</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=22a165af-0dc6-4351-b2df-c55f2f20dcad</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,22a165af-0dc6-4351-b2df-c55f2f20dcad.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm going through the <a href="http://www.opennetcf.com/Products/SmartDeviceFramework/tabid/65/Default.aspx">Smart
Device Framework</a>'s WZC code doing testing and hardening (yes, I realize it's long
overdue) and I realize that it's not all that clear how to add a preferred network
to a wireless adapter.  I've created the beginnings of a new Service
class for the <a href="http://ioc.codeplex.com">OpenNETCF IoC framework</a> (though
it's not required that you use IoC to use the service) that will help applications
manage things.  I'll come back and update this code as I expand the service due
to dogfooding it, but here's the start:
</p>
        <p>
 
</p>
        <pre class="csharp" name="code">using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace OpenNETCF.Net.NetworkInformation
{
    public delegate void ScanCompleteDelegate(AccessPoint[] newNetworks, AccessPoint[] lostNetworks, AccessPoint[] stillAvailableNetworks);

    public class WiFiService
    {
        private List<ACCESSPOINT>
m_knownAPs = new List<ACCESSPOINT>
(); private object m_syncRoot = new object(); private AutoResetEvent m_stopScanEvent
= new AutoResetEvent(false); private WirelessZeroConfigNetworkInterface m_wzc; public
event ScanCompleteDelegate ScanComplete; public int ScanPeriod { get; set; } public
bool Scanning { get; private set; } public WiFiService(WirelessZeroConfigNetworkInterface
netInterface) { m_wzc = netInterface; // default to a 2 second network scan period
ScanPeriod = 2000; } ~WiFiService() { StopScanning(); m_knownAPs.Clear(); } public
void StartScanning() { if (Scanning) return; new Thread(ScanThreadProc) { IsBackground
= true } .Start(); } public void StopScanning() { if (!Scanning) return; m_stopScanEvent.Set();
m_knownAPs.Clear(); } public bool ConnectToOpenNetwork(string ssid) { return ConnectToNetwork(ssid,
null, false, AuthenticationMode.Open, WEPStatus.WEPDisabled); } public bool ConnectToOpenNetwork(AccessPoint
accessPoint) { return m_wzc.AddPreferredNetwork(accessPoint); } public bool ConnectToWEPNetwork(string
ssid, string wepKey) { return ConnectToNetwork(ssid, wepKey, false, AuthenticationMode.Open,
WEPStatus.WEPEnabled); } public bool ConnectToWEPNetwork(AccessPoint accessPoint,
string wepKey) { return ConnectToWEPNetwork(accessPoint.Name, wepKey); } /// 
<SUMMARY>
/// This connects to a WPA network using TKIP encryption. /// 
</SUMMARY>
/// 
<param name="ssid" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPANetwork(string ssid, string passphrase) { return ConnectToNetwork(ssid,
passphrase, false, AuthenticationMode.WPAPSK, WEPStatus.TKIPEnabled); } /// 
<SUMMARY>
/// This method will only connect to a WPA2 network using AES. /// If you need fallback
to WPA (using TKIP), use the overload that takes in an AccessPoint /// 
</SUMMARY>
/// 
<param name="ssid" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPA2Network(string ssid, string passphrase) { return ConnectToNetwork(ssid,
passphrase, false, AuthenticationMode.WPA2PSK, WEPStatus.AESEnabled); } /// 
<SUMMARY>
/// Connects to a WPA or WPA2 (AES or TKIP) /// 
</SUMMARY>
/// 
<param name="accessPoint" />
/// 
<param name="passphrase" />
/// 
<RETURNS></RETURNS>
public bool ConnectToWPANetwork(AccessPoint accessPoint, string passphrase) { // quick
validation var valid = accessPoint.AuthenticationMode == AuthenticationMode.WPA ||
accessPoint.AuthenticationMode == AuthenticationMode.WPAPSK || accessPoint.AuthenticationMode
== AuthenticationMode.WPA2 || accessPoint.AuthenticationMode == AuthenticationMode.WPA2PSK;
if (!valid) { throw new InvalidOperationException("The provided AP is not set up for
WPA"); } return ConnectToNetwork(accessPoint.Name, passphrase, false, accessPoint.AuthenticationMode,
accessPoint.Privacy); } private void ScanThreadProc() { lock (m_syncRoot) { Scanning
= true; do { var et = Environment.TickCount; var current = m_wzc.NearbyAccessPoints;
var added = current.Except(m_knownAPs); var lost = m_knownAPs.Except(current); var
updated = m_knownAPs.Intersect(current); m_knownAPs = current.ToList(); var handler
= ScanComplete; et = Environment.TickCount - et; Debug.WriteLine(string.Format("Network
scan took {0}ms", et)); if (handler != null) { handler(added.ToArray(), lost.ToArray(),
updated.ToArray()); } } while (!m_stopScanEvent.WaitOne(ScanPeriod, false)); Scanning
= false; } } private bool ConnectToNetwork(string ssid, string passphrase, bool adhoc,
AuthenticationMode mode, WEPStatus encryption) { EAPParameters eap = null; switch
(mode) { case AuthenticationMode.WPA: case AuthenticationMode.WPAPSK: case AuthenticationMode.WPA2:
case AuthenticationMode.WPA2PSK: eap = new EAPParameters() { Enable8021x = true, EapType
= EAPType.Default, EapFlags = EAPFlags.Enabled, }; break; } // stop scanning while
connecting var wasScanning = Scanning; StopScanning(); try { lock (m_syncRoot) { return
m_wzc.AddPreferredNetwork(ssid, !adhoc, passphrase, 1, mode, encryption, eap); } }
finally { if (wasScanning) StartScanning(); } } } }
</ACCESSPOINT></ACCESSPOINT></pre>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=22a165af-0dc6-4351-b2df-c55f2f20dcad" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>A service for Scanning and Connecting to WiFi Networks from the CF</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,22a165af-0dc6-4351-b2df-c55f2f20dcad.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/19/AServiceForScanningAndConnectingToWiFiNetworksFromTheCF.aspx</link>
      <pubDate>Fri, 19 Aug 2011 16:08:04 GMT</pubDate>
      <description>&lt;p&gt;
I'm going through the &lt;a href="http://www.opennetcf.com/Products/SmartDeviceFramework/tabid/65/Default.aspx"&gt;Smart
Device Framework&lt;/a&gt;'s WZC code doing testing and hardening (yes, I realize it's long
overdue) and I realize that it's not all that clear how to add a preferred network
to a wireless adapter.&amp;nbsp; I've&amp;nbsp;created the beginnings of&amp;nbsp;a new Service
class&amp;nbsp;for the &lt;a href="http://ioc.codeplex.com"&gt;OpenNETCF IoC&amp;nbsp;framework&lt;/a&gt; (though
it's not required that you use IoC to use the service) that will help applications
manage things.&amp;nbsp; I'll come back and update this code as I expand the service due
to dogfooding it, but here's the start:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;

namespace OpenNETCF.Net.NetworkInformation
{
    public delegate void ScanCompleteDelegate(AccessPoint[] newNetworks, AccessPoint[] lostNetworks, AccessPoint[] stillAvailableNetworks);

    public class WiFiService
    {
        private List&lt;ACCESSPOINT&gt;
m_knownAPs = new List&lt;ACCESSPOINT&gt;
(); private object m_syncRoot = new object(); private AutoResetEvent m_stopScanEvent
= new AutoResetEvent(false); private WirelessZeroConfigNetworkInterface m_wzc; public
event ScanCompleteDelegate ScanComplete; public int ScanPeriod { get; set; } public
bool Scanning { get; private set; } public WiFiService(WirelessZeroConfigNetworkInterface
netInterface) { m_wzc = netInterface; // default to a 2 second network scan period
ScanPeriod = 2000; } ~WiFiService() { StopScanning(); m_knownAPs.Clear(); } public
void StartScanning() { if (Scanning) return; new Thread(ScanThreadProc) { IsBackground
= true } .Start(); } public void StopScanning() { if (!Scanning) return; m_stopScanEvent.Set();
m_knownAPs.Clear(); } public bool ConnectToOpenNetwork(string ssid) { return ConnectToNetwork(ssid,
null, false, AuthenticationMode.Open, WEPStatus.WEPDisabled); } public bool ConnectToOpenNetwork(AccessPoint
accessPoint) { return m_wzc.AddPreferredNetwork(accessPoint); } public bool ConnectToWEPNetwork(string
ssid, string wepKey) { return ConnectToNetwork(ssid, wepKey, false, AuthenticationMode.Open,
WEPStatus.WEPEnabled); } public bool ConnectToWEPNetwork(AccessPoint accessPoint,
string wepKey) { return ConnectToWEPNetwork(accessPoint.Name, wepKey); } /// 
&lt;SUMMARY&gt;
/// This connects to a WPA network using TKIP encryption. /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="ssid"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPANetwork(string ssid, string passphrase) { return ConnectToNetwork(ssid,
passphrase, false, AuthenticationMode.WPAPSK, WEPStatus.TKIPEnabled); } /// 
&lt;SUMMARY&gt;
/// This method will only connect to a WPA2 network using AES. /// If you need fallback
to WPA (using TKIP), use the overload that takes in an AccessPoint /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="ssid"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPA2Network(string ssid, string passphrase) { return ConnectToNetwork(ssid,
passphrase, false, AuthenticationMode.WPA2PSK, WEPStatus.AESEnabled); } /// 
&lt;SUMMARY&gt;
/// Connects to a WPA or WPA2 (AES or TKIP) /// 
&lt;/SUMMARY&gt;
/// 
&lt;param name="accessPoint"&gt;
&gt;
/// 
&lt;param name="passphrase"&gt;
&gt;
/// 
&lt;RETURNS&gt;
&lt;/RETURNS&gt;
public bool ConnectToWPANetwork(AccessPoint accessPoint, string passphrase) { // quick
validation var valid = accessPoint.AuthenticationMode == AuthenticationMode.WPA ||
accessPoint.AuthenticationMode == AuthenticationMode.WPAPSK || accessPoint.AuthenticationMode
== AuthenticationMode.WPA2 || accessPoint.AuthenticationMode == AuthenticationMode.WPA2PSK;
if (!valid) { throw new InvalidOperationException("The provided AP is not set up for
WPA"); } return ConnectToNetwork(accessPoint.Name, passphrase, false, accessPoint.AuthenticationMode,
accessPoint.Privacy); } private void ScanThreadProc() { lock (m_syncRoot) { Scanning
= true; do { var et = Environment.TickCount; var current = m_wzc.NearbyAccessPoints;
var added = current.Except(m_knownAPs); var lost = m_knownAPs.Except(current); var
updated = m_knownAPs.Intersect(current); m_knownAPs = current.ToList(); var handler
= ScanComplete; et = Environment.TickCount - et; Debug.WriteLine(string.Format("Network
scan took {0}ms", et)); if (handler != null) { handler(added.ToArray(), lost.ToArray(),
updated.ToArray()); } } while (!m_stopScanEvent.WaitOne(ScanPeriod, false)); Scanning
= false; } } private bool ConnectToNetwork(string ssid, string passphrase, bool adhoc,
AuthenticationMode mode, WEPStatus encryption) { EAPParameters eap = null; switch
(mode) { case AuthenticationMode.WPA: case AuthenticationMode.WPAPSK: case AuthenticationMode.WPA2:
case AuthenticationMode.WPA2PSK: eap = new EAPParameters() { Enable8021x = true, EapType
= EAPType.Default, EapFlags = EAPFlags.Enabled, }; break; } // stop scanning while
connecting var wasScanning = Scanning; StopScanning(); try { lock (m_syncRoot) { return
m_wzc.AddPreferredNetwork(ssid, !adhoc, passphrase, 1, mode, encryption, eap); } }
finally { if (wasScanning) StartScanning(); } } } }
&lt;/pre&gt;&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=22a165af-0dc6-4351-b2df-c55f2f20dcad" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Compact Framework Code</category>
      <category>OpenNETCF</category>
      <category>SDF Samples</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=63cb95cf-b15a-479d-947f-da1f4dc18193</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,63cb95cf-b15a-479d-947f-da1f4dc18193.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <title>C++ FIFO (Circular Buffer) class</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,63cb95cf-b15a-479d-947f-da1f4dc18193.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/08/12/CFIFOCircularBufferClass.aspx</link>
      <pubDate>Fri, 12 Aug 2011 15:02:26 GMT</pubDate>
      <description>&lt;p&gt;
Here's a FIFO/Circular Buffer class I put together ages ago.&amp;nbsp; I wrote it for
a Windows CE platform, but there's no reason it wouoldn't work on the desktop as well.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;pre class=csharp name="code"&gt;//
// FIFO.h
//
#include 
&lt;WINDOWS.H&gt;
template 
&lt;TYPENAME t&gt;
class FIFO { public: FIFO(int capacityInItems, TCHAR *overrunEventName, TCHAR *dataAvailEventName);
~FIFO(); void Enqueue(T&amp;amp; item); T Dequeue(); T Peek(); int GetCount(); BOOL HasOverrun();
void ClearOverrun(); void Clear(); HANDLE GetOverrunEventHandle(); int GetHighWater();
private: BYTE *m_buffer; volatile DWORD m_pRead; volatile DWORD m_pWrite; volatile
BOOL m_full; volatile BOOL m_empty; volatile BOOL m_overrun; volatile DWORD m_highWater;
DWORD m_capacity; HANDLE m_overrunEvent; HANDLE m_availableEvent; CRITICAL_SECTION
m_cs; int m_increment; }; template&lt;TYPENAME t&gt;
FIFO&lt;T&gt;
::FIFO(int capacityInItems, TCHAR *overrunEventName, TCHAR *dataAvailEventName) :
m_pWrite(0), m_pRead(0), m_empty(TRUE), m_full(FALSE), m_overrun(FALSE), m_overrunEvent(NULL),
m_highWater(0) { m_increment = sizeof(T); m_capacity = capacityInItems * m_increment;
m_buffer = (BYTE*)LocalAlloc(LPTR, m_capacity); if(overrunEventName != NULL) { m_overrunEvent
= CreateEvent(NULL, FALSE, FALSE, overrunEventName); } if(dataAvailEventName != NULL)
{ m_availableEvent = CreateEvent(NULL, TRUE, FALSE, dataAvailEventName); } InitializeCriticalSection(&amp;amp;m_cs);
} template&lt;TYPENAME t&gt;
FIFO&lt;T&gt;
::~FIFO() { LocalFree(m_buffer); DeleteCriticalSection(&amp;amp;m_cs); } template&lt;TYPENAME t&gt;
void FIFO&lt;T&gt;&lt;VOID*&gt;
::Enqueue(T&amp;amp; item) { EnterCriticalSection(&amp;amp;m_cs); if(m_full) { // if we're
full this is an overrun! m_overrun = TRUE; // set an event if(m_overrunEvent != NULL)
{ SetEvent(m_overrunEvent); } } m_empty = FALSE; // set a friendly waitable object
if(m_availableEvent) { SetEvent(m_availableEvent); } memcpy(m_buffer + m_pWrite, static_cast(&amp;amp;item),
m_increment); m_pWrite += m_increment; int count = GetCount(); if(count &amp;gt; m_highWater)
m_highWater = count; if(m_pWrite &amp;gt;= m_capacity) { // back to the start m_pWrite
= 0; } // if we've overrun, the oldest data is tossed if(m_overrun) { m_pRead += m_increment;
if(m_pRead &amp;gt;= m_capacity) { // back to the start m_pRead = 0; } } else { // see
if we're full if(m_pWrite == m_pRead) { m_full = TRUE; // set an event? } } LeaveCriticalSection(&amp;amp;m_cs);
} template&lt;TYPENAME t&gt;
T FIFO&lt;T&gt;
::Dequeue() { T t; EnterCriticalSection(&amp;amp;m_cs); if(m_empty) { memset(&amp;amp;t, 0,
m_increment); LeaveCriticalSection(&amp;amp;m_cs); return t; } m_full = FALSE; memcpy(&amp;amp;t,
m_buffer + m_pRead, m_increment); m_pRead += m_increment; if(m_pRead &amp;gt;= m_capacity)
{ // back to the start m_pRead = 0; } // see if we're empty if(m_pRead == m_pWrite)
{ m_empty = TRUE; // set a friendly waitable object if(m_availableEvent) { ResetEvent(m_availableEvent);
} } LeaveCriticalSection(&amp;amp;m_cs); return t; } template&lt;TYPENAME t&gt;
T FIFO&lt;T&gt;
::Peek() { T *t; if(m_empty) { return NULL; } return t; } template&lt;TYPENAME t&gt;
int FIFO&lt;T&gt;
::GetCount() { int ret = 0; EnterCriticalSection(&amp;amp;m_cs); if(m_empty) ret = 0;
else if(m_full) ret = m_capacity / m_increment; else if(m_pWrite &amp;gt; m_pRead) ret
= (m_pWrite - m_pRead) / m_increment; else ret = (m_capacity / m_increment) - ((m_pRead
- m_pWrite) / m_increment); LeaveCriticalSection(&amp;amp;m_cs); return ret; } template&lt;TYPENAME t&gt;
BOOL FIFO&lt;T&gt;
::HasOverrun() { return m_overrun; } template&lt;TYPENAME t&gt;
void FIFO&lt;T&gt;
::ClearOverrun() { m_overrun = FALSE; } template&lt;TYPENAME t&gt;
void FIFO&lt;T&gt;
::Clear() { m_overrun = FALSE; m_full = FALSE; m_empty = TRUE; m_pWrite = 0; m_pRead
= 0; } template&lt;TYPENAME t&gt;
HANDLE FIFO&lt;T&gt;
::GetOverrunEventHandle() { return m_overrunEvent; } template&lt;TYPENAME t&gt;
int FIFO&lt;T&gt;
::GetHighWater() { return m_highWater; } 
&lt;/pre&gt;&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=63cb95cf-b15a-479d-947f-da1f4dc18193" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=39b5ca97-572b-4069-a31d-6d8a00842279</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,39b5ca97-572b-4069-a31d-6d8a00842279.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today someone <a href="http://stackoverflow.com/questions/6859886/use-bouncy-castle-library-with-net-compact-framework">asked
over on StackOverflow</a> how to compile Bouncy Castle for Compact Framework 3.5. 
Since SO has no way to add attachments, I'm parking the solution here.  Basically
here are the steps:
</p>
        <ol>
          <li>
            <a href="http://www.bouncycastle.org/csharp/index.html">Download the latest source</a> (v
1.7 as of this writing) 
</li>
          <li>
            <a href="http://blog.opennetcf.com/ctacke/content/binary/bouncycastle.cf.zip">Download
my Visual Studio 2008 solution and project files</a>
          </li>
          <li>
Put the csharp.cf.sln in the same location as the existing csharp.sln file 
</li>
          <li>
Put the crypto.cf.csproj in the same location as the existing crypto.csproj file 
</li>
          <li>
Open the csharp.cf.sln file and build</li>
        </ol>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=39b5ca97-572b-4069-a31d-6d8a00842279" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Bouncy Castle (Crypto) in the Compact Framework</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,39b5ca97-572b-4069-a31d-6d8a00842279.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/07/28/BouncyCastleCryptoInTheCompactFramework.aspx</link>
      <pubDate>Thu, 28 Jul 2011 21:08:46 GMT</pubDate>
      <description>&lt;p&gt;
Today someone &lt;a href="http://stackoverflow.com/questions/6859886/use-bouncy-castle-library-with-net-compact-framework"&gt;asked
over on StackOverflow&lt;/a&gt; how to compile Bouncy Castle for Compact Framework 3.5.&amp;nbsp;
Since SO has no way to add attachments, I'm parking the solution here.&amp;nbsp; Basically
here are the steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;a href="http://www.bouncycastle.org/csharp/index.html"&gt;Download the latest source&lt;/a&gt; (v
1.7 as of this writing) 
&lt;li&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/bouncycastle.cf.zip"&gt;Download
my Visual Studio 2008 solution and project files&lt;/a&gt; 
&lt;li&gt;
Put the csharp.cf.sln in the same location as the existing csharp.sln file 
&lt;li&gt;
Put the crypto.cf.csproj in the same location as the existing crypto.csproj file 
&lt;li&gt;
Open the csharp.cf.sln file and build&lt;/li&gt;
&lt;/ol&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=39b5ca97-572b-4069-a31d-6d8a00842279" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=47597099-7916-43b8-8c39-f10426a68fc1</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,47597099-7916-43b8-8c39-f10426a68fc1.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm still working on cleaning out our code archive and publishing things I feel might
still be useful.  Today, I published the OpenNETCF Calendar controls, which provide
some funtionality that has the look and feel of the Pocket Outlook UI.
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/calendar.gif" />
        </p>
        <p>
          <a href="http://cfcalendar.codeplex.com/">Get the source over on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=47597099-7916-43b8-8c39-f10426a68fc1" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF Calendar Controls released on Codeplex</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,47597099-7916-43b8-8c39-f10426a68fc1.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/06/28/OpenNETCFCalendarControlsReleasedOnCodeplex.aspx</link>
      <pubDate>Tue, 28 Jun 2011 14:56:46 GMT</pubDate>
      <description>&lt;p&gt;
I'm still working on cleaning out our code archive and publishing things I feel might
still be useful.&amp;nbsp; Today, I published the OpenNETCF Calendar controls, which provide
some funtionality that has the look and feel of the Pocket Outlook UI.
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/calendar.gif"&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://cfcalendar.codeplex.com/"&gt;Get the source over on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=47597099-7916-43b8-8c39-f10426a68fc1" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=af47cc37-f78d-4281-ba8e-ae2362f917b9</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,af47cc37-f78d-4281-ba8e-ae2362f917b9.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Recently I've seen some <a href="http://stackoverflow.com/questions/6318388/installing-windows-mobile-6-standard-sdk-with-vs2010-without-vs2005">activity
on Stack Overflow</a> where some industrious people are attempting to get Studio 2010
to build non-Phone CF applications.  I assume this is for Continuous Integration/Build
Server stuff, but it's a start toward a community workaround to the long-standing
problem of Microsoft not giving us any help.  Part of the solution appears to
be to copy over some of the targets files from an earlier version of Studio. 
In an effort to aid in that, I've attached those files below.
</p>
        <p>
          <a href="http://blog.opennetcf.com/ctacke/content/binary/msbuild.targets.cf3.5.rar">msbuild.targets.cf3.5.rar
(240.41 KB)</a>
          <br />
          <a href="http://blog.opennetcf.com/ctacke/content/binary/msbuild.targets.cf1_2.rar">msbuild.targets.cf1_2.rar
(255.88 KB)</a>
        </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=af47cc37-f78d-4281-ba8e-ae2362f917b9" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>msbuild Targets files for CF projects</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,af47cc37-f78d-4281-ba8e-ae2362f917b9.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/06/12/msbuildTargetsFilesForCFProjects.aspx</link>
      <pubDate>Sun, 12 Jun 2011 00:10:36 GMT</pubDate>
      <description>&lt;p&gt;
Recently I've seen some &lt;a href="http://stackoverflow.com/questions/6318388/installing-windows-mobile-6-standard-sdk-with-vs2010-without-vs2005"&gt;activity
on Stack Overflow&lt;/a&gt; where some industrious people are attempting to get Studio 2010
to build non-Phone CF applications.&amp;nbsp; I assume this is for Continuous Integration/Build
Server stuff, but it's a start toward a community workaround to the long-standing
problem of Microsoft not giving us any help.&amp;nbsp; Part of the solution appears to
be to copy over some of the targets files from an earlier version of Studio.&amp;nbsp;
In an effort to aid in that, I've attached those files below.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/msbuild.targets.cf3.5.rar"&gt;msbuild.targets.cf3.5.rar
(240.41 KB)&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/content/binary/msbuild.targets.cf1_2.rar"&gt;msbuild.targets.cf1_2.rar
(255.88 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=af47cc37-f78d-4281-ba8e-ae2362f917b9" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=3140bbba-7f2a-4fdd-aa66-ae8ed71a9326</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,3140bbba-7f2a-4fdd-aa66-ae8ed71a9326.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blog.opennetcf.com/ctacke/2011/05/10/CreatingABootSplashImageSplashbmxForWindowsCE.aspx">Earlier
today I published a tool for creating CE splash images</a>. Well I already hit a limitation,
so I've updated the tool.  It now supports all common image formats (PNG, JPG,
GIF and BMP) instead of just BMP.  BIOSLoader also limits your image to 64k -
anything larger might actually hand the device.  The tool now detects when the
result will be larger than 64k and will offer to resize it before compressing as well.
</p>
        <p>
The latest binary and source are <a href="http://splashce.codeplex.com/">up in Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=3140bbba-7f2a-4fdd-aa66-ae8ed71a9326" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>splash.bmx - Take 2</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,3140bbba-7f2a-4fdd-aa66-ae8ed71a9326.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/05/10/splashbmxTake2.aspx</link>
      <pubDate>Tue, 10 May 2011 23:23:28 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://blog.opennetcf.com/ctacke/2011/05/10/CreatingABootSplashImageSplashbmxForWindowsCE.aspx"&gt;Earlier
today I published a tool for creating CE splash images&lt;/a&gt;. Well I already hit a limitation,
so I've updated the tool.&amp;nbsp; It now supports all common image formats (PNG, JPG,
GIF and BMP) instead of just BMP.&amp;nbsp; BIOSLoader also limits your image to 64k -
anything larger might actually hand the device.&amp;nbsp; The tool now detects when the
result will be larger than 64k and will offer to resize it before compressing as well.
&lt;/p&gt;
&lt;p&gt;
The latest binary and source are &lt;a href="http://splashce.codeplex.com/"&gt;up in Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=3140bbba-7f2a-4fdd-aa66-ae8ed71a9326" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=e760019a-494e-4038-896d-3307a1fdd6a5</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,e760019a-494e-4038-896d-3307a1fdd6a5.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you're booting an OS on a device that supports the BIOSLoader, an option is to
display a "splash screen" image while the OS loads from disk.  The file is, by
default, called 'splash.bmx', which is expected to be a compressed binary file, *not*
an image.  The compressed binary file can be generated from a bitmap using bincompress.exe
(which ships with Platform Builder).
</p>
        <p>
While that seems all well and good, there are also some other limitations.  For
example the source bitmap (pre compression) must be 256-color, and I believe there
is likely a maximum file size as well (I'm sure the loader allocates a static block
of RAM to hold the image).  Well my image editor of choice (Paint.NET) doesn't
have a simple mechanism to save as a 256-color bitmap, not all of my PCs have Platform
Builder (and thereforebincompress) installed, and I'm a fan of simplifying multistep
processes in general.
</p>
        <p>
So I created a very simply Windows app that you use to browse to an image, then click
a button and it converts it to 256-color and generates the splash.bmx file for you. 
It was just a couple hours of playing around, so it's not overly robust (it could
probably use a command-line interface for automation, and a "preview" of the conversion
would be nice) but it's functional for what I needed to get done this week. 
Here's what it looks like:
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/splashgen.png" />
        </p>
        <p>
 
</p>
        <p>
I've published the work (source and binary) <a href="http://splashce.codeplex.com/">up
on Codeplex</a>.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e760019a-494e-4038-896d-3307a1fdd6a5" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Creating a Boot Splash Image (splash.bmx) for Windows CE</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,e760019a-494e-4038-896d-3307a1fdd6a5.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/05/10/CreatingABootSplashImageSplashbmxForWindowsCE.aspx</link>
      <pubDate>Tue, 10 May 2011 19:22:11 GMT</pubDate>
      <description>&lt;p&gt;
If you're booting an OS on a device that supports the BIOSLoader, an option is to
display a "splash screen" image while the OS loads from disk.&amp;nbsp; The file is, by
default, called 'splash.bmx', which is expected to be a compressed binary file, *not*
an image.&amp;nbsp; The compressed binary file can be generated from a bitmap using bincompress.exe
(which ships with Platform Builder).
&lt;/p&gt;
&lt;p&gt;
While that seems all well and good, there are also some other limitations.&amp;nbsp; For
example the source bitmap (pre compression) must be 256-color, and I believe there
is likely a maximum file size as well (I'm sure the loader allocates a static block
of RAM to hold the image).&amp;nbsp; Well my image editor of choice (Paint.NET) doesn't
have a simple mechanism to save as a 256-color bitmap, not all of my PCs have Platform
Builder (and thereforebincompress) installed, and I'm a fan of simplifying multistep
processes in general.
&lt;/p&gt;
&lt;p&gt;
So I created a very simply Windows app that you use to browse to an image, then click
a button and it converts it to 256-color and generates the splash.bmx file for you.&amp;nbsp;
It was just a couple hours of playing around, so it's not overly robust (it could
probably use a command-line interface for automation, and a "preview" of the conversion
would be nice) but it's functional for what I needed to get done this week.&amp;nbsp;
Here's what it looks like:
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/splashgen.png"&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I've published the work (source and binary)&amp;nbsp;&lt;a href="http://splashce.codeplex.com/"&gt;up
on Codeplex&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=e760019a-494e-4038-896d-3307a1fdd6a5" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>OpenNETCF</category>
      <category>Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=5232481d-826f-4d84-9c1a-0cbb3eedd078</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,5232481d-826f-4d84-9c1a-0cbb3eedd078.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Last night I was browsing around the Net on a back tracking a visit to the <a href="http://ioc.codeplex.com">OpenNETCF
Inversion Of Control (IoC) project</a>.  I came upon <a href="http://www.iocbattle.com/">a
page</a> where someone had done a quick set of benchmarks for many of the popular
IoC engines out there [http://www.iocbattle.com/].  This got me wondering. 
How would OpenNETCF IoC stack up against these, after all I've never done any performance
comparisons against any other framework.
</p>
        <p>
Well I downloaded the <a href="https://github.com/MartinF/IOCBattle">benchmarking
code</a> the original author had put together and added added an IoC version of the
test (which was really easy to do).  I then ran the singleton test, which essentially
registers a set of dependent classes by interface name (in theRootWorkItem.Services
collection) and then uses the IoC engine to extract the from the store 1,000,000 times. 
It then reports how long it took to do the extraction.  Simple enough.
</p>
        <p>
Here are the results:
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Singleton.png" />
        </p>
        <p>
The hard numbers are not really important - the actual number is going to depend on
your hardware - what is interesting is how they look relative to one anotehr. 
You can see that if you exclude the new operator (which isn't IoC, it's just there
for reference), then the Dynamo engine (which is the test author's engine) preforms
the best.  Now I know nothing about that engine, so if you're interested, I'll
let you investigate that further.
</p>
        <p>
What was interesting to me is that IoC is three times faster than the next fastest
IoC engine (AutoFac), five times faster than Structure Map, roughly 6 times faster
than Castle Windsor or Unity and a whopping 25 times faster than the ever-popular
Ninject engine.  Evidently my focus on performance when developign the engine
paid off.
</p>
        <p>
How about the time it takes to register all of the types that get created?  Are
we paying the piper at creation time in order to save it at resolution?  Here
are the time results for setup (instantiation of singletons):
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Registration.png" />
        </p>
        <p>
Again, IoC is at near front of the pack.
</p>
        <p>
Binary size isn't overly relevent any longer, I mean if you're using managed code
then you've already made the decision that file sizes aren't critical, but it's still
interesting to look at.  Here's a breakdown of the sizes of each of the libraries. 
The libraries marked with an asterisk also have configuration files that are *not*
included in the resported size (so deployment would actually be larger than what the
graph shows).
</p>
        <p>
          <img border="0" src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Size.png" />
        </p>
        <p>
All in all, I'm pretty pleased with the results.  We dogfood the OpenNETCF
IoC framework for all of our projects, both desktop and Compact Framework, so it gets
a fair amound of testing and beating and you can be assured that if there are bugs
I'll do my best to resolve them.  If you've not taken a look at the project, <a href="http://ioc.codeplex.com">give
it a try</a>.
</p>
        <p>
 
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5232481d-826f-4d84-9c1a-0cbb3eedd078" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>Benchmarking OpenNETCF's IoC Framework</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,5232481d-826f-4d84-9c1a-0cbb3eedd078.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/04/29/BenchmarkingOpenNETCFsIoCFramework.aspx</link>
      <pubDate>Fri, 29 Apr 2011 16:23:10 GMT</pubDate>
      <description>&lt;p&gt;
Last night I was browsing around the Net on a back tracking a visit to the &lt;a href="http://ioc.codeplex.com"&gt;OpenNETCF
Inversion Of Control (IoC) project&lt;/a&gt;.&amp;nbsp; I came upon &lt;a href="http://www.iocbattle.com/"&gt;a
page&lt;/a&gt; where someone had done a quick set of benchmarks for many of the popular
IoC engines out there [http://www.iocbattle.com/].&amp;nbsp; This got me wondering.&amp;nbsp;
How would OpenNETCF IoC stack up against these, after all I've never done any performance
comparisons against any other framework.
&lt;/p&gt;
&lt;p&gt;
Well I downloaded the &lt;a href="https://github.com/MartinF/IOCBattle"&gt;benchmarking
code&lt;/a&gt; the original author had put together and added added an IoC version of the
test (which was really easy to do).&amp;nbsp; I then ran the singleton test, which essentially
registers a set of dependent classes by interface name (in theRootWorkItem.Services
collection) and then uses the IoC engine to extract the from the store 1,000,000 times.&amp;nbsp;
It then reports how long it took to do the extraction.&amp;nbsp; Simple enough.
&lt;/p&gt;
&lt;p&gt;
Here are the results:
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Singleton.png"&gt;
&lt;/p&gt;
&lt;p&gt;
The hard numbers are not really important - the actual number is going to depend on
your hardware - what is interesting is how they look relative to one anotehr.&amp;nbsp;
You can see that if you exclude the new operator (which isn't IoC, it's just there
for reference), then the Dynamo engine (which is the test author's engine) preforms
the best.&amp;nbsp; Now I know nothing about that engine, so if you're interested, I'll
let you investigate that further.
&lt;/p&gt;
&lt;p&gt;
What was interesting to me is that IoC is three times faster than the next fastest
IoC engine (AutoFac), five times faster than Structure Map, roughly 6 times faster
than Castle Windsor or Unity and a whopping 25 times faster than the ever-popular
Ninject engine.&amp;nbsp; Evidently my focus on performance when developign the engine
paid off.
&lt;/p&gt;
&lt;p&gt;
How about the time it takes to register all of the types that get created?&amp;nbsp; Are
we paying the piper at creation time in order to save it at resolution?&amp;nbsp; Here
are the time results for setup (instantiation of singletons):
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Registration.png"&gt;
&lt;/p&gt;
&lt;p&gt;
Again, IoC is at near front of the pack.
&lt;/p&gt;
&lt;p&gt;
Binary size isn't overly relevent any longer, I mean if you're using managed code
then you've already made the decision that file sizes aren't critical, but it's still
interesting to look at.&amp;nbsp; Here's a breakdown of the sizes of each of the libraries.&amp;nbsp;
The libraries marked with an asterisk also have configuration files that are *not*
included in the resported size (so deployment would actually be larger than what the
graph shows).
&lt;/p&gt;
&lt;p&gt;
&lt;img border=0 src="http://blog.opennetcf.com/ctacke/content/binary/IoC_Size.png"&gt;
&lt;/p&gt;
&lt;p&gt;
All in all, I'm pretty pleased with the results.&amp;nbsp; We&amp;nbsp;dogfood the OpenNETCF
IoC framework for all of our projects, both desktop and Compact Framework, so it gets
a fair amound of testing and beating and you can be assured that if there are bugs
I'll do my best to resolve them.&amp;nbsp; If you've not taken a look at the project, &lt;a href="http://ioc.codeplex.com"&gt;give
it a try&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=5232481d-826f-4d84-9c1a-0cbb3eedd078" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>Inversion of Control</category>
      <category>OpenNETCF</category>
      <category>OpenNETCF.IoC</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=7195b6fc-a812-4691-8d16-50de1e8aca63</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,7195b6fc-a812-4691-8d16-50de1e8aca63.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width="321" height="98" />
        </p>
        <p>
I've published a refresh of the <a href="http://mtcagent.codeplex.com/">OpenNETCF
MTConnect VirtualAgent</a> code up on Codeplex.  This is a major refactor
from the last publication which extracted the VirtualAgent engine capabilities into
a separate <a href="http://ioc.codeplex.com">IoC module</a>.  This change greatly
simplifies integrating VirtualAgent capabilities into an existing application as well
as allowing an app to publish other <a href="http://opennetcf.com/padarn.ocf">Padarn
REST services and ASP.NET pages</a> without having to modify the VirtualAgent engine
code base.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=7195b6fc-a812-4691-8d16-50de1e8aca63" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>OpenNETCF VirtualAgent Refresh released</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,7195b6fc-a812-4691-8d16-50de1e8aca63.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/04/28/OpenNETCFVirtualAgentRefreshReleased.aspx</link>
      <pubDate>Thu, 28 Apr 2011 23:30:21 GMT</pubDate>
      <description>&lt;p&gt;
&lt;img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width=321 height=98&gt;
&lt;/p&gt;
&lt;p&gt;
I've published a refresh of the &lt;a href="http://mtcagent.codeplex.com/"&gt;OpenNETCF
MTConnect VirtualAgent&lt;/a&gt;&amp;nbsp;code up on Codeplex.&amp;nbsp; This is a major refactor
from the last publication which extracted the VirtualAgent engine capabilities into
a separate &lt;a href="http://ioc.codeplex.com"&gt;IoC module&lt;/a&gt;.&amp;nbsp; This change greatly
simplifies integrating VirtualAgent capabilities into an existing application as well
as allowing an app to publish other &lt;a href="http://opennetcf.com/padarn.ocf"&gt;Padarn
REST services and ASP.NET pages&lt;/a&gt; without having to modify the VirtualAgent engine
code base.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=7195b6fc-a812-4691-8d16-50de1e8aca63" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=39d3b35a-fba4-4e05-bd8f-e02e6bf2501d</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,39d3b35a-fba4-4e05-bd8f-e02e6bf2501d.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
 
</p>
        <p>
          <img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width="321" height="98" />
        </p>
        <p>
I've again refreshed <a href="http://mtconnect.codeplex.com/">OpenNETCF's MTConnect
Managed SDK</a> with a few changes, including:
</p>
        <ul>
          <li>
Added support for some <strong>current</strong> and <strong>sample</strong> filtering
(not all filtering is supported, but I've added device name and data item ID filtering) 
</li>
          <li>
Added AgentInformation to the EntityClient so you get information about the agent
returning a data set for a <strong>probe</strong></li>
          <li>
Miscellaneous bug fixes and refactoring</li>
        </ul>
        <p>
As always, if you find a bug or would like me to work on implementing a specific feature
from the specification, add it to the lists over on the Codeplex site.
</p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=39d3b35a-fba4-4e05-bd8f-e02e6bf2501d" />
        <br />
        <hr />
Managed Code in the Embedded World</body>
      <title>MTConnect SDK Refresh Released</title>
      <guid isPermaLink="false">http://blog.opennetcf.com/ctacke/PermaLink,guid,39d3b35a-fba4-4e05-bd8f-e02e6bf2501d.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2011/04/28/MTConnectSDKRefreshReleased.aspx</link>
      <pubDate>Thu, 28 Apr 2011 19:00:50 GMT</pubDate>
      <description>&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://blog.opennetcf.com/ctacke/content/binary/MTConnect_Logo.jpg" width=321 height=98&gt;
&lt;/p&gt;
&lt;p&gt;
I've again refreshed &lt;a href="http://mtconnect.codeplex.com/"&gt;OpenNETCF's MTConnect
Managed SDK&lt;/a&gt;&amp;nbsp;with a few changes, including:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Added support for some &lt;strong&gt;current&lt;/strong&gt; and &lt;strong&gt;sample&lt;/strong&gt; filtering
(not all filtering is supported, but I've added device name and data item ID filtering) 
&lt;li&gt;
Added AgentInformation to the EntityClient so you get information about the agent
returning a data set for a &lt;strong&gt;probe&lt;/strong&gt; 
&lt;li&gt;
Miscellaneous bug fixes and refactoring&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As always, if you find a bug or would like me to work on implementing a specific feature
from the specification, add it to the lists over on the Codeplex site.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=39d3b35a-fba4-4e05-bd8f-e02e6bf2501d" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <category>.NET Compact Framework</category>
      <category>MTConnect</category>
      <category>OpenNETCF</category>
      <category>Windows Phone 7</category>
    </item>
  </channel>
</rss>