<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" 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/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>dotNetProfessional</title>
    <description>Garry McGlennon</description>
    <link>http://www.dotnetprofessional.com/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.4.5.0</generator>
    <language>en-AU</language>
    <blogChannel:blogRoll>http://www.dotnetprofessional.com/blog/opml.axd</blogChannel:blogRoll>
    <dc:creator>Garry McGlennon</dc:creator>
    <dc:title>dotNetProfessional</dc:title>
    <geo:lat>47.610935</geo:lat><geo:long>-122.141047</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Dotnetprofessional" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>UnitTestEx v1.2 Released!</title>
      <description>&lt;p&gt;I’ve just released an update to the &lt;a href="http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx"&gt;UnitTestEx&lt;/a&gt; component which as the following additions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Re-factored API signatures to make them much simpler &lt;/li&gt;    &lt;li&gt;ExecuteUnitTestScript to support in/out params &lt;/li&gt;    &lt;li&gt;Renamed ExecuteUnitTestValidationScriptReader to ExecuteUnitTestScriptReader which also now supports in params &lt;/li&gt;    &lt;li&gt;Added unit test for all database related features ie ExecuteUnitTestScript &lt;/li&gt;    &lt;li&gt;Added database scripts to allow testing of the new unit tests. &lt;/li&gt;    &lt;li&gt;Compare now supports the ability to treat empty collections as the same as null collections. This feature can be useful if de-serialize your expected results from an XML file and your actual forces some collections to be null but the default behaviour of the code is to have initialized collections. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;For anyone who has been using an older version, this version represents a number of breaking changes. The changes however are not significant and the APIs are now quite stable.&lt;/p&gt;  &lt;p&gt;If you haven’t checked out the component yet, take a look at the &lt;a href="http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx"&gt;original post&lt;/a&gt; and the &lt;a title="UnitTestEx Home" href="http://unittestex.codeplex.com/"&gt;code&lt;/a&gt; on CodePlex.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx&amp;amp;title=UnitTestEx v1.2 Released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/yIhyDeYZYTM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/yIhyDeYZYTM/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</guid>
      <pubDate>Thu, 20 Aug 2009 23:23:51 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/08/20/UnitTestEx-v12-Released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=dfb9f6ae-c7c7-4db2-b883-0cadc09e69c0</feedburner:origLink></item>
    <item>
      <title>Visual Studio Debugging Slow? Try this!</title>
      <description>&lt;p&gt;On my current project I find that I’m working with Visual Studio on a VM that is in an isolated domain, which is making life interesting! One of those ‘interesting’ things was that Debugging in Visual Studio was horrendously slow! It would take several minutes to get to the first break point (first line of a unit test), then still be slow when accessing other parts of the code.&lt;/p&gt;  &lt;p&gt;The slow part of the process was the loading of the symbol files for each of the referenced dlls, including those of the .NET framework. As it turns out Visual Studio actually loads the symbol files for the .NET Framework from the internet! So the delay is primarily due to timeouts which lead to an unbearable (read unusable) debugging environment. The good news is that there is a solution which is quite simple and easy to implement.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h1&gt;Solution&lt;/h1&gt;  &lt;p&gt;In order to dramatically improve your debugging you need to have Visual Studio use a cached version of the symbol files, as well as ensure its not trying to locate symbol files on slow network shares.&lt;/p&gt;  &lt;p&gt;Here are the steps you need to fix the issue:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Create a directory to store you locally cached symbols. Ie C:\Temp\SymbolCache &lt;/li&gt;    &lt;li&gt;Change the debug settings for loading symbols, via Tools|Options|Debugging|Symbols.      &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/1CC7532C/DebuggingOptions1.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DebuggingOptions1" border="0" alt="DebuggingOptions1" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/69F74CB7/DebuggingOptions1_thumb.png" width="244" height="143" /&gt;&lt;/a&gt; &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;(Option 1) Start debugging the code you want (on a machine that can access the internet; even if its slow) and have it sit on a break point. Then go back to the Symbols settings, where you’ll notice the button Load symbols from Microsoft symbol servers is now active (because that was obvious!). Click the button and you’ll see a popup windows indicating the download of the symbol files. After this is complete you can close out of this window and stop debugging. If you now check your Symbol Cache directory you’ll see you have a load of downloaded symbols (may vary depending on what you’ve referenced).      &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/3B9DC70A/SymbolCache.png" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SymbolCache" border="0" alt="SymbolCache" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/VisualStudioDebuggingSlowTrythis/74487117/SymbolCache_thumb.png" width="244" height="171" /&gt;&lt;/a&gt; &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;(Option 2) If you have already done option 1 and you need to apply this to another machine, such as a team members machine, you can simply copy the files from one machine to the other. &lt;/li&gt;    &lt;li&gt;Depending on your environment you may also have one of two environment variables that need updating. Set either of these environment variables to the same location as the cache created in setup 2. The environment variables to change are _NT_SYMBOL_PATH or _NT_ALT_SYMBOL_PATH. The default setting for these are pointing to the Microsoft Symbols server. You can access the variables either via DOS (set command) or via the Advanced System Properties dialog in Windows.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;One you’ve completed the changes you should see a dramatic improvement in your performance. Remember to check in Step 2 that you don’t have any non-existent paths or UNC paths defined as this will also slow things down.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx&amp;amp;title=Visual Studio Debugging Slow? Try this!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/MWb7JgTl070" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/MWb7JgTl070/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (GarryMc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=b95828a8-3e2e-4576-9883-94c00ce8b759</guid>
      <pubDate>Thu, 20 Aug 2009 22:08:47 -0800</pubDate>
      <category>Visual Studio</category>
      <dc:publisher>GarryMc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=b95828a8-3e2e-4576-9883-94c00ce8b759</pingback:target>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=b95828a8-3e2e-4576-9883-94c00ce8b759</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/08/20/Visual-Studio-Debugging-Slow-Try-this!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=b95828a8-3e2e-4576-9883-94c00ce8b759</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=b95828a8-3e2e-4576-9883-94c00ce8b759</feedburner:origLink></item>
    <item>
      <title>dnp.Framework code released!</title>
      <description>&lt;p&gt;In an effort to start getting more of the code I’ve been working on out in the public domain, I’ve finally released all the code for the &lt;a title="Framework Home Page" href="http://dotnetprofessional.com/blog/page/dnpFramework.aspx" target="_blank"&gt;dnp.Framework&lt;/a&gt; on &lt;a title="Framework CodePlex Home Page" href="http://www.codeplex.com/dnpFramework" target="_blank"&gt;CodePlex&lt;/a&gt;. While its not all complete, most of the code is quite stable and can be used now!&lt;/p&gt;  &lt;p&gt;Some of the major components that are included in the framework include:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;&lt;a href="http://dotnetprofessional.com/blog/page/Database-Explorer-API-Overview.aspx" target="_blank"&gt;Database Explorer API&lt;/a&gt;:&lt;/strong&gt; An object oriented database schema API which is ideal for anyone wanting to do code generation. Its based on the provider pattern, so while it currently only supports SQL Server 2005+ its fairly easy to create a new provider for any system. This is stable enough for production use and has an extensive set of unit tests. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data Provider:&lt;/strong&gt; This is a database agnostic API which is fairly similar to the one in the enterprise library except it doesn’t support datasets and the like. Its also has little overhead. This was designed before the Enterprise Library had a decent model, and it has also been used on mobile devices with the compact framework. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;DomainModeller:&lt;/strong&gt; An abstract domain model view of a database schema (extends Database Explorer API). This API is most useful to creating scripts for code generation, where you can concentrate on domain concepts such as base classes, derived classes, namespaces and relationships etc, rather than database concepts. Using this API for code generation can significantly reduce the amount of code typically required. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ServiceModel:&lt;/strong&gt; This project is still under development, but aims to provide the first ‘Model’ that extends the Domain Modeller to define a Service based Application framework. The ServiceModel acts as the abstract API for the final code generation scripts which are currently written using CodeSmith. The scripts currently have good support for the data access layer (repository), service layer (business logic) and entities (using design discussed &lt;a title="Modeling Many to One relationships" href="http://dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank"&gt;here&lt;/a&gt;).  &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There are other components that are less substantial but provide useful features:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Configuration:&lt;/strong&gt; classes to allow custom sections in config files. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;IO:&lt;/strong&gt; classes to make getting info from resource files easier. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Collections:&lt;/strong&gt; classes that support multi-keyed collections. This is useful when you want to key on a natural or business key which is made up of more than one field. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Reflection:&lt;/strong&gt; classes to help with serialization &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Scripting: &lt;/strong&gt;classes that help with naming such as converting names to plural or singular versions, casing such as pascal, camel and proper. There’s also an expression evaluator that allows evaluating an expression against an object. This is used heavily in the Domain Modeller and ServiceModel config files. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Security:&lt;/strong&gt; CookieProtection, MachineKey encoding &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Web:&lt;/strong&gt; SafeLocalStorage, thread wide TimeZone conversions, Web log (IIS) Linq provider &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This framework has taken some time to get this far and while not complete does provide a number of features that are useful today. Over the next few months I’ll blog about some of the features mentioned above to provide a better understanding of how to use them. For now the best way to get a feel for how classes are used is to look at the unit tests for the class. Most of the features have tests which give a good idea of how its used.&lt;/p&gt;  &lt;p&gt;If you’d like to have a particular feature explained in more depth, leave a comment here otherwise I’ll pick the ones I like :)&lt;/p&gt;  &lt;p&gt;Oh and you can find all the code &lt;a title="Framework CodePlex Home Page" href="http://www.codeplex.com/dnpFramework" target="_blank"&gt;here!&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx&amp;amp;title=dnp.Framework code released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/yuRLVrmHQgM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/yuRLVrmHQgM/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=6bc721b0-0207-4161-a296-7fe811e963fb</guid>
      <pubDate>Thu, 21 May 2009 22:25:05 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>.NET 2.0</category>
      <category>ASP.NET</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=6bc721b0-0207-4161-a296-7fe811e963fb</pingback:target>
      <slash:comments>14</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=6bc721b0-0207-4161-a296-7fe811e963fb</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/05/21/dnpFramework-code-released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=6bc721b0-0207-4161-a296-7fe811e963fb</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=6bc721b0-0207-4161-a296-7fe811e963fb</feedburner:origLink></item>
    <item>
      <title>Unit Testing and Test Spy Library Released!</title>
      <description>&lt;p&gt;Its been some time since my last post, so I thought I’d start back with news of a small Unit Testing library I’ve been using with my current client. I developed the library to solve a number of issues I was facing while doing my unit tests. The focus of the library is to provide support for:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Test Spy Pattern:&lt;/strong&gt; a type of of fake that monitors calls and data passed rather than trying to mock the implementation. A discussion of the pattern can be found in the &lt;a href="http://xunitpatterns.com/Test%20Spy.html" target="_blank"&gt;xUnit Patterns&lt;/a&gt; book. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Comparing entities:&lt;/strong&gt; the amount of code generally required to test that an entities properties match those of the expected version can be large and tedious to write. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data access testing:&lt;/strong&gt; while using Fakes and the like is great, you still need to test the code that actually talks to the database. This usually ends up taking a reasonable amount of code to setup and execute, making the test harder to read. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This library provides solutions to the above problems which in my experience has produced cleaner tests that are easier to read and understand. The library comes with a fairly detailed &lt;a title="UnitTestEx User Guide" href="http://unittestex.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27528" target="_blank"&gt;User Guide&lt;/a&gt; so I wont go into the details of how everything works here, however I will provide a quick overview of how the library attempts to solve these issues.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Test Spy pattern:&lt;/strong&gt; adding a single property per method that you want to track to your existing Fake (Test Double) and one or two lines of code to the Fakes method implementation provides the following features:       &lt;ul&gt;       &lt;li&gt;Was called &lt;/li&gt;        &lt;li&gt;Method call count &lt;/li&gt;        &lt;li&gt;Parameters passed in to method (per call) &lt;/li&gt;        &lt;li&gt;Ability to define the data returned from any method of a dependency &lt;/li&gt;        &lt;li&gt;Ability to simulate an exception in a dependency &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Comparing entities:&lt;/strong&gt; given two object graphs you can compare each property in a single line of code using the Compare method. The library also supports the ability to ignore certain properties that tend to always change such as primary keys that are identity fields. The Compare method currently handles the basic value types and strings as well as more complex types such as XmlDocument and DataTable, adding a new complex type is a achievable by simply defining a new Type rule. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Data access testing:&lt;/strong&gt; when testing code that affects a database, you need to ensure the database is in a particular state before starting. This can be done via calling a stored procedure or maybe running a database script. The library opts for the second approach and allows you to embed SQL script files which can then be executed with a single line of code. This approach ensures devs always have the latest scripts and dont have to remember to update their local copy of the database. There are a other methods that help with querying the database after executing the code under test too. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The library also provides helper routines around Serialization and IO. You can download the library and its User Guide from the CodePlex project below:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.codeplex.com/UnitTestEx" href="http://www.codeplex.com/UnitTestEx"&gt;http://www.codeplex.com/UnitTestEx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As I find the time I’ll blog about some of the technical aspects of the library such as extending the Compare method it to support new complex data types.&lt;/p&gt;  &lt;p&gt;If you end up using it in your project, please leave a comment or if you have any feature improvements (or bugs) post them to the CodePlex site. &lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx&amp;amp;title=Unit Testing and Test Spy Library Released!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/utzTKdlVn40" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/utzTKdlVn40/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=76cd9c6f-9512-4771-8594-1778e4094150</guid>
      <pubDate>Wed, 20 May 2009 21:12:09 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=76cd9c6f-9512-4771-8594-1778e4094150</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=76cd9c6f-9512-4771-8594-1778e4094150</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2009/05/20/Unit-Testing-and-Test-Spy-Library-Released!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=76cd9c6f-9512-4771-8594-1778e4094150</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=76cd9c6f-9512-4771-8594-1778e4094150</feedburner:origLink></item>
    <item>
      <title>Turn multiple rows into a single string in SQL Server</title>
      <description>&lt;p&gt;I recently had the task of creating a report where they wanted one of the columns to list out all the users associated with a given report line item in a single comma separated string. My initial thoughts were, that this would involve some type of cursor or at least a loop of some description, which I'd then have to attach to the main result set. However, it seems there's a very nice little trick you can use that will solve this issue without the use of cursors or loops!&lt;/p&gt; &lt;p&gt;With the use of the COALESCE keyword you can create a list in a single line of SQL (except for declarations). I'll use the AdventureWorks database to demonstrate the technique. Assume&amp;nbsp; you need to get a list of Countries and the regions they contain, in a report similar to the one below: &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/TurnmultiplerowsintoasinglestringinSQLSe_13964/SampleReport_2.jpg"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="366" alt="Sample Report" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/TurnmultiplerowsintoasinglestringinSQLSe_13964/SampleReport_thumb.jpg" width="484" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;To produce a list you can use the following SQL:&lt;/p&gt; &lt;div class="csharpcode-wrapper"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @&lt;span class="kwrd"&gt;result&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt;    @&lt;span class="kwrd"&gt;result&lt;/span&gt; = &lt;span class="kwrd"&gt;coalesce&lt;/span&gt;(@&lt;span class="kwrd"&gt;result&lt;/span&gt; + &lt;span class="str"&gt;', '&lt;/span&gt;, &lt;span class="str"&gt;''&lt;/span&gt;) + Name&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;    Person.StateProvince&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt;    Person.StateProvince.CountryRegionCode = @CountryRegionCode&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @&lt;span class="kwrd"&gt;Result&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_1322);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_1322);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
				&lt;div id="CopyToClipboard_Hidden" style="display:none;"&gt;&lt;/div&gt;
				&lt;div id="CopyToClipboard_FlashContainer"&gt;&lt;/div&gt;
                &lt;script type="text/javascript"&gt;

					function CopyToClipboard_Strip( text ){
						text = text.replace( /&amp;nbsp;/g, ' ' );
						text = text.replace( /&amp;quot;/g, '"' );
						text = text.replace( /&amp;#39;/g, '"' );
						text = text.replace( /&amp;amp;/g, '&amp;' );
						text = text.replace( /&amp;lt;/g, String.fromCharCode(60) );
						text = text.replace( /&amp;gt;/g, String.fromCharCode(62) );
						return text;
					}

                    function CopyToClipboard_Copy( text ){

						//### get reference to utility div
						var ele = document.getElementById('CopyToClipboard_Hidden');

						//### the following taken from: http://webchicanery.com/2006/11/14/clipboard-copy-javascript/
						if (false &amp;&amp; window.clipboardData) {
							window.clipboardData.setData( "Text", text );
						} else {
							document.getElementById('CopyToClipboard_FlashContainer').innerHTML = '';
							var divinfo = '&lt;embed id="CopyToClipboard_FlashFile" src="/blog/_clipboard.swf" FlashVars="clipboard=' + encodeURIComponent(text) + '" width="0" height="0" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;';
							document.getElementById('CopyToClipboard_FlashContainer').innerHTML = divinfo;
						}

                    }

					function CopyToClipboard_ViewPlain( text ){
						var win = window.open( '', 'CopyToClipboard_Window', 'width=480, height=480, toolbar=no, menubar=no, scrollbars=auto, resizable=yes, location=no, directories=no, status=no' );
						win.document.write( '&lt;html&gt;&lt;head&gt;&lt;title&gt;Code&lt;/title&gt;&lt;body style="margin:0;padding:0;"&gt;&lt;textarea style="width:100%;height:100%;border:0;"&gt;' + text + '&lt;/textarea&gt;&lt;/body&gt;&lt;/html&gt;' );
					}

                &lt;/script&gt;
            
					&lt;script type="text/javascript"&gt;
						var copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_1322 = CopyToClipboard_Strip('DECLARE @result varchar(max) SELECT    @result = coalesce(@result + \', \', \'\') + NameFROM    Person.StateProvinceWHERE    Person.StateProvince.CountryRegionCode = @CountryRegionCode RETURN @Result');
					&lt;/script&gt;
&lt;p&gt;The way this works is the COALESCE function returns the first non-null expression. For the first record this would be the empty string + Name as @Result would be null. However, the interesting thing is that because we keep concatinating to @Result a single value is returned from the whole result set. The only issue is that for this to work we need a variable to keep storing the information in. So if you want to apply this against another table that supplies the filter, you'll have to create a function that returns the string. As this is a scalar function (ie doesn't return a result set) its use within another query is extremely easy. Assuming a function for the above is called dbo.fnRegionsToString we are left with:&lt;/p&gt;
&lt;div class="csharpcode-wrapper"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; Country, dbo.fnRegionsToString(CountryRegionCode) States&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;
         Person.CountryRegion&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_5376);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_5376);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_5376 = CopyToClipboard_Strip('SELECT Name AS Country, dbo.fnRegionsToString(CountryRegionCode) StatesFROM\r\n         Person.CountryRegion');
					&lt;/script&gt;
&lt;p&gt;The whole script which you can test against the AdventureWorks database is:&lt;/p&gt;
&lt;div class="csharpcode-wrapper"&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;IF&lt;/span&gt;  &lt;span class="kwrd"&gt;EXISTS&lt;/span&gt; (&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; * &lt;span class="kwrd"&gt;FROM&lt;/span&gt; dbo.sysobjects &lt;span class="kwrd"&gt;WHERE&lt;/span&gt; [id] = OBJECT_ID(N&lt;span class="str"&gt;'[dbo].[fnRegionsToString]'&lt;/span&gt;) &lt;span class="kwrd"&gt;AND&lt;/span&gt; type &lt;span class="kwrd"&gt;in&lt;/span&gt; (N&lt;span class="str"&gt;'FN'&lt;/span&gt;, N&lt;span class="str"&gt;'IF'&lt;/span&gt;, N&lt;span class="str"&gt;'TF'&lt;/span&gt;, N&lt;span class="str"&gt;'FS'&lt;/span&gt;, N&lt;span class="str"&gt;'FT'&lt;/span&gt;))&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;DROP&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; dbo.fnRegionsToString&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;GO&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;FUNCTION&lt;/span&gt; dbo.fnRegionsToString&lt;/pre&gt;&lt;pre class="alteven"&gt;(&lt;/pre&gt;&lt;pre class="alt"&gt;    @CountryRegionCode &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(5)&lt;/pre&gt;&lt;pre class="alteven"&gt;)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;RETURNS&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;Max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;AS&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;BEGIN&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;DECLARE&lt;/span&gt; @&lt;span class="kwrd"&gt;result&lt;/span&gt; &lt;span class="kwrd"&gt;varchar&lt;/span&gt;(&lt;span class="kwrd"&gt;max&lt;/span&gt;)&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;SELECT&lt;/span&gt;    @&lt;span class="kwrd"&gt;result&lt;/span&gt; = &lt;span class="kwrd"&gt;coalesce&lt;/span&gt;(@&lt;span class="kwrd"&gt;result&lt;/span&gt; + &lt;span class="str"&gt;', '&lt;/span&gt;, &lt;span class="str"&gt;''&lt;/span&gt;) + Name&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;span class="kwrd"&gt;FROM&lt;/span&gt;    Person.StateProvince&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;WHERE&lt;/span&gt;    Person.StateProvince.CountryRegionCode = @CountryRegionCode&lt;/pre&gt;&lt;pre class="alteven"&gt;    &lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;RETURN&lt;/span&gt; @&lt;span class="kwrd"&gt;Result&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;END&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;GO&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; Name &lt;span class="kwrd"&gt;AS&lt;/span&gt; Country, dbo.fnRegionsToString(CountryRegionCode) States&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt;         Person.CountryRegion&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_6351);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_6351);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard8c68874e5a6244f7bd3fb1bbcbeb9b00_6351 = CopyToClipboard_Strip('IF  EXISTS (SELECT * FROM dbo.sysobjects WHERE [id] = OBJECT_ID(N\'[dbo].[fnRegionsToString]\') AND type in (N\'FN\', N\'IF\', N\'TF\', N\'FS\', N\'FT\'))    DROP FUNCTION dbo.fnRegionsToStringGO CREATE FUNCTION dbo.fnRegionsToString(    @CountryRegionCode varchar(5))RETURNS varchar(Max)ASBEGIN     DECLARE @result varchar(max)     SELECT    @result = coalesce(@result + \', \', \'\') + Name    FROM    Person.StateProvince    WHERE    Person.StateProvince.CountryRegionCode = @CountryRegionCode        RETURN @ResultENDGO SELECT Name AS Country, dbo.fnRegionsToString(CountryRegionCode) StatesFROM         Person.CountryRegion');
					&lt;/script&gt;
&lt;p&gt;This makes for a very clean solution to an otherwise painful problem. So the next time you need to turn a lot of records into a single one, check to see if this technique can help.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx&amp;amp;title=Turn multiple rows into a single string in SQL Server" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/5SdCbStZ3Hc" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/5SdCbStZ3Hc/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</guid>
      <pubDate>Fri, 27 Jun 2008 22:56:56 -0800</pubDate>
      <category>SQL</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</pingback:target>
      <slash:comments>8</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/27/Turn-multiple-rows-into-a-single-string-in-SQL-Server.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=47bbbfdf-4c84-464f-9fb8-58a2427f5c3a</feedburner:origLink></item>
    <item>
      <title>Modeling many-to-one (M:1) entity relationships Part II</title>
      <description>&lt;p&gt;This is the second part of the series which discusses the issues around modeling M:1 (many-to-one) relationships. If you've not read the first part, then its advisable that you read that first before continuing with this part. To keep up to date with this and other blog's you might consider registering with the &lt;a title="The dotNetProfessional RSS feed." href="http://www.dotnetprofessional.com/blog/syndication.axd"&gt;RSS feed&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/post/2008/06/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx"&gt;Part I: The Problem&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part III: BusinessKey as a value type&lt;/p&gt; &lt;h2&gt;Suggested Solution&lt;/h2&gt; &lt;p&gt;Having covered the issues with M:1 relationships and the three different types I'll now present a potential solution which provides the necessary foreign key information, but in a more domain model fashion. I'll also point out yet another issue with the original logical model when it comes to actually using it, which I'll also offer up a solution for. &lt;/p&gt; &lt;p&gt;Remembering the tree types of M:1 relationships discussed previously, lets see how we can treat them differently:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Reference: &lt;/strong&gt;As a reference table will typically (should only have one significant column; which must be unique!) only have one column which we can map to as a string just like we did in the logical model. The effect is that instead of having OrderTypeID we have OrderTypeName, both values are unique and therefore provide a 'key' to the OrderType table. As there's nothing else of real interest in the OrderType table, returning only a single field and merging it into the main entity poses little issue but does provide a much more meaningful value than some arbitrary key. In many cases this can avoid a second call to a service or database as we already have the pertinent information.  &lt;li&gt;&lt;strong&gt;Enum:&lt;/strong&gt; An enum table is also much like the reference table, the only difference being that we can also record all the known values as an enum and tie this enum to the entity exactly like we did in the logical model. When saving the data however, we don't attempt to save the enums number value but its name. That is we send &lt;em&gt;Processing&lt;/em&gt; not &lt;em&gt;1&lt;/em&gt;, as the number may have little connection to the back end database, and again we want to remove our system keys as much as possible. Therefore the save is exactly the same as it would be for a reference type, we just represent the 'string' value differently as we know what the allowable ones are.  &lt;li&gt;&lt;strong&gt;Entity:&lt;/strong&gt; The entity type is the most interesting of the types. If you look at the original model vs the one produced by Linq to SQL, you might be thinking, well its basically the same what's wrong with that? Well a few things actually which is the topic of the next section.&lt;/li&gt;&lt;/ul&gt; &lt;h3&gt;Modeling M:1 Entities&lt;/h3&gt; &lt;p&gt;As suggested, modeling reference and enum types are fairly straightforward just requiring an extra join to get the necessary information (which is worth it as the information is useful!). However, I've indicated that the seemingly correct entity M:1 has some issues. The issues I see are:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;The parent entity still has the child key which is a system key, and is most likely useless to a business person.  &lt;li&gt;If you've adopted the Linq to SQL pattern you have the same issues as already discussed with sync issues etc.  &lt;li&gt;If you want to create a new child entity and associate it to the parent you either have to create the entity first (thereby getting its key) or using the Linq to SQL model and attach a new child entity object; which should work fairly well.  &lt;li&gt;Alternative designs may remove the foreign key from the parent and rely on the child telling the parent what the key is. The issue with this is that you must have a full entity as the child even if you are only concerned with the parent. Also adding the association requires the full entity which may not be available at the time of creating a new entity.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In the past I've tended to treat entity M:1 relationships as reference relationship types with a single key from the entity being used as its business key. This works fairly well, that is until you get an entity that has a business key that maps to more than a single column, which unfortunately happens quite often. In these occasions, I tended to use the entities GUID if it has one or revert to the system key (hey I need something!). As I didn't want the burden of having to retrieve an entire entity just so I know the keys.&lt;/p&gt; &lt;p&gt;So while having the entire entity would be nice and does better represent our original model it poses a number of limitations especially if you just want to associate a pre-existing child entity to a parent. What would be good is to have just the keys, but then be able to upscale to the full entity when the use case requires it. This is exactly what I propose as the solution to this issue. Instead of having a single value to represent a complex entities M:1 relationship we have what I'm calling a business key entity which only knows about the &lt;strong&gt;unique&lt;/strong&gt; business key for that entity and it acts like a value type. The parent then has a relationship with this business key entity not the full entity. Initially I thought an interface could be used to avoid having a separate business entity but as it turns out you can't serialize a property that has an interface as its return type. That basically means in order to support polymorphism (ie the ability to upscale) we have to use implementation inheritance. The original model is demonstrated below using this new technique:&lt;/p&gt; &lt;p&gt;&lt;a title="Model using suggested approach" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_A15E/Model_2.jpg" rel="lightbox"&gt;&lt;img height="210" alt="Model using suggested approach" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_A15E/Model_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;For those who prefer to look at code rather than diagrams, here's how the class for the OrderDetail class and Product business key classes look. The other classes follow a similar pattern, if you are keen to see how all the code looks, leave an email and I'll try bundle it all up:&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;div class="csharpcode-wrapper"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OrderDetailBusinessKey &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Int32 _orderDetailID;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;     &lt;span class="rem"&gt;//  Business key constructor&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetailBusinessKey(System.Int32 orderDetailID)&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;         _orderDetailID = orderDetailID;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetailBusinessKey(){}&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Int32 OrderDetailID&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;         get {&lt;span class="kwrd"&gt;return&lt;/span&gt; _orderDetailID;}&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;         set {_orderDetailID = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt; [Serializable]&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; OrderDetail&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;     : OrderDetailBusinessKey&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Private Variables&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; OrderBusinessKey _order;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; ProductBusinessKey _product;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Int32 _quantity;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Decimal _price;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.Decimal _total;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;     &lt;span class="rem"&gt;// Variables for relationships&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Constructors&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderDetail()&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;         &lt;span class="kwrd"&gt;this&lt;/span&gt;.Initialize();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  38:&lt;/span&gt;     &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:&lt;/span&gt;     &lt;span class="rem"&gt;/// This code initializes the domain value types for the generated properties&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  40:&lt;/span&gt;     &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:&lt;/span&gt;     &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  42:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:&lt;/span&gt;         _order = &lt;span class="kwrd"&gt;new&lt;/span&gt; bl.OrderBusinessKey();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  44:&lt;/span&gt;         _product = &lt;span class="kwrd"&gt;new&lt;/span&gt; bl.ProductBusinessKey();&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  46:&lt;/span&gt;         &lt;span class="rem"&gt;// Call the Initialize routine in the partial class&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:&lt;/span&gt;         &lt;span class="kwrd"&gt;this&lt;/span&gt;.ExtendedInitialize();&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  48:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  50:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:&lt;/span&gt;     &lt;span class="preproc"&gt;#region&lt;/span&gt; Public Properties&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  52:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  54:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; OrderBusinessKey Order&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  56:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _order; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:&lt;/span&gt;         set { _order = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  58:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  60:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey Product&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  62:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _product; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:&lt;/span&gt;         set { _product = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  64:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  66:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Int32 Quantity&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  68:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _quantity; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:&lt;/span&gt;         set { _quantity = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  70:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  72:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Decimal Price&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  74:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _price; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  75:&lt;/span&gt;         set { _price = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  76:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  77:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  78:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.Decimal Total&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  79:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  80:&lt;/span&gt;         get { &lt;span class="kwrd"&gt;return&lt;/span&gt; _total; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  81:&lt;/span&gt;         set { _total = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  82:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  83:&lt;/span&gt;     &lt;span class="preproc"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  84:&lt;/span&gt; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  85:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  86:&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ProductBusinessKey &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  87:&lt;/span&gt; {&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  88:&lt;/span&gt;     &lt;span class="kwrd"&gt;private&lt;/span&gt; System.String _productName;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  89:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  90:&lt;/span&gt;     &lt;span class="rem"&gt;//  Business key constructor&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  91:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey(System.String productName)&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  92:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  93:&lt;/span&gt;         _productName = productName;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  94:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  95:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; ProductBusinessKey(){}&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  96:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  97:&lt;/span&gt;     &lt;span class="kwrd"&gt;public&lt;/span&gt; System.String ProductName&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  98:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  99:&lt;/span&gt;         get {&lt;span class="kwrd"&gt;return&lt;/span&gt; _productName;}&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt; 100:&lt;/span&gt;         set {_productName = &lt;span class="kwrd"&gt;value&lt;/span&gt;; }&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt; 101:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt; 102:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard289196bca4be4cd6bc0057830de5beaf_6350);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard289196bca4be4cd6bc0057830de5beaf_6350);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard289196bca4be4cd6bc0057830de5beaf_6350 = CopyToClipboard_Strip('public partial class OrderDetailBusinessKey    2: {   3:     private System.Int32 _orderDetailID;   4:     5:     //  Business key constructor   6:     public OrderDetailBusinessKey(System.Int32 orderDetailID)   7:     {   8:         _orderDetailID = orderDetailID;   9:     }  10:     public OrderDetailBusinessKey(){}  11:    12:     public System.Int32 OrderDetailID  13:     {  14:         get {return _orderDetailID;}  15:         set {_orderDetailID = value; }  16:     }  17: }  18:    19: [Serializable]  20: public partial class OrderDetail  21:     : OrderDetailBusinessKey  22: {  23:     #region Private Variables  24:     private OrderBusinessKey _order;  25:     private ProductBusinessKey _product;  26:     private System.Int32 _quantity;  27:     private System.Decimal _price;  28:     private System.Decimal _total;  29:     // Variables for relationships  30:     #endregion  31:    32:     #region Constructors  33:     public OrderDetail()  34:     {  35:         this.Initialize();  36:     }  37:    38:     /// &amp;lt;summary&amp;gt;  39:     /// This code initializes the domain value types for the generated properties  40:     /// &amp;lt;/summary&amp;gt;  41:     protected virtual void Initialize()  42:     {  43:         _order = new bl.OrderBusinessKey();  44:         _product = new bl.ProductBusinessKey();  45:    46:         // Call the Initialize routine in the partial class  47:         this.ExtendedInitialize();  48:     }  49:     #endregion  50:    51:     #region Public Properties  52:    53:    54:     public OrderBusinessKey Order  55:     {  56:         get { return _order; }  57:         set { _order = value; }  58:     }  59:    60:     public ProductBusinessKey Product  61:     {  62:         get { return _product; }  63:         set { _product = value; }  64:     }  65:    66:     public System.Int32 Quantity  67:     {  68:         get { return _quantity; }  69:         set { _quantity = value; }  70:     }  71:    72:     public System.Decimal Price  73:     {  74:         get { return _price; }  75:         set { _price = value; }  76:     }  77:    78:     public System.Decimal Total  79:     {  80:         get { return _total; }  81:         set { _total = value; }  82:     }  83:     #endregion  84: }  85:    86: public partial class ProductBusinessKey   87: {  88:     private System.String _productName;  89:    90:     //  Business key constructor  91:     public ProductBusinessKey(System.String productName)  92:     {  93:         _productName = productName;  94:     }  95:     public ProductBusinessKey(){}  96:    97:     public System.String ProductName  98:     {  99:         get {return _productName;} 100:         set {_productName = value; } 101:     } 102: }');
					&lt;/script&gt;
&lt;p&gt;At first glance this might seem overly complex, but if you think about what's happening its not. The perceived complexity comes from the fact that every 'entity' now has a base business key class. While I've shown them all on the diagram, in general they wouldn't need to be seen, just knowing that the property is type ProductBusinessKey would be enough without actually showing the relationship. However, looking at the model, we can see that all but the primary key IDs have been eliminated from our domain model and it looks surprisingly similar to what our original logical model looked like. This approach provides a number of benefits despite its slightly more complex model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Flexible persistence:&lt;/strong&gt; You can add either an existing entity to a parent via its business key or the entire entity. The code used to persist the relationship can simply check what its type is to determine if a full entity needs updating/saving or just an association is required based on the business key. Also you don't have the duplication of keys, so you can write Order.Status = Status.Shipped or even OrderDetail.Product.ProductName = "Product B" (assuming you are using the BusinessKey not the full entity) which seems very intuitive. 
&lt;li&gt;&lt;strong&gt;Eliminate foreign key IDs:&lt;/strong&gt; Although its true that some entities don't have business or natural keys. In these situations, you're left with either using a GUID if available or the system primary key. 
&lt;li&gt;&lt;strong&gt;Entities are more useful:&lt;/strong&gt; Your entities now having gotten rid of meaningless keys (from the business perspective) can do more without requesting more data from the server. Ie if you wanted to list the OrderDetails chances are you could get away with displaying OrderDetail.Product.ProductName to the user and not have to worry about retrieving more detail about a product unless specifically requested. 
&lt;li&gt;&lt;strong&gt;SOA friendly:&lt;/strong&gt; This design is more friendly as the entities resemble documents more than they represent a table, as such they make for a much friendlier XML representation which is now human readable ie instead of seeing IDs for products you'll see the actual product names.&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;So what's the downside of the approach? From what I can see the main downside is the amount of effort required to make it all work. There are a lot more classes that need creating and you do have to do some extra joins in your selects too; however I believe it reduces complexity overall as the model is more natural and cleaner to work with. However, these issues can be mitigated via code generation, and the good news is that I'll be releasing something fairly soon (notice the vague reference) that implements this model. The sample above was completely code generated. If anyone is interested in being an alpha/beta tester, send me an email via the contacts page or leave a comment.&lt;/p&gt;
&lt;p&gt;While this might look like the end of the discussion, there are still a few things that need addressing including inheritance and the concept of the business key as a value type. These will be covered in the last part of this series, so check back soon.&lt;/p&gt;
&lt;p&gt;This discussion is to obtain feedback on how others feel about the approach I'm taking with my models and open a discussion on how best to model these M:1 relationships. I look forward to any feedback, positive or negative on the approach.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part II" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/BkawZ5avUk4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/BkawZ5avUk4/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</guid>
      <pubDate>Wed, 25 Jun 2008 19:00:13 -0800</pubDate>
      <category>.NET 2.0</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/25/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=52ca981c-db9f-46b7-87fd-faf8ed7dcfe8</feedburner:origLink></item>
    <item>
      <title>Modeling many-to-one (M:1) entity relationships Part I</title>
      <description>&lt;p&gt;Designing a domain model can be a tough job and if you're lucky enough to start from scratch then it becomes even tougher once you apply it to the physical database model. Over the next few posts I' like to discuss the issues we encounter when modeling this relationship type, examine the way its 'normally' done and then present an alternative that I believe presents a more domain model centric view of the world. The series will be broken up into the following sections, with this being the first. To keep up to date with this and other blog's you might consider registering with the &lt;a title="The dotNetProfessional RSS feed." href="http://www.dotnetprofessional.com/blog/syndication.axd"&gt;RSS feed&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Part I: The Problem&lt;/p&gt; &lt;p&gt;&lt;a title="Part II: Suggested Solution" href="http://www.dotnetprofessional.com/blog/post/2008/06/Modeling-many-to-one-(M1)-entity-relationships-Part-II.aspx"&gt;Part II: Suggested Solution&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Part III: BusinessKey as a value type&lt;/p&gt; &lt;p&gt;The main issue when designing a domain model is that they don't have these oddities called foreign keys, as the relationships are known by association. However, once you turn your domain model into a database schema we have to start adding all these extra keys, which get worse when you have a M:M (many-to-many) relationship! In this post I'd like to discuss how we normally model the M:1 (many-to-one) relationship and its pitfalls. &lt;/p&gt; &lt;h2&gt;The Problem&lt;/h2&gt; &lt;p&gt;When designing a domain model (entity model) in UML its unlikely that you'd include foreign key relationships as part of your design as this is a database concept rather than a domain concept. If we take a very simple and arguably contrived example (its very basic just to highlight the concepts I want to discuss) of an Order it might look something like this (note I'm using the VS class designer which doesn't support multiplicities hence I have to use two associations to highlight relationships):&lt;/p&gt; &lt;p&gt;&lt;a title="Logical Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/LogicalModel_2.jpg" rel="lightbox"&gt;&lt;img height="244" alt="Logica Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/LogicalModel_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;In this example we have three different types of M:1 relationships being modeled, which are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Entity &lt;/strong&gt;- The OrderDetail --&amp;gt; Product and Oder--&amp;gt;Customer are M:1 relationships which map to other entities within the business domain.  &lt;li&gt;&lt;strong&gt;Reference &lt;/strong&gt;- The Order.OrderType property is one that is restricted by a known set of values. However, this set of values can change over the life time of the application. That is its data driven and so the current values can't be coded directly within the application. Also a reference value is usually defined as a single field with no other business properties.  &lt;li&gt;&lt;strong&gt;Enum&lt;/strong&gt; - The Order.Status property is also restricted by a known set of values. However, unlike a reference type the values don't or can't change. These values typically drive logic which is set during design, adding a new value after deployment wouldn't add value as the application wouldn't know what to do with it. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Now that I've defined the different M:1 relationship types, they would typically be modeled in the database all the same way as foreign key constraints to their respective tables. The following diagram shows the ER (Entity Relationship) diagram of the physical database model.&lt;/p&gt; &lt;p&gt;&lt;a title="Physical Database Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/PhysicalModel_2.jpg" rel="lightbox"&gt;&lt;img height="251" alt="Physical Database Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/PhysicalModel_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;So the next step in modeling our sample is to create the actual business entities that we can use in a real application, taking into account how our data is physically stored so that we can map our logical to the physical as easy as possible. This of course is where things typically start to deviate from our nice logical model. We have to take these foreign keys into consideration as the database needs them, so typically we end up with something more like the following figure than our original logical model. The following was created using Linq for SQL, which like most O/RMs (the Entity Framework will improve on this) will create something like the following:&lt;/p&gt; &lt;p&gt;&lt;a title="Linq to SQL Model" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/Linq-Model_2.jpg" rel="lightbox"&gt;&lt;img height="341" alt="Linq to SQL Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ModelingmanytooneM1entityrelationshipsPa_8644/Linq-Model_thumb.jpg" width="580"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;You'll notice from this model that it more resembles the database model than it does our original logical model. We have an extra entity in the OrderType which we'd probably have in our logical too, to allow for maintenance but we didn't need to tie this object to our Order entity. The changes that were made to our original model can be summarized as:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Simple types are now complex types, namely instead of a simple enum or string we now have full entities with their associated complexities.  &lt;li&gt;Our 'domain' entities now have system keys liberally scattered throughout to support persistence back to the database. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;We also have the following issues as a result of this:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;We expose a lot of internal information about our database when we expose foreign keys, exposing this data presents a security risk as a hacker may attempt to corrupt your data by altering the primary or foreign keys. This becomes a bigger issue when you expose your data via web services.&amp;nbsp; &lt;li&gt;In the case of Linq to SQL we also have duplication of foreign key fields, namely we have both an OrderTypeID (foreign key field) and an object reference to the OrderType entity. This just looks plain ugly! Also lets say you want to change the OrderType to a different one, if you change the OrderTypeID from 1 to 2, and you did have an OrderType entity associated at the time, you'd be out of sync! The entity version of the OrderType wouldn't match the change you've just made. In the Linq to SQL architecture you're not even allowed to change the foreign key once its been set! You have to change the OrderType entity which will then update the Order.OrderTypeID. Which only goes to highlight the problems. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;So now that I've expressed the issue and the potential problems with this type of design which is an all to common pattern, with the exception of the double foreign key reference that Linq to SQL uses . The question becomes why? The reasons as I see it are two fold:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Effort, it takes some effort to design more closely to the original logical model  &lt;li&gt;Architectural/Technical in that we need those damn keys, so the issue is how do we make a nicer model without loosing the essential information we need? &lt;/li&gt;&lt;/ol&gt; &lt;p&gt;The next part of the series will examine what we can do to fix this situation and bring our model back in line with what we originally intended.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx&amp;amp;title=Modeling many-to-one (M:1) entity relationships Part I" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/ci5J6Ej9aPU" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/ci5J6Ej9aPU/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</guid>
      <pubDate>Sun, 22 Jun 2008 13:06:18 -0800</pubDate>
      <category>.NET 2.0</category>
      <category>Framework</category>
      <category>Modeling</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</pingback:target>
      <slash:comments>11</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/06/22/Modeling-many-to-one-(M1)-entity-relationships-Part-I.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=df81b12d-6a6c-48a9-b568-e67a5869d93e</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=df81b12d-6a6c-48a9-b568-e67a5869d93e</feedburner:origLink></item>
    <item>
      <title>Create a full entity class diagram with a T4 template</title>
      <description>&lt;p&gt;I've just released another sample for the Database Explorer API, this time using the built in features of Visual Studio 2008 (should work with VS 2005 with a download of the SDK). Visual Studio 2008 comes with a built in code generator known as T4. While the built in editing experience leaves a bit to be desired the free &lt;a href="http://www.t4editor.net/" target="_blank"&gt;T4 editor&lt;/a&gt; by Clarius Consulting goes a long way to making it workable. If you download the editor, it indicates that the time bomb expires in Jan 1, 2008; this however isn't the case as they're still working on the next release.&lt;/p&gt; &lt;p&gt;This sample creates a fairly decent (not perfect by any means) set of entities which you can then easily drop on to a class designer and get a good feel for how your domain model looks. It has support for all but the recursive relationship type, which could be added as the API does support this. This sample is provided to show how much you can do with both T4 and the API in only a small amout of code. I've included a screen shot from the Adventure Works sample, which as you can see supports many relationship types. The sample download includes the results run against the AdventureWorks sample database.&lt;/p&gt; &lt;p&gt;To download the new sample visit the projects &lt;a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=dnpFramework&amp;amp;ReleaseId=11811" target="_blank"&gt;CodePlex page&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Remember to provide as much feed back on the samples and API as you can. Enjoy!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/CreateafullentityclassdiagramwithaT4temp_13FDE/Entity%20Model_2.png" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="134" alt="Entity Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/CreateafullentityclassdiagramwithaT4temp_13FDE/Entity%20Model_thumb.png" width="244" border="0"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx&amp;amp;title=Create a full entity class diagram with a T4 template" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/5PKSGY726sc" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/5PKSGY726sc/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</guid>
      <pubDate>Wed, 26 Mar 2008 05:42:02 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <category>Visual Studio</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</pingback:target>
      <slash:comments>7</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/26/Create-a-full-entity-class-diagram-with-a-T4-template.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=7f5ad734-97df-4e9b-90d7-cd7019ca5f32</feedburner:origLink></item>
    <item>
      <title>Learning DSL tools with Videos!</title>
      <description>&lt;p&gt;I'm in the process of getting up to speed with DSL tools, and while there's a whole lot of info out there, at the end of a long day I'd prefer to watch a video on a new subject rather than pour over the written docs, but trying to locate all the video's can be difficult, and even more if you want to view them in the right order. Well this is my effort to make things a little easier. Unless otherwise stated these videos's relate to Visual Studio 2008 edition of DSL tools, as I discover more DSL video's I'll add them to the list. If you know of a good one I've missed, leave a comment and I'll get it added. &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Presenter:&amp;nbsp; &lt;/strong&gt;&lt;a href="http://hilton.giesenow.com/" target="_blank"&gt;&lt;strong&gt;Hilton Giesenow&lt;/strong&gt;&lt;/a&gt;&lt;em&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/4/f/2/4f2c5ab5-f95a-40e7-8e08-d427f7ef29d7/WinVideo-Extensibility-CreateAndUseT4Templates.wmv" target="_blank"&gt;How Do I: Create And Use T4 Templates?&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;&amp;nbsp;&lt;/h3&gt; &lt;p&gt;&lt;strong&gt;Presenter: &lt;/strong&gt;&lt;a href="http://www.alchemysoftware.co.za" target="_blank"&gt;&lt;strong&gt;Dylan Miles&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/7/1/2/712cdc62-1cb4-4282-bf75-a12fc7d4803f/WinVideo-Extensibility-DSLTools-GettingStarted.wmv" target="_blank"&gt;How Do I: Get Started with the Visual Studio Domain Specific Languages?&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/0/5/3/053d7a6b-d845-47f9-8f10-4aada2264a6e/WinVideo-Extensibility-DSLTools-CreateAndCustomize.wmv"&gt;How Do I: Create and Customize My Domain Specific Language?&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/d/5/c/d5ce892e-447e-46e4-a496-990ebf40d4d0/WinVideo-Extensibility-DSLTools-AdvancedCustomization.wmv" target="_blank"&gt;How Do I: Use Advanced Customization?&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/4/2/a/42aaf634-df86-47cf-a9b4-8dbf84c3cdff/WinVideo-Extensibility-DSLTools-GeneratingCode.wmv" target="_blank"&gt;How Do I: Generate Code from my Domain Specific Language Using DSL Tools?&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;a href="http://download.microsoft.com/download/8/f/8/8f89212c-7ef2-4631-84e8-eb26742bb2a2/WinVideo-Extensibility-MultiProjectTemplate.wmv" target="_blank"&gt;How Do I: Create a Multi Project Template?&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;For those interested in DSL tools and need a rich database schema API to go with it, I've developed the &lt;a href="http://www.dotnetprofessional.com/blog/post/2008/03/Database-Explorer-API-beta-released.aspx"&gt;Database Explorer API&lt;/a&gt; which provides a rich model to access your database schemas. This API is part of the larger &lt;a href="http://www.dotnetprofessional.com/blog/page/dnpFramework.aspx"&gt;dnp.Framework&lt;/a&gt; which will also include a Domain Model API amongst other things. Register for the &lt;a href="http://www.dotnetprofessional.com/blog/syndication.axd" target="_blank"&gt;RSS feed&lt;/a&gt; to keep updated on any updates.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx&amp;amp;title=Learning DSL tools with Videos!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx&amp;amp;title=Learning DSL tools with Videos!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx&amp;amp;title=Learning DSL tools with Videos!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/OaR-2Bm_bf4" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/OaR-2Bm_bf4/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=805828dc-95ab-4a19-bf49-305189f793f0</guid>
      <pubDate>Fri, 21 Mar 2008 08:35:20 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>Framework</category>
      <category>Visual Studio</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=805828dc-95ab-4a19-bf49-305189f793f0</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=805828dc-95ab-4a19-bf49-305189f793f0</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/21/Learning-DSL-tools-with-Videos!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=805828dc-95ab-4a19-bf49-305189f793f0</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=805828dc-95ab-4a19-bf49-305189f793f0</feedburner:origLink></item>
    <item>
      <title>Database Explorer API beta released</title>
      <description>&lt;p&gt;For anyone that's read my blog entries you've seen me make mention to a framework that I've been working on. Well today marks the release of the first beta of part of that framework. The Database Explorer API, is a database schema API that is designed to make accessing database schema information easy and intuitive. &lt;/p&gt; &lt;p&gt;The API has support for schemas, tables, views, indexes, constraints, relationships ie 1-1, 1-M, M-M, M-1 and recursion. While its original goal was as a replacement for the SchemaExplorer API provided with the Code Smith product, its uses are most definitely not limited to code generation. The API has no dependencies on any other libraries except the ones required to run your database. So if you're a user of &lt;a title="MyGeneration code generation tool" href="http://www.mygenerationsoftware.com/portal/default.aspx" target="_blank"&gt;MyGeneration&lt;/a&gt;, &lt;a title="ArchAngel is a top tier code generation tool with advanced features" href="http://www.slyce.com/ArchAngel/" target="_blank"&gt;ArchAngel&lt;/a&gt; or some other code generation tool, or even if you want to use it in a windows form application you'll only have to reference the dll's to get started; oh and its free too!&lt;/p&gt; &lt;p&gt;The API is fairly complete but does lack support for stored procedures, functions, and retrieving contents of views. However, these are slated for a future release and any feed back on which are more important would be appreciated.&lt;a href="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/DatabaseExplorerAPIbetareleased_F19A/ConsoleSample_2.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 10px 5px 10px 10px; border-right-width: 0px" height="125" alt="ConsoleSample" src="http://dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/DatabaseExplorerAPIbetareleased_F19A/ConsoleSample_thumb.jpg" width="244" align="right" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;At present the API is in beta and only supports SQL Server 2005, however the provider model being used can easily be used to support other databases. If you are working with another database I'd be happy to work with you to get that database supported.&lt;/p&gt; &lt;p&gt;I've tried to supply a reasonable about of documentation and a few samples (which I'll blog about in more detail over the next week or so) to help get you up and running fast, because I know if it takes more than 10 minutes to get a feel for something, its probably too hard. For those not familiar with Code Smith I've just completed a sample using a console app so you can see it works as easy without Code Smith. The sample is the same as the one detailed in the &lt;a title="Code Smith samples tutorial" href="http://www.dotnetprofessional.com/blog/page/blog/page/Database-Explorer-API-Overview.aspx"&gt;API overview&lt;/a&gt; so check that out for more details.&lt;/p&gt; &lt;p&gt;As this is a beta I welcome all feed back, positive or negative (though keep it constructive) and I intend to keep releasing updates regularly. To keep updated, I'd recommend registering with the &lt;a title="Register for this blogs RSS feed." href="blog/syndication.axd" target="_blank"&gt;rss feed&lt;/a&gt;. The following links provide you with more information about the current release and what to expect in future releases.&lt;/p&gt; &lt;p&gt;&lt;a title="dnp.Framework" href="blog/page/dnpFramework.aspx"&gt;dnp.Framework&lt;/a&gt;&amp;nbsp; - Provides a summary of the framework and its components. You can also download the framework here.&lt;/p&gt; &lt;p&gt;&lt;a href="blog/page/Database-Explorer-API-Overview.aspx"&gt;Database Explorer API Overview&lt;/a&gt; - provides an overview of the API and a covers one of the samples within the API.&lt;/p&gt; &lt;p&gt;&lt;a title="Database Explorer API" href="blog/page/Database-Explorer-API-(beta).aspx"&gt;Database Explorer API&lt;/a&gt; - Provides more detailed information about the API including a class diagram. (work in progress)&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Download: &lt;a href="http://www.dotnetprofessional.com/blog/file.axd?file=Database+Explorer+-+Console+Sample.zip"&gt;Database Explorer - Console Sample.zip (39.42 kb)&lt;/a&gt;  &lt;p&gt;.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx&amp;amp;title=Database Explorer API beta released" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx&amp;amp;title=Database Explorer API beta released" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx&amp;amp;title=Database Explorer API beta released" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/ZVlB8WGhoE8" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/ZVlB8WGhoE8/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=80c6fcea-3004-4303-9915-62920ffb9870</guid>
      <pubDate>Mon, 17 Mar 2008 17:10:56 -0800</pubDate>
      <category>.NET 2.0</category>
      <category>Framework</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=80c6fcea-3004-4303-9915-62920ffb9870</pingback:target>
      <slash:comments>19</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=80c6fcea-3004-4303-9915-62920ffb9870</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/17/Database-Explorer-API-beta-released.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=80c6fcea-3004-4303-9915-62920ffb9870</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=80c6fcea-3004-4303-9915-62920ffb9870</feedburner:origLink></item>
    <item>
      <title>Did you forget something when you deployed your ASP.NET App?</title>
      <description>&lt;p&gt;While I don't normally get involved with deploying web applications (we normally have 'people' for that) however I did have to deploy the application you're using now. Which brings me to the blog post I recently found which discusses the top 10 best practices for ASP.NET which I've linked to on my &lt;a title="Toolbox with useful links and information." href="http://www.dotnetprofessional.com/blog/pages/toolbox.aspx" target="_blank"&gt;toolbox&lt;/a&gt; page. The main one that concerned was of concern to me was forgetting to switch off debug mode. &lt;/p&gt; &lt;div class="csharpcode-wrapper"&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;compilation&lt;/span&gt; &lt;span class="attr"&gt;debug&lt;/span&gt;&lt;span class="kwrd"&gt;="false"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;system.web&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard59be978bbc354ca78890e2970faab803_517);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard59be978bbc354ca78890e2970faab803_517);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard59be978bbc354ca78890e2970faab803_517 = CopyToClipboard_Strip('&amp;lt;system.web&amp;gt;   2:   &amp;lt;compilation debug="false" /&amp;gt;   3: &amp;lt;/system.web&amp;gt;');
					&lt;/script&gt;
&lt;p&gt;This setting appears to have a large impact on production web sites so I'd check out the detail in the &lt;a href="http://blogs.msdn.com/tess/archive/2006/04/13/575364.aspx" target="_blank"&gt;this post&lt;/a&gt; to get all the details. Also you might want to check the config files of the production apps you work on or blog if you host your own; lets just say we may need to update a few of ours!&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx&amp;amp;title=Did you forget something when you deployed your ASP.NET App?" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx&amp;amp;title=Did you forget something when you deployed your ASP.NET App?" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx&amp;amp;title=Did you forget something when you deployed your ASP.NET App?" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/sh0NvLP1sr0" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/sh0NvLP1sr0/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=c2eb8598-2ec5-43e6-aabc-5e25e26d0746</guid>
      <pubDate>Sat, 15 Mar 2008 04:54:28 -0800</pubDate>
      <category>.NET 1</category>
      <category>.NET 2.0</category>
      <category>.NET 3.5</category>
      <category>ASP.NET</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=c2eb8598-2ec5-43e6-aabc-5e25e26d0746</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=c2eb8598-2ec5-43e6-aabc-5e25e26d0746</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/15/Did-you-forget-something-when-you-deployed-your-ASPNET-App.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=c2eb8598-2ec5-43e6-aabc-5e25e26d0746</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=c2eb8598-2ec5-43e6-aabc-5e25e26d0746</feedburner:origLink></item>
    <item>
      <title>Visual Studio Extensibility (VSX) gets serious!</title>
      <description>&lt;p&gt;I went along to the &lt;a href="http://www.netda.net/" target="_blank"&gt;.NET developers association&lt;/a&gt; in Redmond on Monday where &lt;a href="http://blogs.msdn.com/klevy" target="_blank"&gt;Ken Levy&lt;/a&gt; demonstrated the extensibility tools of VS.NET 2008 (which also relates to VS 2005 to some extent). It seems that MS have decided to offer the VS 2008 shell license free! If you're anyone who's looking at providing third party tools (related or not to Visual Studio) and need a good IDE host, you've just saved yourself a bucket load of time. Also, it runs in two modes, integrated (merges with your instance of VS 2008) or isolated where it acts as its own (customisable too I was led to believe) IDE without the need for VS 2008. &lt;/p&gt;  &lt;p&gt;If you're not so inclined to use the VS Shell,&amp;#160; you may want to try adding your own custom extensions to VS to provide addition features MS haven't gotten around to yet. The API which used to be only available to partners (at a large cost - which is now free!) allows you to extend the IDE in just about any way you want. The VSX site provides links to numerous samples and they seem quite committed to building a large community around this technology, so I'd keep an eye on their &lt;a href="http://visualstudiogallery.com/" target="_blank"&gt;Visual Studio Gallery&lt;/a&gt; where the community will post their extensions.&lt;/p&gt;  &lt;p&gt;Other improvements seem to be in the area of DSLs (Domain Specific Languages) where they now provide DSL tools to build your own DSLs. This is an area I believe will become more important as people begin to realize that a lot of what we do is based on a known pattern, with customizations for a given problem.&lt;/p&gt;  &lt;p&gt;I'll be looking into how DSLs can be leveraged with the framework I'm currently developing that code gens your stored procs, entities and services. Anyway for those who are interested in learning more about these new tools I'd recommend you visit the following sites:   &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.com/vsx"&gt;http://msdn.com/vsx&lt;/a&gt; - The Visual Studio Extensibility home page&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/klevy"&gt;http://blogs.msdn.com/klevy&lt;/a&gt; - Ken Levy's blog&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;Also MS sponsored CoDe magazine for a special focus on VSX which allows you to download the full magazine which has a heap of VSX information. You can download the PDF &lt;a href="http://www.code-magazine.com/focus/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Oh should mention that the demo's are quite impressive, take a look at the &lt;a href="http://blogs.msdn.com/vsxteam/archive/2007/12/15/AddOn-Studio-for-World-of-Warcraft-released.aspx" target="_blank"&gt;World of War Craft editor&lt;/a&gt; (with its own language) using the VS Shell.&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx&amp;amp;title=Visual Studio Extensibility (VSX) gets serious!" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx&amp;amp;title=Visual Studio Extensibility (VSX) gets serious!" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx&amp;amp;title=Visual Studio Extensibility (VSX) gets serious!" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/EQ82kr7ndCQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/EQ82kr7ndCQ/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=5fd5325c-c408-407e-9304-8d43e08b4383</guid>
      <pubDate>Thu, 13 Mar 2008 02:51:39 -0800</pubDate>
      <category>.NET 3.5</category>
      <category>Visual Studio</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=5fd5325c-c408-407e-9304-8d43e08b4383</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=5fd5325c-c408-407e-9304-8d43e08b4383</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/13/Visual-Studio-Extensibility-(VSX)-gets-serious!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=5fd5325c-c408-407e-9304-8d43e08b4383</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=5fd5325c-c408-407e-9304-8d43e08b4383</feedburner:origLink></item>
    <item>
      <title>ASP.NET Dynamic Controls &amp;amp; State Management</title>
      <description>&lt;blockquote&gt;   &lt;p&gt;This article was originally published in the April 2003 issue of Visual Studio Magazine. Their online version has been archived, so it has been reproduced here. The articles code requires updating for .NET 2.0 which will be the subject of a future post.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;ASP.NET has brought about a huge change in how we as developers think about designing a web site. We all know that ASP.NET now gives us the opportunity to create reusable custom controls which we can drag and drop onto our pages, which can even remember the information entered between postbacks, using the viewstate mechanism built into ASP.NET. This has proven to be a huge advantage in designing our pages, by allowing us to bring our more traditional programming model to the Web for the first time. ASP.NET also allows us to add these same controls dynamically at runtime. &lt;/p&gt;  &lt;p&gt;The sample project which we will create is a relatively simple one, which should clearly demonstrate all the issues that you will face when trying to create dynamic controls yourself. In general Microsoft has done a good job with their architecture and made it really quite straightforward. However, there are circumstances where things do start to get somewhat more interesting, and we will tackle this area in detail so that you will be armed with all the knowledge you need to tackle any dynamic control issue.&lt;/p&gt;  &lt;h2&gt;Why Use Dynamic Controls?&lt;/h2&gt;  &lt;p&gt;The ability to add controls at runtime gives us the ability to create some very sophisticated web sites. We could for example have the home page render completely differently based on the users profile. We could also dynamically load the modules or controls that the user wanted so that the experience would be unique for each user. This is a particularly powerful technique if you need to change branding of your site dynamically. However, this is not the only use, if you were to create a Wizard, then you would want to load different screens based on the previous selection.&lt;/p&gt;  &lt;h2&gt;Creating our first Dynamic Control Page&lt;/h2&gt;  &lt;p&gt;The good news is that ASP.NET allows us to create dynamic controls very easily, well it does in part but I&amp;#8217;ll come to that later. To dynamically create a control at runtime all we need to do is use the following line of code. &lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; Me.Controls.Add(Page.LoadControl(&amp;#8220;~/MyControl.ascx&amp;#8221;)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_2313);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_2313);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_2313 = CopyToClipboard_Strip('Me.Controls.Add(Page.LoadControl(&amp;#8220;~/MyControl.ascx&amp;#8221;)');
					&lt;/script&gt;

&lt;p&gt;You should note however that the control to be loaded must be the fully qualified name otherwise you may get a file not found error. A good tip is to use the &amp;#8216;~&amp;#8217; tilde at the beginning as it is a special character which represents the root of the web application, when used with Server side controls.&lt;/p&gt;

&lt;p&gt;This is the most basic way to display a dynamic control. In the example above we just added the control to the pages control collection. However&lt;a title="Figure 1" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%201%20-%20Project%20Structure_4.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 10px 0px 10px 10px; border-right-width: 0px" height="207" alt="Figure 1 - Project Structure" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%201%20-%20Project%20Structure_thumb_1.jpg" width="244" align="right" border="0" /&gt;&lt;/a&gt;, you can do the same thing for any container control such as a Panel or Placeholder control. In most cases you will probably want to use a Panel or Placeholder as it will allow easier positioning on the page. This is precisely what we use in our sample project, see &lt;strong&gt;Figure 1&lt;/strong&gt;. As you can see we have arranged three Panel controls on the page to represent a Title, Menu/Login and Content area. This should be a familiar web design to most of you. As you can see there isn&amp;#8217;t any real visual content yet, as we will be adding this content dynamically each time the page loads. We will be creating several simple User Controls to insert into the panel areas which we can easily create in VS.NET. It should be kept in mind that these controls can comprise any number of ASP.NET Controls. To demonstrate the use of dynamic controls we will create a series of steps or screens to guide a potential user of our site through registration. To keep it simple we will assume that anyone who isn&amp;#8217;t registered will want to be and make our registration page our home page. You will I trust not replicate this in your site!&lt;/p&gt;

&lt;p&gt;Due to the time it would take to describe exactly what I&amp;#8217;ve built, I&amp;#8217;d prefer to mention the &amp;#8216;interesting&amp;#8217; points of code and ask that you download the sample project which contains all the code. For instructions on how to make use of these samples check out the sidebar.&lt;/p&gt;

&lt;h2&gt;Creating a Wizard Control&lt;/h2&gt;

&lt;p&gt;The sample consists of the following User Controls&lt;/p&gt;

&lt;table cellspacing="0" cellpadding="2" width="398" border="1"&gt;&lt;tbody&gt;
    &lt;tr&gt;
      &lt;td valign="top" width="202"&gt;Banner.ascx&lt;/td&gt;

      &lt;td valign="top" width="194"&gt;Banner no advertising&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="204"&gt;Banner_Advertising.ascx&lt;/td&gt;

      &lt;td valign="top" width="193"&gt;Banner with advertising&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="205"&gt;Wizard.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Container for each step&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="206"&gt;Wizard_Step1.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Get Username &amp;amp; Password&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="206"&gt;Wizard_Step2.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Get personal Details&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="206"&gt;Wizard_Step3.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Confirm Data Collected&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="206"&gt;Login.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Allow user to login&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td valign="top" width="206"&gt;Menu.ascx&lt;/td&gt;

      &lt;td valign="top" width="192"&gt;Sample of a menu&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;&lt;/table&gt;

&lt;p&gt;What we want to do is create a Wizard interface that we can then dynamically load our steps into at runtime. This has several advantages, namely that it keeps the code for each step simple and also allows you to change the Wizards look and feel anytime without going back to the i&lt;a title="Figure 2" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%202%20-%20Wizard%20Interface_2.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 10px 0px 10px 10px; border-right-width: 0px" height="158" alt="Figure 2 - Wizard Interface" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%202%20-%20Wizard%20Interface_thumb.jpg" width="244" align="right" border="0" /&gt;&lt;/a&gt;ndividual steps. &lt;strong&gt;Figure 2&lt;/strong&gt; shows the structure of our Wizard interface, the other controls such as the Banner are simply text written onto the control, one having some advertising the other not. All of these controls will be dynamically loaded into the Template shown in &lt;strong&gt;Figure 1&lt;/strong&gt; as previously discussed. The UseControl in the middle of the Wizard will be discussed later in the article. &lt;/p&gt;

&lt;p&gt;Looking at the Wizard template you&amp;#8217;ll notice that I&amp;#8217;ve decided to keep the traditional Wizard style interface and have a Title and Description for each step. These details will be taken from each step as it is loaded into the control. The question then arises how do we achieve this? The best way is to make use of Interfaces. As we know an Interface allows us to create a type of contract that each object that implements it must adhere to. Then when we want to reference those objects, we can be guaranteed that if they have implemented the interface that it will have at least those properties and methods defined by the interface. Another great advantage of using interfaces is that it allows us to use early binding in our code, and therefore reduces potential errors. So I&amp;#8217;ve created the IWizard interface which has the following signature (a signature is a common term to describe the properties and methods that make up an interface). 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Interface&lt;/span&gt; IWizard&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; Title() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; Description() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; NextStep() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; PreviousStep() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Interface&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_9110);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_9110);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_9110 = CopyToClipboard_Strip('Public Interface IWizard\r\n    ReadOnly Property Title() As String\r\n    ReadOnly Property Description() As String\r\n    ReadOnly Property NextStep() As String\r\n    ReadOnly Property PreviousStep() As String\r\nEnd Interface');
					&lt;/script&gt;

&lt;p&gt;I have added a few extras to help us know what the next and previous steps in the wizard are. This will help our container control (ie Wizard.ascx) know which control to load next and which buttons should be enabled etc. As this is directly related to the Wizard UI I&amp;#8217;ve put this Interface code in the Wizard.ascx file. You can see how all this code has been implemented by looking at the code behind file for the Wizard.&lt;/p&gt;

&lt;p&gt;Now that we have defined our Wizard interface we need to ensure that each step implements it. To see how this is done check &lt;strong&gt;Listing 1&lt;/strong&gt;. A thing to note about this code is how we determine the next step. In essence we check that the information entered on the screen for that step is valid. If it is then return the next step, if not then return the current step.&lt;/p&gt;

&lt;p&gt;Now that we have coded all the steps to incorporate our IWizard interface and have coded the Wizard itself, its time to see if it works. When we run our first sample application (Example1.aspx), we get a screen that should look like that of &lt;strong&gt;Figure 3&lt;/strong&gt;. Here you can see that we have loaded three controls dynamically into the Template (see &lt;strong&gt;Listing 2&lt;/strong&gt;). In this case, as the user has not logged in, they are presented with the ability to register. To keep things simple you can see that the code merely checks a QueryString parameter for a value of &amp;#8216;True&amp;#8217;.&lt;/p&gt;

&lt;h2&gt;Maintaining State between PostBacks&lt;/h2&gt;

&lt;p&gt;When we enter our details and press next we notice that we get a rather unexpected result, none of the controls we added are still there. The reason for this is because of the way we normally code our ASP.NET Form_Load events. Normally we would do the following as is the case in our first example (see &lt;strong&gt;Listing 2&lt;/strong&gt;).&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.IsPostBack &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;     &amp;#8230;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; If&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_12815);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_12815);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_12815 = CopyToClipboard_Strip('If Not Me.IsPostBack Then\r\n    &amp;#8230;\r\nEnd If');
					&lt;/script&gt;

&lt;p&gt;If we hadn&amp;#8217;t created these controls dynamically this style of coding would be both fine and preferable, as it means we don&amp;#8217;t have to do any extra work. However, this doesn&amp;#8217;t work because despite how much Microsoft have done for us, we are still living in a stateless environment, and to that end if you create something at runtime, ASP.NET won&amp;#8217;t keep track of it for you. You will need to do that for yourself. This means you can&amp;#8217;t make use of this feature as you must always recreate the controls each time. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   &lt;strong&gt;Listing 1 &amp;#8211; Wizard_Step1.ascx &lt;/strong&gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="preproc"&gt;#Region&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;IWizard Interface&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; Title() _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;         &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; &lt;span class="kwrd"&gt;Implements&lt;/span&gt; IWizard.Title&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;User Registration&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;     &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; Description() &lt;span class="kwrd"&gt;As&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;             &lt;span class="kwrd"&gt;String&lt;/span&gt; &lt;span class="kwrd"&gt;Implements&lt;/span&gt; IWizard.Description&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Please enter the Username and Password you wish to use on our site.&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;     &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; NextStep() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;             &lt;span class="kwrd"&gt;Implements&lt;/span&gt; IWizard.NextStep&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;             &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.txtName.Text.Length &amp;gt; 0 &lt;span class="kwrd"&gt;AndAlso&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;                     &lt;span class="kwrd"&gt;Me&lt;/span&gt;.txtPassword.Text.Length &amp;gt; 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;~/Wizard_Step2.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;             &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;~/Wizard_Step1.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;             &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;     &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;     &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; PreviousStep() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;             &lt;span class="kwrd"&gt;Implements&lt;/span&gt; IWizard.PreviousStep&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;Start&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt; &lt;span class="preproc"&gt;#End Region&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_14340);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_14340);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_14340 = CopyToClipboard_Strip('   Listing 1 &amp;#8211; Wizard_Step1.ascx \r\n#Region &amp;quot;IWizard Interface&amp;quot;\r\n\r\n    Public ReadOnly Property Title() _\r\n        As String Implements IWizard.Title\r\n        Get\r\n            Return &amp;quot;User Registration&amp;quot;\r\n        End Get\r\n    End Property\r\n\r\n    Public ReadOnly Property Description() As _\r\n            String Implements IWizard.Description\r\n        Get\r\n            Return &amp;quot;Please enter the Username and Password you wish to use on our site.&amp;quot;\r\n        End Get\r\n    End Property\r\n    \r\n    Public ReadOnly Property NextStep() As String _\r\n            Implements IWizard.NextStep\r\n        Get\r\n            If Me.txtName.Text.Length &amp;gt; 0 AndAlso _\r\n                    Me.txtPassword.Text.Length &amp;gt; 0 Then\r\n                Return &amp;quot;~/Wizard_Step2.ascx&amp;quot;\r\n            Else\r\n                Return &amp;quot;~/Wizard_Step1.ascx&amp;quot;\r\n            End If\r\n        End Get\r\n    End Property\r\n    \r\n    Public ReadOnly Property PreviousStep() As String _\r\n            Implements IWizard.PreviousStep\r\n        Get\r\n            Return &amp;quot;Start&amp;quot;\r\n        End Get\r\n    End Property\r\n\r\n#End Region');
					&lt;/script&gt;

&lt;p&gt;We could overcome this by removing the IF condition and it would fix our initial problem by recreating the controls during each postback, however there are still many issues that need to be resolved such as the following.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We need to keep track of the last control, load it and have its events fire before we remove it to replace it with the control for the next step. &lt;/li&gt;

  &lt;li&gt;Replace current control with the next one. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This process can start to become rather complicated and it would be much better if we were able to wrap this complexity up into a user control. This is exactly what we will be tackling next. &lt;/p&gt;

&lt;h2&gt;Creating a Dynamic Control Host Control&lt;/h2&gt;

&lt;p&gt;To make our coding life easier and to solve the problems associated with creating dynamic controls, we can create a control which handles all the more complex tasks for us. This then leaves us with a simple object model to program against. This is what we will be using in Example 2, and it makes what would otherwise be a complicated task easy.&lt;/p&gt;

&lt;p&gt;The amount of code required for our control isn&amp;#8217;t particularly large, but the concepts behind it all can be a bit confusing. I will try to explain the code presented in &lt;strong&gt;Listing 3&lt;/strong&gt;, and point out the issues as we go along. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;   &lt;strong&gt;Listing 2 &amp;#8211; Load Event of Example1.aspx&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;         &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.Load&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="rem"&gt;'Put user code to initialise the page here&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     &lt;span class="rem"&gt;' Create the page based on the user who has entered&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.IsPostBack &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;         &lt;span class="kwrd"&gt;If&lt;/span&gt; Request.QueryString(&lt;span class="str"&gt;&amp;quot;Registered&amp;quot;&lt;/span&gt;) = &lt;span class="str"&gt;&amp;quot;True&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;             &lt;span class="rem"&gt;' Top security here, you might want to do better&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;             &amp;#8216; authentication&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlBanner.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;                 Add(Page.LoadControl(&lt;span class="str"&gt;&amp;quot;~/Banner.ascx&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlMenu.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;                 Add(Page.LoadControl(&lt;span class="str"&gt;&amp;quot;~/menu.ascx&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;         &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlBanner.Controls. _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;                 Add(Page.LoadControl(&lt;span class="str"&gt;&amp;quot;~/Banner_Advertising.ascx&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlMenu.Controls.Add(Page.LoadControl(&lt;span class="str"&gt;&amp;quot;~/Login.ascx&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlContent.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;                 Add(Page.LoadControl(&lt;span class="str"&gt;&amp;quot;~/Wizard.ascx&amp;quot;&lt;/span&gt;))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_22621);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_22621);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_22621 = CopyToClipboard_Strip('   Listing 2 &amp;#8211; Load Event of Example1.aspx\r\nPrivate Sub Page_Load(ByVal sender As System.Object, _\r\n        ByVal e As System.EventArgs) Handles MyBase.Load\r\n    \'Put user code to initialise the page here\r\n    \' Create the page based on the user who has entered\r\n    If Not Me.IsPostBack Then\r\n        If Request.QueryString(&amp;quot;Registered&amp;quot;) = &amp;quot;True&amp;quot; Then\r\n            \' Top security here, you might want to do better\r\n            &amp;#8216; authentication\r\n            Me.pnlBanner.Controls. _\r\n                Add(Page.LoadControl(&amp;quot;~/Banner.ascx&amp;quot;))\r\n            Me.pnlMenu.Controls. _\r\n                Add(Page.LoadControl(&amp;quot;~/menu.ascx&amp;quot;))\r\n        Else\r\n            Me.pnlBanner.Controls. _\r\n                Add(Page.LoadControl(&amp;quot;~/Banner_Advertising.ascx&amp;quot;))\r\n            Me.pnlMenu.Controls.Add(Page.LoadControl(&amp;quot;~/Login.ascx&amp;quot;))\r\n            Me.pnlContent.Controls. _\r\n                Add(Page.LoadControl(&amp;quot;~/Wizard.ascx&amp;quot;))\r\n        End If\r\n    End If\r\nEnd Sub');
					&lt;/script&gt;

&lt;p&gt;Basically what we want the control to handle for us is the whole state management of our controls once we tell it to create it. That is once we put our DynamicControlHost.ascx on our form and tell it to dynamically load a particular control, we want to assume that when we do a post back it will just be there, and we as the user of the control don&amp;#8217;t have to worry about recreating it. In essence we want it to act like a control we placed there at design time.&lt;/p&gt;

&lt;p&gt;To start with, we create ourselves a blank User Control in VS.NET. Next we put a Panel control onto our design surface and set the width and height properties to be 100%. This will ensure that anything we put into this will use the entire area. We then want to name it and Panel1 is not my recommendation, so we will name it &amp;#8216;pnlHost&amp;#8217; which should make it somewhat easier to understand later. That&amp;#8217;s all there is to it from the UI standpoint. Now let&amp;#8217;s examine the code in &lt;strong&gt;Listing 3 &lt;/strong&gt;which contains all the code necessary to finish off the control. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;   &lt;strong&gt;Listing 3 &amp;#8211; Dynamic Host Control&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;MustInherit&lt;/span&gt; &lt;span class="kwrd"&gt;Class&lt;/span&gt; DynamicControlHost&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;Inherits&lt;/span&gt; System.Web.UI.UserControl&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="kwrd"&gt;Protected&lt;/span&gt; &lt;span class="kwrd"&gt;WithEvents&lt;/span&gt; pnlHost &lt;span class="kwrd"&gt;As&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;             System.Web.UI.WebControls.Panel&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;     Web Form Designer Generated Code Here.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;     &lt;span class="kwrd"&gt;Dim&lt;/span&gt; m_strUserControl &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;     &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; UniqueKey() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.UniqueID &amp;amp; &lt;span class="str"&gt;&amp;quot;DynamicControl&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;     &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Init2_Load(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;             System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;             &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.Init&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;         &lt;span class="rem"&gt;'Now change the ID of this control to that of what&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;         &lt;span class="rem"&gt;'it was previously if it is a postback&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;         &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Page.IsPostBack &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;             &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.UserControlPath.Length &amp;lt;&amp;gt; 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;                         Add(Page.LoadControl(&lt;span class="kwrd"&gt;Me&lt;/span&gt;.UserControlPath))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;             &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;     &lt;span class="kwrd"&gt;Property&lt;/span&gt; UserControlPath() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;             &lt;span class="kwrd"&gt;If&lt;/span&gt; m_strUserControl.Length = 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;                 &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; Request.Form(&lt;span class="kwrd"&gt;Me&lt;/span&gt;.UniqueKey) _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;                         &lt;span class="kwrd"&gt;Is&lt;/span&gt; &lt;span class="kwrd"&gt;Nothing&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;                     m_strUserControl = Request.Form(&lt;span class="kwrd"&gt;Me&lt;/span&gt;.UniqueKey)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;                 &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;             &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; m_strUserControl&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:&lt;/span&gt;         &lt;span class="kwrd"&gt;Set&lt;/span&gt;(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; Value &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  38:&lt;/span&gt;             &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls.Count &amp;gt; 0 &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:&lt;/span&gt;                 &lt;span class="rem"&gt;' check that the current control isn't the same&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  40:&lt;/span&gt;                 &lt;span class="rem"&gt;' as this new one&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:&lt;/span&gt;                 &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.UserControlPath &amp;lt;&amp;gt; Value &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  42:&lt;/span&gt;                     &lt;span class="rem"&gt;' Remove old items because we can't simply&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:&lt;/span&gt;                     &lt;span class="rem"&gt;' replace them!&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  44:&lt;/span&gt;                     &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls. _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:&lt;/span&gt;                             Remove(&lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls(0))&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  46:&lt;/span&gt;                     &lt;span class="rem"&gt;' Add New Items&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:&lt;/span&gt;                     &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  48:&lt;/span&gt;                             Add(Page.LoadControl(Value))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:&lt;/span&gt;                     &lt;span class="rem"&gt;' Store the new values&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  50:&lt;/span&gt;                     m_strUserControl = Value&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:&lt;/span&gt;                 &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  52:&lt;/span&gt;             &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls. _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  54:&lt;/span&gt;                         Add(Page.LoadControl(Value))&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:&lt;/span&gt;                 m_strUserControl = Value&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  56:&lt;/span&gt;             &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Set&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  58:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  60:&lt;/span&gt;     &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; UserControl() &lt;span class="kwrd"&gt;As&lt;/span&gt; Control&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  61:&lt;/span&gt;         &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  62:&lt;/span&gt;             &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls(0)&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  63:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  64:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  65:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  66:&lt;/span&gt;     &lt;span class="kwrd"&gt;Protected&lt;/span&gt; &lt;span class="kwrd"&gt;Overrides&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Render(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; writer &lt;span class="kwrd"&gt;As&lt;/span&gt; _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  67:&lt;/span&gt;             System.Web.UI.HtmlTextWriter)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  68:&lt;/span&gt;         &lt;span class="rem"&gt;' We want to include a HTML Form field to store the&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  69:&lt;/span&gt;         &lt;span class="rem"&gt;' current UI Object&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  70:&lt;/span&gt;         &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.Render(writer)&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  71:&lt;/span&gt;         writer.Write(&lt;span class="str"&gt;&amp;quot;&amp;lt;input type=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot; name=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &amp;amp; _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  72:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Me&lt;/span&gt;.UniqueKey &amp;amp; &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;value=&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &amp;amp; _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  73:&lt;/span&gt;                 &lt;span class="kwrd"&gt;Me&lt;/span&gt;.UserControlPath &amp;amp; &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="str"&gt;&amp;quot;/&amp;gt;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  74:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  75:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Class&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_28665);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_28665);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_28665 = CopyToClipboard_Strip('   Listing 3 &amp;#8211; Dynamic Host Control\r\nPublic MustInherit Class DynamicControlHost\r\n    Inherits System.Web.UI.UserControl\r\n    Protected WithEvents pnlHost As _\r\n            System.Web.UI.WebControls.Panel\r\n\r\n    Web Form Designer Generated Code Here.\r\n    Dim m_strUserControl As String = &amp;quot;&amp;quot;\r\n\r\n    Private ReadOnly Property UniqueKey() As String\r\n        Get\r\n            Return Me.UniqueID &amp;amp; &amp;quot;DynamicControl&amp;quot;\r\n        End Get\r\n    End Property\r\n    Private Sub Init2_Load(ByVal sender As _\r\n            System.Object, ByVal e As System.EventArgs) _\r\n            Handles MyBase.Init\r\n        \'Now change the ID of this control to that of what\r\n        \'it was previously if it is a postback\r\n        If Me.Page.IsPostBack Then\r\n            If Me.UserControlPath.Length &amp;lt;&amp;gt; 0 Then\r\n                Me.pnlHost.Controls. _\r\n                        Add(Page.LoadControl(Me.UserControlPath))\r\n            End If\r\n        End If\r\n    End Sub\r\n    Property UserControlPath() As String\r\n        Get\r\n            If m_strUserControl.Length = 0 Then\r\n                If Not Request.Form(Me.UniqueKey) _\r\n                        Is Nothing Then\r\n                    m_strUserControl = Request.Form(Me.UniqueKey)\r\n                End If\r\n            End If\r\n\r\n            Return m_strUserControl\r\n        End Get\r\n        Set(ByVal Value As String)\r\n            If Me.pnlHost.Controls.Count &amp;gt; 0 Then\r\n                \' check that the current control isn\'t the same\r\n                \' as this new one\r\n                If Me.UserControlPath &amp;lt;&amp;gt; Value Then\r\n                    \' Remove old items because we can\'t simply\r\n                    \' replace them!\r\n                    Me.pnlHost.Controls. _\r\n                            Remove(Me.pnlHost.Controls(0))\r\n                    \' Add New Items\r\n                    Me.pnlHost.Controls. _\r\n                            Add(Page.LoadControl(Value))\r\n                    \' Store the new values\r\n                    m_strUserControl = Value\r\n                End If\r\n            Else\r\n                Me.pnlHost.Controls. _\r\n                        Add(Page.LoadControl(Value))\r\n                m_strUserControl = Value\r\n            End If\r\n        End Set\r\n    End Property\r\n\r\n    ReadOnly Property UserControl() As Control\r\n        Get\r\n            Return Me.pnlHost.Controls(0)\r\n        End Get\r\n    End Property\r\n\r\n    Protected Overrides Sub Render(ByVal writer As _\r\n            System.Web.UI.HtmlTextWriter)\r\n        \' We want to include a HTML Form field to store the\r\n        \' current UI Object\r\n        MyBase.Render(writer)\r\n        writer.Write(&amp;quot;&amp;lt;input type=&amp;quot;&amp;quot;hidden&amp;quot;&amp;quot; name=&amp;quot;&amp;quot;&amp;quot; &amp;amp; _\r\n                Me.UniqueKey &amp;amp; &amp;quot;&amp;quot;&amp;quot;value=&amp;quot;&amp;quot;&amp;quot; &amp;amp; _\r\n                Me.UserControlPath &amp;amp; &amp;quot;&amp;quot;&amp;quot;/&amp;gt;&amp;quot;)\r\n    End Sub\r\nEnd Class');
					&lt;/script&gt;

&lt;p&gt;Looking at &lt;strong&gt;Listing 4&lt;/strong&gt; we can see how the code in &lt;strong&gt;Listing 3&lt;/strong&gt; is used. One of the first things to note is that we can still use our Me.IsPostBack statement, this is due to the fact we have put our custom control on the form which ASP.NET will automatically recreate for us. The only code we actually need to write to use the control is the following. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchBanner.UserControlPath = &lt;span class="str"&gt;&amp;quot;~/Banner.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_43745);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_43745);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_43745 = CopyToClipboard_Strip('Me.dchBanner.UserControlPath = &amp;quot;~/Banner.ascx&amp;quot;');
					&lt;/script&gt;

&lt;p&gt;Where we simply set the path of the Usercontrol we wish to load. Now looking at the code in &lt;strong&gt;Listing 3&lt;/strong&gt; we can find out what is happening when we set this property.&lt;/p&gt;

&lt;p&gt;First we check if we have previously loaded a control by checking the number of controls in the pnlHost control collection. As our control will only ever support one at a time we simply check if its greater than zero. If we haven&amp;#8217;t loaded a control yet, then we simply add the control to the Panel object and set the private strUserControl to the value of the Usercontrol, which we will store later.&lt;a title="Figure 3" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%203%20-%20Home%20Page_2.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 10px 0px 10px 10px; border-right-width: 0px" height="172" alt="Figure 3 - Home Page" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Figure%203%20-%20Home%20Page_thumb.jpg" width="244" align="right" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If however we had loaded a control then we would need to first check if the new control is the same as the current one. If it is not, we need to remove it from the Panel control collection and replace it with the new one. This sounds simple enough, but as luck would have it once you add a control you can&amp;#8217;t simply replace it with another, you must remove it and then add your new one.&lt;/p&gt;

&lt;p&gt;This doesn&amp;#8217;t seem like it would cause many problems, but it does! At the moment our control would only work every second time, to understand why this is so we need to get a very close look at how ViewState works, which is our next Topic, but before we do we need to finish discussing the other properties.&lt;/p&gt;

&lt;p&gt;As mentioned earlier we can now check for PostBack, this is possible due to our control automatically recreating the previously loaded control during its Page_Init event. I&amp;#8217;ve decided to use a separate routine that handles the event as I find it makes maintenance easier if you can see all your code, as opposed to having some hidden in the Form Designer code area.&lt;/p&gt;

&lt;p&gt;The code is fairly straight forward in that is simply checks for a PostBack event signaling that we should have a control to load back too, but we double check this by seeing if we have a control stored. The technique used to store the previous control is worth discussing and is wrapped up in the UserControlPath property and Render method which is discussed below.&lt;/p&gt;

&lt;p&gt;Once we have determined a control has been previously loaded we load it into the Panel object ready to use. As you will notice from &lt;strong&gt;Figure 5&lt;/strong&gt;, this makes the control ready to be used prior to the Load Events, thereby making our dynamic control act just like a control added at design time.&lt;/p&gt;

&lt;p&gt;Back to how we store the current UserControl, we can look at the property Get of the UserControlPath property which first checks if the local variable has been set (remember that this is a stateless environment and this variable is reset at the start of each PostBack), if it is then this is returned. However if it isn&amp;#8217;t then it is repopulated by getting the value that was stored with the form. The value is stored with the form during the Render method which has been overridden. I have chosen this technique for a few reasons.&lt;/p&gt;

&lt;p&gt;At the time we need to know the current UserControl, ViewState is not available to us, and so we can&amp;#8217;t use that. Another alternative would have been to use session state which I did use in the first versions of this control. However, apart from using resources on the Server, which is never a good thing, it suffered a major issue with users using the browser back button. As the current control is stored on the Server if a previous page is sent back, our control will attempt to load a control which is incompatible with the ViewState data held in the form. When this happens it all ends in a crash! So there had to be a better way. Server controls were out as they again weren&amp;#8217;t available to us in the Page_Init event, and the hidden input box control didn&amp;#8217;t seem to render for some reason. Therefore I used the technique of adding the hidden input box directly to the output stream. A hidden text box (as Classic ASP programmers will know) is a great way to pass information from page to page, and in fact is the way Microsoft handle their ViewState data. This form field will be available during the Page_Init using the following line of code, as used in the property Get of UserControlPath. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; Request.Form(&lt;span class="kwrd"&gt;Me&lt;/span&gt;.UniqueKey)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_49225);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_49225);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_49225 = CopyToClipboard_Strip('Request.Form(Me.UniqueKey)');
					&lt;/script&gt;

&lt;p&gt;The UniqueKey property is used to ensure that should we have several of our controls on the one form each will be able to be identified uniquely. This is achieved by simply annotating the text &amp;#8216;DyanmicControl&amp;#8217; to the end of the controls UniqueID property.&lt;/p&gt;

&lt;p&gt;UserControl is our last property and is useful if you want to access the control as an object once you&amp;#8217;ve created it. The code is very straight forward, basically just returning the first control in the panels control collection. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.pnlHost.Controls(0)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_50451);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_50451);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_50451 = CopyToClipboard_Strip('Return Me.pnlHost.Controls(0)');
					&lt;/script&gt;

&lt;h2&gt;Getting a close look at ViewState&lt;/h2&gt;

&lt;p&gt;We would have all heard of and probably even looked at ViewState by now. However how does ASP.NET make use of the hidden variable? View state is a wonderful piece of technology that Microsoft has given us to simulate a state full environment. Most of the time we need not worry too much about how it works, because it just does. However when we start to get a bit tricky as we are in this example we do need to understand what&amp;#8217;s happening under the covers, because something isn&amp;#8217;t working right and we need to understand why.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve written two little utilities which let us get a better look at what&amp;#8217;s happening, you&amp;#8217;ll find the code in the download. One lists all the form controls and their contents, and the other lists the contents of ViewState.&lt;/p&gt;

&lt;p&gt;To see what is happening when we run our project lets put a break point on the following line in Example2.aspx, which is located in the PreRender event. This line does nothing except to allow us code to place a break point on, now run the project. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Dim&lt;/span&gt; x &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = 1&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_52288);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_52288);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_52288 = CopyToClipboard_Strip('Dim x as Integer = 1');
					&lt;/script&gt;

&lt;p&gt;Press continue when the code stops, the first page will then appear to run fine so enter a username and password, now before the next screen appears the code will stop again. At this point type the following into the command window. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; web.utils.debug.displayFormVars (&lt;span class="kwrd"&gt;Me&lt;/span&gt;.Controls)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_53273);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_53273);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_53273 = CopyToClipboard_Strip('web.utils.debug.displayFormVars (Me.Controls)');
					&lt;/script&gt;

&lt;p&gt;This will produce a long list of all the controls that are on the page, now look for the following section.&lt;/p&gt;

&lt;p&gt;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:_ctl4) 
  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1:_ctl0) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:Label2(dchContent:_ctl0:dchStep:_ctl1:Label2) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1:_ctl1) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:txtAddress(dchContent:_ctl0:dchStep:_ctl1:txtAddress) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1:_ctl2) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:Label3(dchContent:_ctl0:dchStep:_ctl1:Label3) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1:_ctl3) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:txtPhone(dchContent:_ctl0:dchStep:_ctl1:txtPhone) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1:_ctl4) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl1) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:pnlHost(dchContent:_ctl0:dchStep:pnlHost) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ID:(dchContent:_ctl0:dchStep:_ctl2)&lt;/p&gt;

&lt;p&gt;The thing I&amp;#8217;d like to draw your attention to is the UniqueID of the dynamic control host content control (dchContent), and one of the controls that it contains like the textbox for the Name. At the moment the UniqueID is dchContent:_ctl0:dchStep:_ctl1:txtAddress. Lets, now continue the program and stop it again after we enter some details.&lt;/p&gt;

&lt;p&gt;Now if you do the same thing again you&amp;#8217;ll notice that the UniqueID is now dchContent:_ctl0:dchStep:_ctl0:txtAddress, but why is it different, and what does it mean? What it means is that unless the UniqueID&amp;#8217;s are exactly the same between postback&amp;#8217;s ViewState will not work!, and neither will the events on the control. However, if you try running the page again, by reentering the data you&amp;#8217;ll notice as pointed out earlier that on the second attempt it does in fact work. Looking at the UniqueID&amp;#8217;s again after the postback you&amp;#8217;ll notice it&amp;#8217;s the same as the previous. So why is this happening? The reason is quite simple, basically when ever you add a control to a container ASP.NET keeps an internal count which it then uses to calculate the UniqueID for that control. The reason it does this is because you could have 4 texboxes all with the same name (such as in a grid), and .NET needs to identify them all uniquely, it does this by means of a UniqueID. This is all fine, except when you want to remove an item from the collection and add a new one. The problem is the internal counter doesn&amp;#8217;t reset, which means if you add ten controls then remove them all again then add one more control the internal counter would be 10 not 0. This makes sense because unless .NET can guarantee a UniqueID for every control it generates the ViewState mechanism just wouldn&amp;#8217;t work properly. So what does this mean for our control? Well it means that unless we can always make the UniqueID for each control the same on postback our control simply won&amp;#8217;t work! &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;   &lt;strong&gt;Listing 4 - Example 2 Page Load&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; Page_Load(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; &lt;span class="kwrd"&gt;MyBase&lt;/span&gt;.Load&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="rem"&gt;' Put user code to initialize the page here&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     &lt;span class="rem"&gt;' Create the page based on the user who has entered&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;     &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.IsPostBack &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;         &lt;span class="kwrd"&gt;If&lt;/span&gt; Request.QueryString(&lt;span class="str"&gt;&amp;quot;Registered&amp;quot;&lt;/span&gt;) = _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;                 &lt;span class="str"&gt;&amp;quot;True&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;             &lt;span class="rem"&gt;' Top security here, you might want to do &lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;             &lt;span class="rem"&gt;' better authentication&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchBanner.UserControlPath = &lt;span class="str"&gt;&amp;quot;~/Banner.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchMenu.UserControlPath = &lt;span class="str"&gt;&amp;quot;~/menu.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;         &lt;span class="kwrd"&gt;Else&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchBanner.UserControlPath =&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;                     &lt;span class="str"&gt;&amp;quot;~/Banner_Advertising.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchMenu.UserControlPath = &lt;span class="str"&gt;&amp;quot;~/Login.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;             &lt;span class="kwrd"&gt;Me&lt;/span&gt;.dchContent.UserControlPath = _&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;                     &lt;span class="str"&gt;&amp;quot;~/Wizard2.ascx&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;         &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_57764);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_57764);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_57764 = CopyToClipboard_Strip('   Listing 4 - Example 2 Page Load\r\nPrivate Sub Page_Load(ByVal sender As System.Object, _\r\n    ByVal e As System.EventArgs) Handles MyBase.Load\r\n    \' Put user code to initialize the page here\r\n    \' Create the page based on the user who has entered\r\n    If Not Me.IsPostBack Then\r\n        If Request.QueryString(&amp;quot;Registered&amp;quot;) = _\r\n                &amp;quot;True&amp;quot; Then\r\n            \' Top security here, you might want to do \r\n            \' better authentication\r\n            Me.dchBanner.UserControlPath = &amp;quot;~/Banner.ascx&amp;quot;\r\n            Me.dchMenu.UserControlPath = &amp;quot;~/menu.ascx&amp;quot;\r\n        Else\r\n            Me.dchBanner.UserControlPath =\r\n                    &amp;quot;~/Banner_Advertising.ascx&amp;quot;\r\n            Me.dchMenu.UserControlPath = &amp;quot;~/Login.ascx&amp;quot;\r\n            Me.dchContent.UserControlPath = _\r\n                    &amp;quot;~/Wizard2.ascx&amp;quot;\r\n        End If\r\n    End If\r\nEnd Sub');
					&lt;/script&gt;

&lt;p&gt;I&amp;#8217;m not completely satisfied with the solution I&amp;#8217;ve found, however it does seem to do the trick, and is very easy to implement. The interesting thing is you don&amp;#8217;t have to touch our custom control. Instead you need to add a little bit of code to each control which will be created dynamically. As we can override properties in .NET we are able to override the UniqueID property of all our controls. So to get everything to work you simply include this piece of code in all your custom controls. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Overrides&lt;/span&gt; &lt;span class="kwrd"&gt;ReadOnly&lt;/span&gt; &lt;span class="kwrd"&gt;Property&lt;/span&gt; UniqueID() &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;     &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;         &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.Parent.Parent.UniqueID &amp;amp; &lt;span class="str"&gt;&amp;quot;:_ctl0&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;Get&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Property&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_63000);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_63000);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_63000 = CopyToClipboard_Strip('Public Overrides ReadOnly Property UniqueID() As String\r\n    Get\r\n        Return Me.Parent.Parent.UniqueID &amp;amp; &amp;quot;:_ctl0&amp;quot;\r\n    End Get\r\nEnd Property');
					&lt;/script&gt;

&lt;p&gt;The purpose of this code is to ensure that the UniqueID for each control within the container remains _ctl0 regardless of what the internal counter would have &lt;a title="Figure 5" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Event%20Model_2.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 10px 10px 10px 0px; border-right-width: 0px" height="244" alt="Figure 5 Page Event Model" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/Event%20Model_thumb.jpg" width="98" align="left" border="0" /&gt;&lt;/a&gt;made it. Now given that we have basically removed the safeguard that Microsoft has put in, there are some ramifications. You will only be able to include one control per instance of the DyanamicControlHost control. However, given that we don&amp;#8217;t support more than one anyway that&amp;#8217;s not a big issue, but it is one to remember if you use the technique elsewhere. Also you may have problems if the control is used outside the dynamic control host control.&lt;/p&gt;

&lt;p&gt;So given that you&amp;#8217;ve added this code to your controls the DyanamicControlHost is now complete and makes using dynamically created controls as easy to use as those we create at design time (see &lt;strong&gt;Listing 4&lt;/strong&gt;). Note that in the code download the first step in the wizard (Wizard_Step1.ascx) has this code commented out to demonstrate how it worked without the code. You will need to uncomment this code again to make example 2 work properly.&lt;/p&gt;

&lt;p&gt;As an alternative in the second step, I have tried to demonstrate another technique. Now that we have a full OO language we can take advantage of Inheritance, and so I have created a WizardBase class which includes the overridden UniqueID property and the IWizard interface. So you can now Inherit from this class instead of System.Web.UI.UserControl. This means instead of implementing the properties of IWizard you now override the properties of the base class instead. The base class has been included in the Wizard.ascx code behind file. This method preferable as it ensures you don&amp;#8217;t forget to override the UniqueID property while still forcing you to implement all the IWizard properties.&lt;/p&gt;

&lt;h2&gt;Storing Data after PostBack&lt;/h2&gt;

&lt;p&gt;Now that we have solved the issues with the dynamic controls being created we need look at how we can persist data between round trips to the server, so that we can make use of the data when the finish button is pressed.&lt;/p&gt;

&lt;p&gt;To do this we need to store the data between postbacks in a way that&amp;#8217;s easy to retrieve. The .NET framework provides a number of nice ways to do this. To give more options when storing our data, I designed a simple Data Storage component for post back data (see &lt;strong&gt;Figure 4&lt;/strong&gt;), which takes advantage of the .NET features but simplifies their use. This currently makes use of the cache object, but could be reconfigured to use just about anything. The code is included as part of the download but was a bit lengthy to include here.&lt;/p&gt;

&lt;p&gt;So using our new Data Storage system it becomes a simple matter of storing and retrieving information as the following examples demonstrate. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; Web.Data.Store(&lt;span class="str"&gt;&amp;quot;Registration.Name&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;Me&lt;/span&gt;.txtName.Text)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; strName = &lt;span class="kwrd"&gt;CType&lt;/span&gt;(Web.Data.Retrieve(&lt;span class="str"&gt;&amp;quot;Registration.Name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;),&lt;span class="kwrd"&gt;String&lt;/span&gt;)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_67818);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_67818);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_67818 = CopyToClipboard_Strip('Web.Data.Store(&amp;quot;Registration.Name&amp;quot;, Me.txtName.Text)\r\n\r\nstrName = CType(Web.Data.Retrieve(&amp;quot;Registration.Name&amp;quot;, &amp;quot;&amp;quot;),String)');
					&lt;/script&gt;

&lt;p&gt;Note that the first parameter takes a key, this is used to identify the data once it has been stored. Looking at the UML model of the data object we can see that it is overloaded and allows for a default value if so desired. Another overloaded parameter is that of sessionWide which determines whether this value is cleared when the clear method is called. Remember not to store many items here as it will remain in memory until the session has ended.&lt;/p&gt;

&lt;p&gt;We are now ready to start collecting our information from the forms. Each form simply stores the current value of its controls during the changed event of the particular control. As all the code for this is virtually identical, I&amp;#8217;ll only detail one of them. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Sub&lt;/span&gt; txtName_TextChanged(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sender &lt;span class="kwrd"&gt;As&lt;/span&gt; System.&lt;span class="kwrd"&gt;Object&lt;/span&gt;, _&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt;         &lt;span class="kwrd"&gt;ByVal&lt;/span&gt; e &lt;span class="kwrd"&gt;As&lt;/span&gt; System.EventArgs) &lt;span class="kwrd"&gt;Handles&lt;/span&gt; txtName.TextChanged&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="rem"&gt;'  We want to store this information so that we can use it later on.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     Web.Data.Store(&lt;span class="str"&gt;&amp;quot;Registration.Name&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;Me&lt;/span&gt;.txtName.Text)&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt; &lt;span class="kwrd"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_69771);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_69771);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_69771 = CopyToClipboard_Strip('Private Sub txtName_TextChanged(ByVal sender As System.Object, _\r\n        ByVal e As System.EventArgs) Handles txtName.TextChanged\r\n    \'  We want to store this information so that we can use it later on.\r\n    Web.Data.Store(&amp;quot;Registration.Name&amp;quot;, Me.txtName.Text)\r\nEnd Sub');
					&lt;/script&gt;

&lt;p&gt;To retrieve the data once stored is again a simple process as this excerpt from the third step in the Wizard shows. &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;Me&lt;/span&gt;.lblName.Text = &lt;span class="kwrd"&gt;CType&lt;/span&gt;(Web.Data.Retrieve(&lt;span class="str"&gt;&amp;quot;Registration.Name&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;), &lt;span class="kwrd"&gt;String&lt;/span&gt;)&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_71654);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_71654);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_71654 = CopyToClipboard_Strip('Me.lblName.Text = CType(Web.Data.Retrieve(&amp;quot;Registration.Name&amp;quot;, &amp;quot;&amp;quot;), String)');
					&lt;/script&gt;

&lt;p&gt;Notice how we always use the CType function, this is because the Retrieve method returns back a data type of Object. If you turn Option Strict On, which you should do as it actually makes your code run faster as well as reducing potential errors. You&amp;#8217;ll notice that you get an error if you don&amp;#8217;t explicitly cast the returned object into the correct data type of the receiving object. In this case the Text property of the Label control has a type of String.&lt;a title="Figure 4" href="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/UML%20Diagram_2.jpg" rel="lightbox"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px 0px 10px 10px; border-right-width: 0px" height="56" alt="Figure 4 Data UML Diagram" src="http://www.dotnetprofessional.com/blog/image.axd?picture=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_13B13/UML%20Diagram_thumb.jpg" width="244" align="right" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It&amp;#8217;s also interesting to note that it&amp;#8217;s important to re-populate controls during the Page_PreRender event and not the Page_Load event. The reason for this is evident if you examine &lt;strong&gt;Figure 5&lt;/strong&gt;, here you can see that the Page_Load events fires before the events of individual controls. This means that if you re-populate the controls during the Load event you would in fact overwrite any changes the user had made, which would not be very desirable.&lt;/p&gt;

&lt;p&gt;So once we have wired up all the controls to store their values into our new Data object, we can then make use of this data to redisplay it in our last step of the sample. In reality we would pass the data to a database and do other validation, but we have kept the sample simple.&lt;/p&gt;

&lt;h2&gt;Bits &amp;amp; Pieces&lt;/h2&gt;

&lt;p&gt;That&amp;#8217;s covered the core section of the article, however there are a few other bits and pieces which are worth knowing when you start to create your own implementations. &lt;/p&gt;

&lt;p&gt;Caching is a new feature in ASP.NET and we have the ability to cache at either the page level or control level. Making use of this with your dynamic controls means you can create container sites where most of the work is already cached and only the inner content has to be processed.&lt;/p&gt;

&lt;p&gt;Also, it is possible to create one page that then dynamically loads each of the content controls into the content area via a query string parameter, such as; &lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; http://LocalHost/Default.aspx?url=~/Page1.ascx&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboard16762699eed9449ca2a71875c6d33182_75019);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboard16762699eed9449ca2a71875c6d33182_75019);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboard16762699eed9449ca2a71875c6d33182_75019 = CopyToClipboard_Strip('http://LocalHost/Default.aspx?url=~/Page1.ascx');
					&lt;/script&gt;

&lt;p&gt;Your page can then dynamically load the URL into the content area. An advantage of this technique would be that if you needed to change the layout of the main pages you&amp;#8217;d only have to do it in one place.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;We have covered a large amount of material in this article, material which if mastered will help you produce more dynamic and exciting web applications. The techniques discussed here were varied from data storage to process flows using a Wizard metaphor. I encourage you to test drive the code supplied and let your imagination loose on the possibilities that dynamic controls can bring.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;a href="http://www.dotnetprofessional.com/blog/file.axd?file=WindowsLiveWriter/ASP.NETDynamicControlsStateManagement_C000/DynamicControls.zip" rel="enclosure"&gt;Source - DynamicControls.zip (72 kb)&lt;/a&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx&amp;amp;title=ASP.NET Dynamic Controls &amp;amp; State Management" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx&amp;amp;title=ASP.NET Dynamic Controls &amp;amp; State Management" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx&amp;amp;title=ASP.NET Dynamic Controls &amp;amp; State Management" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/IOyIjHe4n7M" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/IOyIjHe4n7M/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=cd03c6c2-b76b-48f9-9862-4bd0fa11f4a4</guid>
      <pubDate>Thu, 06 Mar 2008 06:00:35 -0800</pubDate>
      <category>.NET 1</category>
      <category>ASP.NET</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=cd03c6c2-b76b-48f9-9862-4bd0fa11f4a4</pingback:target>
      <slash:comments>27</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=cd03c6c2-b76b-48f9-9862-4bd0fa11f4a4</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/06/ASPNET-Dynamic-Controls-and-State-Management.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=cd03c6c2-b76b-48f9-9862-4bd0fa11f4a4</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=cd03c6c2-b76b-48f9-9862-4bd0fa11f4a4</feedburner:origLink></item>
    <item>
      <title>Encrypt sections of Web.Config or App.Config</title>
      <description>&lt;p&gt;In many application be they web or otherwise it can be important to secure parts of the configuration files incase the file is compromised by a hacker or you simply don't want anyone to know what the true values are. It turns out that this is fairly easy to do using the ASP.NET IIS Registration Tool (Aspnet_regiis.exe) (obvious right?). To illustrate the point I'll show you a typical config file and what's required to encrypt parts of it.     &lt;br /&gt;    &lt;br /&gt;&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;div class="csharpcode"&gt;     &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!--&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="rem"&gt;  Initial Config file without taking encryption into concideration&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; &lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dataConfiguration&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;             Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data,&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;             Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt; &lt;span class="attr"&gt;defaultDatabase&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyDatabase&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;databaseType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;             Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;             PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BufferSize&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;999999&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.UserName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-username&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.Password&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-password&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;   &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyConnectionString&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;connectionString&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Data Source=.;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;         Integrated Security=SSPI;Initial Catalog=MyApplicationDB;&amp;quot;&lt;/span&gt; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;         &lt;span class="attr"&gt;providerName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_472);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_472);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_472 = CopyToClipboard_Strip('&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;\r\n&amp;lt;!--\r\n  Initial Config file without taking encryption into concideration\r\n--&amp;gt;\r\n\r\n&amp;lt;configuration&amp;gt;\r\n  &amp;lt;configSections&amp;gt;\r\n    &amp;lt;section name=&amp;quot;dataConfiguration&amp;quot; type=&amp;quot;Microsoft.Practices.EnterpriseLibrary.\r\n            Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data,\r\n            Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot; /&amp;gt;\r\n  &amp;lt;/configSections&amp;gt;\r\n  &amp;lt;dataConfiguration defaultDatabase=&amp;quot;MyDatabase&amp;quot;&amp;gt;\r\n    &amp;lt;providerMappings&amp;gt;\r\n      &amp;lt;add databaseType=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, \r\n            Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,\r\n            PublicKeyToken=b03f5f7f11d50a3a&amp;quot; name=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n    &amp;lt;/providerMappings&amp;gt;\r\n  &amp;lt;/dataConfiguration&amp;gt;\r\n\r\n  &amp;lt;appSettings&amp;gt;\r\n    &amp;lt;add key=&amp;quot;BufferSize&amp;quot; value=&amp;quot;999999&amp;quot;/&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.UserName&amp;quot; value=&amp;quot;secure-username&amp;quot;/&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.Password&amp;quot; value=&amp;quot;secure-password&amp;quot;/&amp;gt;\r\n  &amp;lt;/appSettings&amp;gt;\r\n  \r\n  &amp;lt;connectionStrings&amp;gt;\r\n    &amp;lt;add name=&amp;quot;MyConnectionString&amp;quot; connectionString=&amp;quot;Data Source=.;\r\n        Integrated Security=SSPI;Initial Catalog=MyApplicationDB;&amp;quot; \r\n        providerName=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n  &amp;lt;/connectionStrings&amp;gt;\r\n&amp;lt;/configuration&amp;gt;');
					&lt;/script&gt;

&lt;p&gt;The settings of each of these can easily be retrieved using the following code which is included in the download as a console app. 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; static void Main(string[] args)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     // Write out the contents of the config file.&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     Console.WriteLine(&amp;quot;MyConnectionString = &amp;quot; + &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;         ConfigurationManager.ConnectionStrings[&amp;quot;MyConnectionString&amp;quot;]);&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;     Console.WriteLine(&amp;quot;BufferSize = &amp;quot; + ConfigurationManager.AppSettings[&amp;quot;BufferSize&amp;quot;]);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;     Console.WriteLine(&amp;quot;SomeService.UserName = &amp;quot; + &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;         ConfigurationManager.AppSettings[&amp;quot;SomeService.UserName&amp;quot;]);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;     Console.WriteLine(&amp;quot;SomeService.Password = &amp;quot; + &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;         ConfigurationManager.AppSettings[&amp;quot;SomeService.Password&amp;quot;]);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;     Console.ReadLine();&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_8728);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_8728);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_8728 = CopyToClipboard_Strip('static void Main(string[] args)\r\n{\r\n    // Write out the contents of the config file.\r\n    Console.WriteLine(&amp;quot;MyConnectionString = &amp;quot; + \r\n        ConfigurationManager.ConnectionStrings[&amp;quot;MyConnectionString&amp;quot;]);\r\n    Console.WriteLine(&amp;quot;BufferSize = &amp;quot; + ConfigurationManager.AppSettings[&amp;quot;BufferSize&amp;quot;]);\r\n    Console.WriteLine(&amp;quot;SomeService.UserName = &amp;quot; + \r\n        ConfigurationManager.AppSettings[&amp;quot;SomeService.UserName&amp;quot;]);\r\n    Console.WriteLine(&amp;quot;SomeService.Password = &amp;quot; + \r\n        ConfigurationManager.AppSettings[&amp;quot;SomeService.Password&amp;quot;]);\r\n\r\n    Console.ReadLine();\r\n}');
					&lt;/script&gt;

&lt;p&gt;In the example above you may want to encrypt the connection string and two of the keys in appSettings, but probably not the BufferSize property as you'd like that to be easily accessible or at least readable on the production server. The problem we have is that the Aspnet_regiis.exe tool only works on entire sections ie appSettings, connectionStrings. So encrypting the connectionStrings section is fairly straightforward and can be done with the following command lines: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; copy App.Config App.Config.original&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; rename App.config web.config&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; aspnet_regiis -pef connectionStrings . -prov DataProtectionConfigurationProvider&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; rename web.config App.config&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_11935);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_11935);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_11935 = CopyToClipboard_Strip('copy App.Config App.Config.original\r\nrename App.config web.config\r\naspnet_regiis -pef connectionStrings . -prov DataProtectionConfigurationProvider\r\nrename web.config App.config');
					&lt;/script&gt;

&lt;p&gt;So this is a little strange and the reason is that the tool only works with web.config files, however by renaming, then processing our app.config file we can get the desired result. I've included this as a batch file in the project download. You just need to run the batch file in the directory that your app.config file resides in. If you want to run this against your web.config then you only need the third line. The new config file should look something like this (I've reformatted it a bit): 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!--&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="rem"&gt;  Initial Config file without taking encryption into concideration&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; &lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dataConfiguration&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;         Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data,&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;         Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt; &lt;span class="attr"&gt;defaultDatabase&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyDatabase&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;databaseType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase,&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;          Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;          PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BufferSize&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;999999&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.UserName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-username&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.Password&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-password&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;   &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt; &lt;span class="attr"&gt;configProtectionProvider&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;         &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAA&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;         AAAADZgAAqAAAABAAAAAd1TPFE24MHo78J8HYFRXKAAAAAASAAACgAAAAEAAAAAJ8yjPvsnqP0Lo&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;         Qt05ynrWoAQAANJdt/En21VeyYb8OJcTE3p+MeKOMG4xsFPzjlrHnyaJmVEekYVMCkX2RG/1pV1J&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;         DfsaCAXKSyBnxDiCM5yAQEA5TSxeedQYvKXWBWrUxMMIjNUmjZDsbc8I/eBKarMCHav7d+oguijn&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;         HFf948x48Z25434QY1lZ4hnkP7oW5dO9639iaT3+uWJRoARzHzcfvNYxtJ/+jowoZyt+JRcHjR1Q&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;         MBD/CMsehNh4nQeWX2zp09tYm2EdIj7LmSyWwrE9Livf1qs/IBGRv1zWPIue956mAwDbXPg4tuF1&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;         Ml4Qdm3rj9+mCp/sht80ixkWM9nID8/OaqZqzaaK/J/3vMjZF+w4SeFws8Vo40xb48/Mr1Q5EOZe&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt;         JMNa1ySiard4pckR1Xd3rRPA+J1+6BBTCws0qsmBtd5pVs0KW0xt0HIlUELA7NYIsXML+zGFgJ2C&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:&lt;/span&gt;         TTGcTQsUF5y3+soUeXxfM2Eq3NqSVouWJMImT2udvR6PCiHGsNMiT9/ZK8TL0C5aAzD47IAc0ngA&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  38:&lt;/span&gt;         DF/uTcX8ERWUy7LPwIlDRXamTlRmVvXt712na83nFf+FExhQAAADDz+jCgtqU0npcs6WJgVP/+QU&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:&lt;/span&gt;         cQQ==&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  40:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  42:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_13639);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_13639);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_13639 = CopyToClipboard_Strip('&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;\r\n&amp;lt;!--\r\n  Initial Config file without taking encryption into concideration\r\n--&amp;gt;\r\n\r\n&amp;lt;configuration&amp;gt;\r\n  &amp;lt;configSections&amp;gt;\r\n    &amp;lt;section name=&amp;quot;dataConfiguration&amp;quot; type=&amp;quot;Microsoft.Practices.EnterpriseLibrary.\r\n        Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data,\r\n        Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot; /&amp;gt;\r\n  &amp;lt;/configSections&amp;gt;\r\n  &amp;lt;dataConfiguration defaultDatabase=&amp;quot;MyDatabase&amp;quot;&amp;gt;\r\n    &amp;lt;providerMappings&amp;gt;\r\n      &amp;lt;add databaseType=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase,\r\n         Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,\r\n         PublicKeyToken=b03f5f7f11d50a3a&amp;quot; name=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n    &amp;lt;/providerMappings&amp;gt;\r\n  &amp;lt;/dataConfiguration&amp;gt;\r\n\r\n  &amp;lt;appSettings&amp;gt;\r\n    &amp;lt;add key=&amp;quot;BufferSize&amp;quot; value=&amp;quot;999999&amp;quot;/&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.UserName&amp;quot; value=&amp;quot;secure-username&amp;quot;/&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.Password&amp;quot; value=&amp;quot;secure-password&amp;quot;/&amp;gt;\r\n  &amp;lt;/appSettings&amp;gt;\r\n  \r\n  &amp;lt;connectionStrings configProtectionProvider=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&amp;gt;\r\n    &amp;lt;EncryptedData&amp;gt;\r\n      &amp;lt;CipherData&amp;gt;\r\n        &amp;lt;CipherValue&amp;gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAA\r\n        AAAADZgAAqAAAABAAAAAd1TPFE24MHo78J8HYFRXKAAAAAASAAACgAAAAEAAAAAJ8yjPvsnqP0Lo\r\n        Qt05ynrWoAQAANJdt/En21VeyYb8OJcTE3p+MeKOMG4xsFPzjlrHnyaJmVEekYVMCkX2RG/1pV1J\r\n        DfsaCAXKSyBnxDiCM5yAQEA5TSxeedQYvKXWBWrUxMMIjNUmjZDsbc8I/eBKarMCHav7d+oguijn\r\n        HFf948x48Z25434QY1lZ4hnkP7oW5dO9639iaT3+uWJRoARzHzcfvNYxtJ/+jowoZyt+JRcHjR1Q\r\n        MBD/CMsehNh4nQeWX2zp09tYm2EdIj7LmSyWwrE9Livf1qs/IBGRv1zWPIue956mAwDbXPg4tuF1\r\n        Ml4Qdm3rj9+mCp/sht80ixkWM9nID8/OaqZqzaaK/J/3vMjZF+w4SeFws8Vo40xb48/Mr1Q5EOZe\r\n        JMNa1ySiard4pckR1Xd3rRPA+J1+6BBTCws0qsmBtd5pVs0KW0xt0HIlUELA7NYIsXML+zGFgJ2C\r\n        TTGcTQsUF5y3+soUeXxfM2Eq3NqSVouWJMImT2udvR6PCiHGsNMiT9/ZK8TL0C5aAzD47IAc0ngA\r\n        DF/uTcX8ERWUy7LPwIlDRXamTlRmVvXt712na83nFf+FExhQAAADDz+jCgtqU0npcs6WJgVP/+QU\r\n        cQQ==&amp;lt;/CipherValue&amp;gt;\r\n      &amp;lt;/CipherData&amp;gt;\r\n    &amp;lt;/EncryptedData&amp;gt;\r\n  &amp;lt;/connectionStrings&amp;gt;\r\n&amp;lt;/configuration&amp;gt;');
					&lt;/script&gt;

&lt;p&gt;So that's how easy it is to encrypt a section of the config file, however, we still have an issue with encrypting part of our appSettings. The problem is you can't selectively encrypt part of a section, its an all or nothing scenario. Therefore, to achieve our goal, we have to add a new section and encrypt that. This leaves us with a config file that looks like this: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!--&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="rem"&gt;  Config file taking encryption into concideration&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; &lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secureAppSettings&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;/strong&gt;&lt;span class="kwrd"&gt;&lt;strong&gt;=&amp;quot;System.Configuration.NameValueSectionHandler,&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;         System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;quot;&lt;/strong&gt;&lt;/span&gt;&lt;strong&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dataConfiguration&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;         Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;         Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt; &lt;span class="attr"&gt;defaultDatabase&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyDatabase&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;databaseType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;         Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral, &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;         PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BufferSize&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;999999&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;secureAppSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.UserName&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-username&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;SomeService.Password&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secure-password&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;strong&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;secureAppSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/strong&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyConnectionString&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;connectionString&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Data Source=.;Integrated Security=SSPI;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;         Initial Catalog=MyApplicationDB;&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;providerName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_24896);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_24896);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_24896 = CopyToClipboard_Strip('&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;\r\n&amp;lt;!--\r\n  Config file taking encryption into concideration\r\n--&amp;gt;\r\n\r\n&amp;lt;configuration&amp;gt;\r\n  &amp;lt;configSections&amp;gt;\r\n    &amp;lt;section name=&amp;quot;secureAppSettings&amp;quot; type=&amp;quot;System.Configuration.NameValueSectionHandler,\r\n        System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;quot; /&amp;gt;\r\n    &amp;lt;section name=&amp;quot;dataConfiguration&amp;quot; type=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.\r\n        Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, \r\n        Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot; /&amp;gt;\r\n  &amp;lt;/configSections&amp;gt;\r\n  &amp;lt;dataConfiguration defaultDatabase=&amp;quot;MyDatabase&amp;quot;&amp;gt;\r\n    &amp;lt;providerMappings&amp;gt;\r\n      &amp;lt;add databaseType=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, \r\n        Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral, \r\n        PublicKeyToken=b03f5f7f11d50a3a&amp;quot; name=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n    &amp;lt;/providerMappings&amp;gt;\r\n  &amp;lt;/dataConfiguration&amp;gt;\r\n\r\n  &amp;lt;appSettings&amp;gt;\r\n    &amp;lt;add key=&amp;quot;BufferSize&amp;quot; value=&amp;quot;999999&amp;quot;/&amp;gt;\r\n  &amp;lt;/appSettings&amp;gt;\r\n\r\n  &amp;lt;secureAppSettings&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.UserName&amp;quot; value=&amp;quot;secure-username&amp;quot;/&amp;gt;\r\n    &amp;lt;add key=&amp;quot;SomeService.Password&amp;quot; value=&amp;quot;secure-password&amp;quot;/&amp;gt;\r\n  &amp;lt;/secureAppSettings&amp;gt;\r\n\r\n  &amp;lt;connectionStrings&amp;gt;\r\n    &amp;lt;add name=&amp;quot;MyConnectionString&amp;quot; connectionString=&amp;quot;Data Source=.;Integrated Security=SSPI;\r\n        Initial Catalog=MyApplicationDB;&amp;quot; providerName=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n  &amp;lt;/connectionStrings&amp;gt;\r\n&amp;lt;/configuration&amp;gt;');
					&lt;/script&gt;

&lt;p&gt;The new parts have been highlighted and show that I've added a new secureAppSettings (can be anything) section and then added the section with the name value pairs that I want to encrypt. Now all I need do is modify the original batch file to include this section too: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; copy App.Config App.Config.original&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; rename App.config web.config&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; aspnet_regiis -pef connectionStrings . -prov DataProtectionConfigurationProvider&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; aspnet_regiis -pef secureAppSettings . -prov DataProtectionConfigurationProvider&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt; rename web.config App.config&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_34496);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_34496);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_34496 = CopyToClipboard_Strip('copy App.Config App.Config.original\r\nrename App.config web.config\r\naspnet_regiis -pef connectionStrings . -prov DataProtectionConfigurationProvider\r\naspnet_regiis -pef secureAppSettings . -prov DataProtectionConfigurationProvider\r\nrename web.config App.config');
					&lt;/script&gt;

&lt;p&gt;This then produces the following encrypted config file ready for deployment - well almost... 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; &lt;span class="rem"&gt;&amp;lt;!--&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt; &lt;span class="rem"&gt;  Config file taking encryption into concideration&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt; &lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;secureAppSettings&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Configuration.NameValueSectionHandler,&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;         System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;section&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;dataConfiguration&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;         Configuration.DatabaseSettings,Microsoft.Practices.EnterpriseLibrary.Data, &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;         Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configSections&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt; &lt;span class="attr"&gt;defaultDatabase&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MyDatabase&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  16:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;databaseType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  17:&lt;/span&gt;         Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  18:&lt;/span&gt;         PublicKeyToken=b03f5f7f11d50a3a&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Data.SqlClient&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  19:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;providerMappings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  20:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;dataConfiguration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  21:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  22:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  23:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;add&lt;/span&gt; &lt;span class="attr"&gt;key&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;BufferSize&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;999999&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  24:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;appSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  25:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  26:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;secureAppSettings&lt;/span&gt; &lt;span class="attr"&gt;configProtectionProvider&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  27:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  28:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  29:&lt;/span&gt;         &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAAA&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  30:&lt;/span&gt;         AAADZgAAqAAAABAAAACF8idXnx0O07526CxQFh9BAAAAAASAAACgAAAAEAAAACNxLiQ6eAyzE8jZG&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  31:&lt;/span&gt;         yUhwThYAQAAii89rtpXJsxeklxD/7LhjtLzzaRGxcCpWUDuI+uNKuN0GrDeKSXRB0s7tfumGdzkZM&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  32:&lt;/span&gt;         iR6qlTE9ueIDWO8tm79pVJ3emkYSiBRGi4KXs5oAPugwyuZ/Qfq3LC2d1U07EWGvOBQK4SjTC56De&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  33:&lt;/span&gt;         KKZDLwu+3WRBYLGLdJapCnMQ4lB/Ev29R9XYW9iqQfgOFE3iFdtcfts4+8Ig7y6CYe3A845VZWBD0&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  34:&lt;/span&gt;         6SFu2obFZ8vGCRmF2qr0M9N9uxT+xOCRX7G5vkbH+TpFSiUQoV+cC5f9y98uCyj2xL60GxO+PZM8W&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  35:&lt;/span&gt;         UJFYknRoX6SkVzfRwX+GWcdRc+nYSM1+I/hica32POuWur5lAhye0JO2SHTKSj66S+XjiM64fkh+b&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  36:&lt;/span&gt;         HNp1LXf0ciEZQNIZeknVzClns6vHHDYYPI3iPYs+dTv3hoNPSDe4kee9BhuPWgRBS3uObPt6ySv46&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  37:&lt;/span&gt;         QHJH4QWsUAAAAxcEHWBLJ1zw1Y5etR7t4EFeU5X8=&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  38:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  39:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  40:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;secureAppSettings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  41:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  42:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt; &lt;span class="attr"&gt;configProtectionProvider&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  43:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  44:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  45:&lt;/span&gt;         &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAAA&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  46:&lt;/span&gt;         AAADZgAAqAAAABAAAABv17Dh+HaRnrZppOfniJMaAAAAAASAAACgAAAAEAAAAF1mqOQdo+lvm45mQ&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  47:&lt;/span&gt;         MwaiaKoAQAAHVHExOIDaItnnbRK7n/qHudiSUAq22t2qRTSxQDxE/lYyN2gA/cWHTw4njHVRu+MJN&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  48:&lt;/span&gt;         awquuIFKW7RLFAlDYdJPA2xPHakwJXt6MLCOgdXmd+YojqP7AYHrPbFuRGF/8sNY+SlH0QOZya53D&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  49:&lt;/span&gt;         AuljzMUQoE27BQbsCT+tLriMnGgmc8SaCjAFqqVc538zxxKLFnLZJLttHm5qAq7/y65abZDMjYo4Y&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  50:&lt;/span&gt;         m4RpmhxQ5ZyITWpGt8RWabZ10MgWvcWS+QiL+ONVhs7lgR5wo0tDk1aoMh0f2VrSZPfXYoC8ZR2JV&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  51:&lt;/span&gt;         0jqVSNasYmZN/+AO2G+6/S8YxETJqYD3BL8qFBtok9NUzvvoGMZYw+lJniSoLCBWtNoFpFM90/v0x&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  52:&lt;/span&gt;         hCfRZZqiYj/8OOpJQT38ycG1N/zskhK/LAKe7loZGgPMl1wUjnFGpLOHW+f2ikVtYtHkH3+qxqny8&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  53:&lt;/span&gt;         AeSZKovMnhfZlXUJx18G0Ugpvskmgju9aKtnE6UWLZbiiygJAfifQUjTwjFXgibQmuvFPxlWuUSW7&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  54:&lt;/span&gt;         e6fBzVggx1zpDqnu5RGksN+zOg3S7IyiC79GihQAAAAWBM1NaI+3SdfalbKCGvuhxxTNSQ==&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  55:&lt;/span&gt;         &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherValue&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  56:&lt;/span&gt;       &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;CipherData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  57:&lt;/span&gt;     &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;EncryptedData&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  58:&lt;/span&gt;   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;connectionStrings&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  59:&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_36023);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_36023);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_36023 = CopyToClipboard_Strip('&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; ?&amp;gt;\r\n&amp;lt;!--\r\n  Config file taking encryption into concideration\r\n--&amp;gt;\r\n\r\n&amp;lt;configuration&amp;gt;\r\n  &amp;lt;configSections&amp;gt;\r\n    &amp;lt;section name=&amp;quot;secureAppSettings&amp;quot; type=&amp;quot;System.Configuration.NameValueSectionHandler,\r\n        System, Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089&amp;quot; /&amp;gt;\r\n    &amp;lt;section name=&amp;quot;dataConfiguration&amp;quot; type=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.\r\n        Configuration.DatabaseSettings,Microsoft.Practices.EnterpriseLibrary.Data, \r\n        Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a&amp;quot; /&amp;gt;\r\n  &amp;lt;/configSections&amp;gt;\r\n  &amp;lt;dataConfiguration defaultDatabase=&amp;quot;MyDatabase&amp;quot;&amp;gt;\r\n    &amp;lt;providerMappings&amp;gt;\r\n      &amp;lt;add databaseType=&amp;quot;Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase, \r\n        Microsoft.Practices.EnterpriseLibrary.Data, Version=3.0.0.0, Culture=neutral,\r\n        PublicKeyToken=b03f5f7f11d50a3a&amp;quot; name=&amp;quot;System.Data.SqlClient&amp;quot; /&amp;gt;\r\n    &amp;lt;/providerMappings&amp;gt;\r\n  &amp;lt;/dataConfiguration&amp;gt;\r\n\r\n  &amp;lt;appSettings&amp;gt;\r\n    &amp;lt;add key=&amp;quot;BufferSize&amp;quot; value=&amp;quot;999999&amp;quot;/&amp;gt;\r\n  &amp;lt;/appSettings&amp;gt;\r\n\r\n  &amp;lt;secureAppSettings configProtectionProvider=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&amp;gt;\r\n    &amp;lt;EncryptedData&amp;gt;\r\n      &amp;lt;CipherData&amp;gt;\r\n        &amp;lt;CipherValue&amp;gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAAA\r\n        AAADZgAAqAAAABAAAACF8idXnx0O07526CxQFh9BAAAAAASAAACgAAAAEAAAACNxLiQ6eAyzE8jZG\r\n        yUhwThYAQAAii89rtpXJsxeklxD/7LhjtLzzaRGxcCpWUDuI+uNKuN0GrDeKSXRB0s7tfumGdzkZM\r\n        iR6qlTE9ueIDWO8tm79pVJ3emkYSiBRGi4KXs5oAPugwyuZ/Qfq3LC2d1U07EWGvOBQK4SjTC56De\r\n        KKZDLwu+3WRBYLGLdJapCnMQ4lB/Ev29R9XYW9iqQfgOFE3iFdtcfts4+8Ig7y6CYe3A845VZWBD0\r\n        6SFu2obFZ8vGCRmF2qr0M9N9uxT+xOCRX7G5vkbH+TpFSiUQoV+cC5f9y98uCyj2xL60GxO+PZM8W\r\n        UJFYknRoX6SkVzfRwX+GWcdRc+nYSM1+I/hica32POuWur5lAhye0JO2SHTKSj66S+XjiM64fkh+b\r\n        HNp1LXf0ciEZQNIZeknVzClns6vHHDYYPI3iPYs+dTv3hoNPSDe4kee9BhuPWgRBS3uObPt6ySv46\r\n        QHJH4QWsUAAAAxcEHWBLJ1zw1Y5etR7t4EFeU5X8=&amp;lt;/CipherValue&amp;gt;\r\n      &amp;lt;/CipherData&amp;gt;\r\n    &amp;lt;/EncryptedData&amp;gt;\r\n  &amp;lt;/secureAppSettings&amp;gt;\r\n\r\n  &amp;lt;connectionStrings configProtectionProvider=&amp;quot;DataProtectionConfigurationProvider&amp;quot;&amp;gt;\r\n    &amp;lt;EncryptedData&amp;gt;\r\n      &amp;lt;CipherData&amp;gt;\r\n        &amp;lt;CipherValue&amp;gt;AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAALNO8kQcyL0SKbOQ8HQGp0AQAAAACAAAA\r\n        AAADZgAAqAAAABAAAABv17Dh+HaRnrZppOfniJMaAAAAAASAAACgAAAAEAAAAF1mqOQdo+lvm45mQ\r\n        MwaiaKoAQAAHVHExOIDaItnnbRK7n/qHudiSUAq22t2qRTSxQDxE/lYyN2gA/cWHTw4njHVRu+MJN\r\n        awquuIFKW7RLFAlDYdJPA2xPHakwJXt6MLCOgdXmd+YojqP7AYHrPbFuRGF/8sNY+SlH0QOZya53D\r\n        AuljzMUQoE27BQbsCT+tLriMnGgmc8SaCjAFqqVc538zxxKLFnLZJLttHm5qAq7/y65abZDMjYo4Y\r\n        m4RpmhxQ5ZyITWpGt8RWabZ10MgWvcWS+QiL+ONVhs7lgR5wo0tDk1aoMh0f2VrSZPfXYoC8ZR2JV\r\n        0jqVSNasYmZN/+AO2G+6/S8YxETJqYD3BL8qFBtok9NUzvvoGMZYw+lJniSoLCBWtNoFpFM90/v0x\r\n        hCfRZZqiYj/8OOpJQT38ycG1N/zskhK/LAKe7loZGgPMl1wUjnFGpLOHW+f2ikVtYtHkH3+qxqny8\r\n        AeSZKovMnhfZlXUJx18G0Ugpvskmgju9aKtnE6UWLZbiiygJAfifQUjTwjFXgibQmuvFPxlWuUSW7\r\n        e6fBzVggx1zpDqnu5RGksN+zOg3S7IyiC79GihQAAAAWBM1NaI+3SdfalbKCGvuhxxTNSQ==\r\n        &amp;lt;/CipherValue&amp;gt;\r\n      &amp;lt;/CipherData&amp;gt;\r\n    &amp;lt;/EncryptedData&amp;gt;\r\n  &amp;lt;/connectionStrings&amp;gt;\r\n&amp;lt;/configuration&amp;gt;');
					&lt;/script&gt;

&lt;p&gt;If we try and run our original console app the values for our secure settings won't be retrieved, which if you've been paying attention you'll no-doubt have worked this out as the values are no longer part of the appSettings section but part of the secureAppSettings section. So we need to update our original console app to look at this section instead: 
  &lt;br /&gt;

  &lt;br /&gt;&lt;/p&gt;

&lt;div class="csharpcode-wrapper"&gt;
  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Main(&lt;span class="kwrd"&gt;string&lt;/span&gt;[] args)&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:&lt;/span&gt;     &lt;span class="rem"&gt;// Write out the contents of the config file.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   4:&lt;/span&gt;     Console.WriteLine(&lt;span class="str"&gt;&amp;quot;MyConnectionString = &amp;quot;&lt;/span&gt; + &lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:&lt;/span&gt;         ConfigurationManager.ConnectionStrings[&lt;span class="str"&gt;&amp;quot;MyConnectionString&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   6:&lt;/span&gt;     Console.WriteLine(&lt;span class="str"&gt;&amp;quot;BufferSize = &amp;quot;&lt;/span&gt; + ConfigurationManager.AppSettings[&lt;span class="str"&gt;&amp;quot;BufferSize&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;   8:&lt;/span&gt;     &lt;span class="rem"&gt;// Access the secureAppSettings&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:&lt;/span&gt;     NameValueCollection secureAppSettings = &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  10:&lt;/span&gt;         (NameValueCollection)ConfigurationManager.GetSection(&lt;span class="str"&gt;&amp;quot;secureAppSettings&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:&lt;/span&gt;     Console.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeService.UserName = &amp;quot;&lt;/span&gt; + secureAppSettings[&lt;span class="str"&gt;&amp;quot;SomeService.UserName&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  12:&lt;/span&gt;     Console.WriteLine(&lt;span class="str"&gt;&amp;quot;SomeService.Password = &amp;quot;&lt;/span&gt; + secureAppSettings[&lt;span class="str"&gt;&amp;quot;SomeService.Password&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  13:&lt;/span&gt;&amp;#160; &lt;/pre&gt;

    &lt;pre class="alteven"&gt;&lt;span class="lnum"&gt;  14:&lt;/span&gt;     Console.ReadLine();&lt;/pre&gt;

    &lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  15:&lt;/span&gt; }&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;div class="CopyToClipboard" style=""&gt;&lt;div&gt;&lt;a href="javascript:void(0);" onclick="CopyToClipboard_ViewPlain(copyToClipboardf2f360d5153043ac924b938bd987e249_50859);"&gt;View Plain&lt;/a&gt; | &lt;a href="javascript:void(0);" onclick="CopyToClipboard_Copy(copyToClipboardf2f360d5153043ac924b938bd987e249_50859);"&gt;Copy To Clipboard&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
					&lt;script type="text/javascript"&gt;
						var copyToClipboardf2f360d5153043ac924b938bd987e249_50859 = CopyToClipboard_Strip('static void Main(string[] args)\r\n{\r\n    // Write out the contents of the config file.\r\n    Console.WriteLine(&amp;quot;MyConnectionString = &amp;quot; + \r\n        ConfigurationManager.ConnectionStrings[&amp;quot;MyConnectionString&amp;quot;]);\r\n    Console.WriteLine(&amp;quot;BufferSize = &amp;quot; + ConfigurationManager.AppSettings[&amp;quot;BufferSize&amp;quot;]);\r\n\r\n    // Access the secureAppSettings\r\n    NameValueCollection secureAppSettings = \r\n        (NameValueCollection)ConfigurationManager.GetSection(&amp;quot;secureAppSettings&amp;quot;);\r\n    Console.WriteLine(&amp;quot;SomeService.UserName = &amp;quot; + secureAppSettings[&amp;quot;SomeService.UserName&amp;quot;]);\r\n    Console.WriteLine(&amp;quot;SomeService.Password = &amp;quot; + secureAppSettings[&amp;quot;SomeService.Password&amp;quot;]);\r\n\r\n    Console.ReadLine();\r\n}');
					&lt;/script&gt;

&lt;p&gt;Running this version gives the same result as the original except that now all the parts that we want encrypted are. The really cool thing is that this works if the config is encrypted or not, which allows you to work with an un-encrypted version during dev and then have your Ops people encrypt it (once they put the real values in) just prior to deploy or as part of the deployment script.&lt;/p&gt;

&lt;div class="wlWriterSmartContent" id="scid:8eb9d37f-1541-4f29-b6f4-1eea890d4876:dbdc4edd-cec7-4be5-8aaa-864ec8e78b16" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;p&gt;&lt;div&gt;&lt;a href="http://dotnetprofessional.com/blog/file.axd?file=WindowsLiveWriter/EncryptsectionsofWeb.ConfigorApp.Config_FDE4/EncryptionSample_1.zip" target="_self"&gt;EncryptionSample.zip&lt;/a&gt;&lt;/div&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx&amp;amp;title=Encrypt sections of Web.Config or App.Config" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx&amp;amp;title=Encrypt sections of Web.Config or App.Config" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx&amp;amp;title=Encrypt sections of Web.Config or App.Config" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/dqyiqYEySgQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/dqyiqYEySgQ/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=fefa3f3f-3741-4795-b40e-b016d6f39de4</guid>
      <pubDate>Mon, 03 Mar 2008 18:03:24 -0800</pubDate>
      <category>.NET 1</category>
      <category>.NET 2.0</category>
      <category>ASP.NET</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=fefa3f3f-3741-4795-b40e-b016d6f39de4</pingback:target>
      <slash:comments>16</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=fefa3f3f-3741-4795-b40e-b016d6f39de4</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=fefa3f3f-3741-4795-b40e-b016d6f39de4</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=fefa3f3f-3741-4795-b40e-b016d6f39de4</feedburner:origLink></item>
    <item>
      <title>Programming Microsoft Message Queues (MSMQ) in .NET Book Chapters</title>
      <description>&lt;p&gt;Here is Chapters 4 &amp;amp; 5 of the book I never got around to publishing. The chapters cover MSMQ in a fair amount of depth, but remember whole books have been written on this subject. So don&amp;#8217;t expect it to be some type of bible. Having said that, if you don&amp;#8217;t need to be a guru then these Chapters will give you more than enough knowledge to start working with MSMQ and also explain why it&amp;#8217;s a good fit for a particular situation. I&amp;#8217;ve included the table of contents so you&amp;#8217;ll have an idea of what&amp;#8217;s being covered. If you have any feedback feel free to leave a comment!  &lt;/p&gt;  &lt;h2&gt;Chapter 4 Contents&lt;/h2&gt;  &lt;h3&gt;Message Queues 101.&lt;/h3&gt;  &lt;h4&gt;A Simple Analogy.&lt;/h4&gt;  &lt;h4&gt;The Mechanics.&lt;/h4&gt;  &lt;h4&gt;Types of Queues.&lt;/h4&gt;  &lt;h4&gt;Why use Message Queues?.&lt;/h4&gt;  &lt;h4&gt;What are my Options?.&lt;/h4&gt;  &lt;h4&gt;Choosing the correct option.&lt;/h4&gt;  &lt;h4&gt;Simple.&lt;/h4&gt;  &lt;h4&gt;Complex.&lt;/h4&gt;  &lt;h4&gt;Recoverable.&lt;/h4&gt;  &lt;h4&gt;Transactional &lt;/h4&gt;  &lt;h4&gt;Acknowledgements, Time Outs, Journaling and Dead-letters.&lt;/h4&gt;  &lt;h4&gt;Queued Components.&lt;/h4&gt;  &lt;h4&gt;MSMQ Triggers.&lt;/h4&gt;  &lt;h4&gt;Installing MSMQ. &lt;/h4&gt;  &lt;h3&gt;MessageQueue Object&lt;/h3&gt;  &lt;h4&gt;Queue to connect &lt;/h4&gt;  &lt;h4&gt;MessageQueue.Send. &lt;/h4&gt;  &lt;h4&gt;Simple Method. &lt;/h4&gt;  &lt;h4&gt;Example 1a &amp;#8211; Sending a Text Message (Hand coding) &lt;/h4&gt;  &lt;h4&gt;Example 1b &amp;#8211; Sending a Text Message (IDE) &lt;/h4&gt;  &lt;h4&gt;Complex Method. &lt;/h4&gt;  &lt;h4&gt;Example 2 &amp;#8211; Sending an Object &lt;/h4&gt;  &lt;h4&gt;Example 3 &amp;#8211; Recoverable Messages. &lt;/h4&gt;  &lt;h4&gt;MessageQueue.Receive. &lt;/h4&gt;  &lt;h4&gt;Example 4 &amp;#8211; Message Monitor &lt;/h4&gt;  &lt;h4&gt;Static Methods. &lt;/h4&gt;  &lt;h3&gt;Summary. &lt;/h3&gt;  &lt;h4&gt;Resources: &lt;/h4&gt;  &lt;h2&gt;Chapter 5 Contents&lt;/h2&gt;  &lt;h3&gt;Using Transactions. &lt;/h3&gt;  &lt;h4&gt;Internal Transactions. &lt;/h4&gt;  &lt;h4&gt;Example 5 &amp;#8211; Sending a Transactional Message. &lt;/h4&gt;  &lt;h4&gt;External Transactions. &lt;/h4&gt;  &lt;h4&gt;Using COM+ for DTC Support &lt;/h4&gt;  &lt;h4&gt;Using COM+ to update a Database. &lt;/h4&gt;  &lt;h4&gt;Example 5c &amp;#8211; Creating a DTC enabled Message receiver &lt;/h4&gt;  &lt;h4&gt;Acknowledgements, Time outs and Journaling. &lt;/h4&gt;  &lt;h3&gt;Acknowledgements. &lt;/h3&gt;  &lt;h4&gt;Example 6a &amp;#8211; Setting Acknowledgements. &lt;/h4&gt;  &lt;h4&gt;Example 6b &amp;#8211; Receiving Acknowledgements. &lt;/h4&gt;  &lt;h4&gt;Example 6c &amp;#8211; Receiving Messages. &lt;/h4&gt;  &lt;h4&gt;Timeouts. &lt;/h4&gt;  &lt;h4&gt;Example 7 &amp;#8211; Timeouts. &lt;/h4&gt;  &lt;h4&gt;Journaling &amp;amp; Dead-letters. &lt;/h4&gt;  &lt;h4&gt;Example 8a &amp;#8211; Keeping copies of received messages. &lt;/h4&gt;  &lt;h4&gt;Example 8b &amp;#8211; Keeping copies of sent messages. &lt;/h4&gt;  &lt;h4&gt;Example 8c Receiving messages from Public Queues. &lt;/h4&gt;  &lt;h4&gt;Example 8d &amp;#8211; Resending a Timed out message. &lt;/h4&gt;  &lt;p&gt;&amp;#160; &lt;/p&gt;  &lt;h3&gt;WMI.&lt;/h3&gt;  &lt;h3&gt;Summary. &lt;/h3&gt;  &lt;h4&gt;Resources: &lt;/h4&gt;  &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/file.axd?file=CHAPTER+4+-+Message+Queues.pdf" rel="enclosure"&gt;CHAPTER 4 - Message Queues.pdf (627.48 kb)&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/file.axd?file=CHAPTER+5+-+Message+Queues+II.pdf" rel="enclosure"&gt;CHAPTER 5 - Message Queues II.pdf (503.01 kb)&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/file.axd?file=MSMQ+Samples.zip" rel="enclosure"&gt;MSMQ Samples.zip (170.97 kb)&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dotnetprofessional.com/blog/post/2007/09/The-dotNetProfessional---Its-been-awhile.aspx"&gt;Book Table of Contents&lt;/a&gt;&lt;/p&gt;&lt;div class="socialBookmarksContainer"&gt;&lt;a rel="nofollow" href="http://digg.com/submit/?url=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx" target="_blank" title="Digg It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/digg_24.png" style="border: 0;" alt="Digg It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.dzone.com/links/add.html?url=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx&amp;amp;title=Programming Microsoft Message Queues (MSMQ) in .NET Book Chapters" target="_blank" title="DZone It!"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/dzone_24.png" style="border: 0;" alt="DZone It!" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.stumbleupon.com/submit?url=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx" target="_blank" title="StumbleUpon"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/stumbleupon_24.png" style="border: 0;" alt="StumbleUpon" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://technorati.com/ping?url=http://www.dotnetprofessional.com/blog/" target="_blank" title="Technorati"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/technorati_24.png" style="border: 0;" alt="Technorati" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://reddit.com/submit?url=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx&amp;amp;title=Programming Microsoft Message Queues (MSMQ) in .NET Book Chapters" target="_blank" title="Reddit"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/reddit_24.png" style="border: 0;" alt="Reddit" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://del.icio.us/post?url=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx&amp;amp;title=Programming Microsoft Message Queues (MSMQ) in .NET Book Chapters" target="_blank" title="Del.icio.us"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/delicious_24.png" style="border: 0;" alt="Del.icio.us" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://www.newsvine.com/_wine/save?u=http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx" target="_blank"title="NewsVine"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/newsvine_24.png" style="border: 0;" alt="NewsVine" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://furl.net" target="_blank" title="Furl"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/furl_24.png" style="border: 0;" alt="Furl" /&gt;&lt;/a&gt;&lt;a rel="nofollow" href="http://blinklist.com/submit/" target="_blank" title="BlinkList"&gt;&lt;img src="/blog/themes/dnpTheme/socialbookmarks/circle/blinklist_24.png" style="border: 0;" alt="BlinkList" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Dotnetprofessional/~4/WyBLnLZixXQ" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/Dotnetprofessional/~3/WyBLnLZixXQ/post.aspx</link>
      <author>garrmc.nospam@nospam.dotNetProfessional.com (garrymc)</author>
      <comments>http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx#comment</comments>
      <guid isPermaLink="false">http://www.dotnetprofessional.com/blog/post.aspx?id=d7d66310-b677-4694-89be-05369428efd1</guid>
      <pubDate>Tue, 09 Oct 2007 19:11:30 -0800</pubDate>
      <category>.NET 1</category>
      <category>Book</category>
      <dc:publisher>garrymc</dc:publisher>
      <pingback:server>http://www.dotnetprofessional.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.dotnetprofessional.com/blog/post.aspx?id=d7d66310-b677-4694-89be-05369428efd1</pingback:target>
      <slash:comments>9</slash:comments>
      <trackback:ping>http://www.dotnetprofessional.com/blog/trackback.axd?id=d7d66310-b677-4694-89be-05369428efd1</trackback:ping>
      <wfw:comment>http://www.dotnetprofessional.com/blog/post/2007/10/09/Programming-Microsoft-Message-Queues-(MSMQ)-in-NET-Book-Chapters.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.dotnetprofessional.com/blog/syndication.axd?post=d7d66310-b677-4694-89be-05369428efd1</wfw:commentRss>
    <feedburner:origLink>http://www.dotnetprofessional.com/blog/post.aspx?id=d7d66310-b677-4694-89be-05369428efd1</feedburner:origLink></item>
  </channel>
</rss>
