<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>ASP.NET</title>
        <link>http://blogs.sftsrc.com/stuart/category/4.aspx</link>
        <description>ASP.NET</description>
        <language>en-US</language>
        <copyright>Stuart Thompson</copyright>
        <managingEditor>stuart.thompson@sftsrc.com</managingEditor>
        <generator>Subtext Version 1.9.5.0</generator>
        <item>
            <title>The ASP.NET, Silverlight, PHP, Rails Experiment</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx</link>
            <description>&lt;p style="text-align: justify;"&gt;I've been working with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/default.aspx"&gt;Microsoft technologies&lt;/a&gt; for over ten years, specifically &lt;a target="_blank" href="http://www.asp.net/"&gt;Microsoft's web development technologies&lt;/a&gt;.  During that time I have built a variety sites ranging in scope from e-commerce, educational, service provision, &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Software_as_a_Service"&gt;SaaS&lt;/a&gt;, to dashboards, portals, internal tools, and even SAP-migration.  While I praise the technology stack for what it allows me to do, it also comes with a whole host of limitations that make it hard for me to deliver the experience my clients would like.  Throughout this decade of web development I have heard a lot from those around me about alternative technology stacks that promise all manner of improvements and experiences.  Unfortunately there is a lot of resistance from any one technology stack to listen to and learn from the stacks around them, most of the cross-platform feedback comes in the form of "Microsoft sucks" or "PHP is for fan-boy script kiddies".  The truth is that a large number of successful business are hosted on a wide variety of platforms.  Each technology stack has to at least be viable for that to be true.  The problem is getting at the truth without the zealous noise of "my stacks better than your stack" getting in the way.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;I decided that it was time for me to branch out and become more informed on these technologies myself so that I could truly understand the differences and what made each of them unique.  I'm hoping that as part of this experience I can not only become a better developer but also learn the problems that Ruby on Rails or PHP addresses.  I'll like to be able to speak from an informed standpoint about the differences between the Microsoft and open-source approaches as well as better understand the problems each of those development worlds faces on a daily basis.  Either way, it's going to be a heck of a lot of fun.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The experiment I have in mind is to build the same web-site using four different technologies.  From the Microsoft camp I have chosen &lt;a target="_blank" href="http://www.asp.net"&gt;ASP.NET&lt;/a&gt; and &lt;a target="_blank" href="http://silverlight.net/"&gt;Silverlight&lt;/a&gt;.  From the open-source perspective I have chosen &lt;a target="_blank" href="http://www.php.net/"&gt;PHP&lt;/a&gt; and &lt;a target="_blank" href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt;.  I chose PHP and RoR because they are two technologies that I have always wanted to learn.  Learning both of those will also require some digging into &lt;a target="_blank" href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; and &lt;a target="_blank" href="http://www.linux.org"&gt;Linux&lt;/a&gt;, another two areas that I have too little direct experience with to effectively participate in an informed conversation.&lt;/p&gt;
&lt;p style="text-align: center;"&gt;&lt;a href="http://www.asp.net"&gt;&lt;img height="44" width="108" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/logo.png" title="ASP.NET" class="alignnone size-full wp-image-48" /&gt; &lt;/a&gt; &lt;a href="http://www.silverlight.net"&gt;&lt;img height="45" width="131" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/silverlightlogo.jpg" title="silverlightlogo" class="alignnone size-full wp-image-49" /&gt; &lt;/a&gt;&lt;a href="http://www.php.net"&gt;&lt;img height="49" width="86" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/php.gif" title="php" class="alignnone size-full wp-image-50" /&gt; &lt;/a&gt;&lt;a href="http://www.rubyonrails.org"&gt;&lt;img height="54" width="42" alt="" src="http://stuartthompsontech.wordpress.com/files/2008/10/rails.png?w=74" title="rails" class="alignnone size-thumbnail wp-image-51" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;Our horses are ready to race.  In terms of hosting, I have selected &lt;a target="_blank" href="http://www.dreamhost.com"&gt;DreamHost&lt;/a&gt; for the PHP and Rails sites, and I'm going to use &lt;a target="_blank" href="http://www.stormhosts.com"&gt;StormHosts&lt;/a&gt; for the &lt;a target="_blank" href="http://www.asp.net"&gt;ASP.NET&lt;/a&gt; and &lt;a target="_blank" href="http://www.silverlight.net"&gt;Silverlight&lt;/a&gt; projects (assuming that SH can do .NET 3.5, which I believe I saw at some point).  The reason I'm using remote hosting services for this experiment is that I don't believe you get the true experience of a technology stack until you host it in this way.  It is very easy to get a Rails site up and running using &lt;a target="_blank" href="http://www.webrick.org"&gt;WEBrick&lt;/a&gt; and a local installation of Ruby.  Similarly, it is easy to get an ASP.NET site running on the personal web server that ships with &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/vstudio/default.aspx"&gt;Visual Studio 2008&lt;/a&gt;.&lt;/p&gt;
&lt;p style="text-align: justify;"&gt;The first phase of the experiment is to get a "Hello World!" site up and running for each of the four environments.  The specifications are that a single end-point be accessible that displays the text "Hello World!" and that this end-point is accessible in both &lt;a target="_blank" href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx"&gt;Internet Explorer&lt;/a&gt; 7 and &lt;a target="_blank" href="http://www.mozilla.com/en-US/firefox/"&gt;FireFox&lt;/a&gt; 3.&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/108.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx</guid>
            <pubDate>Mon, 27 Oct 2008 20:06:37 GMT</pubDate>
            <wfw:comment>http://blogs.sftsrc.com/stuart/comments/108.aspx</wfw:comment>
            <comments>http://blogs.sftsrc.com/stuart/archive/2008/10/27/108.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/108.aspx</wfw:commentRss>
        </item>
        <item>
            <title>JavaScript Print Button</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2008/06/24/92.aspx</link>
            <description>&lt;p&gt;To implement a print button on a web page, you can use the &lt;font face="Courier New"&gt;window.print()&lt;/font&gt; javascript function.  The following example shows an image that is displaying a printer icon and will print the current page when clicked.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code:&lt;/strong&gt;&lt;br /&gt;
&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#800000"&gt;img&lt;/font&gt; &lt;font color="#ff0000"&gt;border&lt;/font&gt;&lt;font color="#0000ff"&gt;="0"&lt;/font&gt; &lt;font color="#ff0000"&gt;onclick&lt;/font&gt;&lt;font color="#0000ff"&gt;="window.print();"&lt;/font&gt; &lt;font color="#ff0000"&gt;src&lt;/font&gt;&lt;font color="#0000ff"&gt;="/images/PrintIcon.gif" &lt;font color="#ff0000"&gt;style&lt;/font&gt;="cursor:hand;" /&amp;gt;&lt;/font&gt;&lt;br /&gt;
&lt;/font&gt;&lt;font color="#808080"&gt;&lt;em&gt;(Replace the text &lt;font face="Courier New"&gt;/images/PrintIcon.gif&lt;/font&gt; with the location of an icon in your site.)&lt;/em&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br /&gt;
&lt;img border="0" src="http://www.stuartthompson.net/BlogImages/Tech/04-03-2008-JavascriptPrintButton/04-03-2008-PrintButton.bmp" alt="" onclick="window.print();" style="" /&gt; &lt;/p&gt;
&lt;p&gt;A better application of this idea is to first create a page that renders a print preview of the information you want to print.  This print preview will look similar to the original page but will not contain navigation items, header images, or other page clutter.  Furthermore, the data can be formatted to fit cleanly on 8.5" x 11" paper.  Embed the print icon in the print preview page and allow users to print from there. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/92.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2008/06/24/92.aspx</guid>
            <pubDate>Tue, 24 Jun 2008 15:19:40 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2008/06/24/92.aspx#feedback</comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/92.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day Two - Creating Custom Data Source Controls</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/17/68.aspx</link>
            <description>&lt;p&gt;
Presenter: Rocky Lhotka&lt;br /&gt;
Code: &lt;a href="http://www.lhotka.net"&gt;http://www.lhotka.net&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This discussion contains information about creating custom data source controls.  Before diving into the concepts involved, lets first consider a justification for such development.  This is provided in the form of an analysis of the two most commonly used controls that are available for that purpose:
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;SqlDataSource&lt;/u&gt;&lt;br /&gt;
The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sqldatasource.aspx"&gt;&lt;span style="font-family:Courier,New"&gt;SqlDataSource&lt;/span&gt;&lt;/a&gt; object allows developers to retrieve data from a database directly and use data-binding to display and edit the data inside of web or windows forms.  However, this is really only useful in 2-tier applications and leads to a poor architecture.  I find the &lt;span style="font-family:Courier,New"&gt;SqlDataSource&lt;/span&gt; control to be most useful in prototyping.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;ObjectDataSource&lt;/u&gt;&lt;br /&gt;
The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.objectdatasource.aspx"&gt;&lt;span style="font-family:Courier,New"&gt;ObjectDataSource&lt;/span&gt;&lt;/a&gt;, while vastly superior to the &lt;span style="font-family:Courier,New"&gt;SqlDataSource&lt;/span&gt; control, is still quite restrictive in several ways.  It requires the presence of a default public constructor and restricts the use of read-only properties in the objects with which it can interact.  Having a default public constructor weakens the application of a factory pattern for object creation, and the lack of support for read-only properties weakens the encapsulation of the objects.  Furthermore, the &lt;span style="font-family:Courier,New"&gt;ObjectDataSource&lt;/span&gt; control was originally called the &lt;span style="font-family:Courier,New"&gt;DataSetDataSource&lt;/span&gt; control and was originally intended exclusively for the purpose of connecting to data sets.  The fact that it also works for custom object types is more of an accidental side-effect than a planned purpose.  Another weakness of the &lt;span style="font-family:Courier,New"&gt;ObjectDataSource&lt;/span&gt; control is that it uses reflection to invoke methods upon your custom objects at run-time based upon string names of those methods that were configured at design-time.  However, this provides no compile-time warning or errors in the case that a method name was typed into the designer or markup incorrectly or in the case that the method name is changed.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Base Classes for a custom Data Source&lt;/b&gt;&lt;br /&gt;
There are four base classes that are important when implementing a custom data source control:&lt;br /&gt;
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;DataSourceControl&lt;/li&gt;
&lt;li&gt;DataSourceView&lt;/li&gt;
&lt;li&gt;DataSourceDesigner&lt;/li&gt;
&lt;li&gt;DesignerDataSourceView&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
There are also three interfaces that need to be implemented:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;IDataSourceSchema&lt;/li&gt;
&lt;li&gt;IDataSourceViewSchema&lt;/li&gt;
&lt;li&gt;IDataSourceFieldSchema&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;table border="1" cellpadding="1" cellspacing="0"&gt;
	&lt;tr&gt;
		&lt;td style="background-color:blue;color:white;font-family:Courier, New"&gt;DataSource&lt;/td&gt;
		&lt;td style="background-color:blue;color:white;font-family:Courier, New"&gt;DataSourceView&lt;/td&gt;
		&lt;td&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td style="background-color:green;color:white;font-family:Courier, New"&gt;DataSourceDesigner&lt;/td&gt;
		&lt;td style="background-color:green;color:white;font-family:Courier, New"&gt;DesignerDatasourceView&lt;/td&gt;
		&lt;td&gt; &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td style="background-color:purple;color:white;font-family:Courier, New"&gt;ObjectSchema&lt;/td&gt;
		&lt;td style="background-color:purple;color:white;font-family:Courier, New"&gt;ObjectViewSchema&lt;/td&gt;
		&lt;td style="background-color:purple;color:white;font-family:Courier, New"&gt;ObjectFieldInfo&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td style="background-color:darkblue;color:white;font-family:Courier, New"&gt;Configuration&lt;/td&gt;
		&lt;td&gt; &lt;/td&gt;
		&lt;td&gt; &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;Debugging Custom Data Source Controls&lt;/b&gt;&lt;br /&gt;
The debugging story for custom control development is a little different from the typical debugging experience because the runtime and design-time execution is actually happening within Visual Studio itself.  Typically an external executable or a web hosting service such as IIS would host the code.  However, for a custom control it is Visual Studio that is executing the designer  and run-time code and as such the debugging story needs to change slightly.  The way in which we debug custom controls in Visual Studio is to start a second instance that will be the test host and then attach to the process of that Visual Studio instance with the main instance from which we will perform the debugging.  Now breakpoints will be hit in the first instance of Visual Studio as the second instance of Visual Studio executes the code within the custom control.

&lt;p&gt;
&lt;b&gt;Run-time Support&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;The base DataSourceControl class&lt;/u&gt;&lt;br /&gt;
The base class to use for a custom data source control is &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.datasourcecontrol.aspx"&gt;&lt;span style="font-family: Courier, New"&gt;System.Web.UI.DataSourceControl&lt;/span&gt;&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;The base DataSourceView class&lt;/u&gt;&lt;br /&gt;
The data source view derivation actually performs the bulk of the work for the control.  This class is derived from the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.datasourceview.aspx"&gt;&lt;span style="font-family: Courier, New"&gt;System.Web.UI.DataSourceView&lt;/span&gt;&lt;/a&gt;.  To implement a derived data source view class, you &lt;b&gt;must&lt;/b&gt; override the &lt;span style="font-family: Courier, New"&gt;ExecuteSelect&lt;/span&gt; method from the base DataSourceView class.  When a data-bound control is rendering, for example a GridView, the control realizes that it does not have a data source.  However, it realizes that a data source control is configured and &lt;i&gt;asks&lt;/i&gt; the data source control for some data.  This raises the &lt;span style="font-family: Courier, New"&gt;ExecuteSelect&lt;/span&gt; method on the derived &lt;span style="font-family: Courier, New"&gt;DataSourceView&lt;/span&gt; class.  It is in this method that the data for the source is read and returned.  Additional properties such as row count, for paging, are set during the method.  The assumption is that once the &lt;span style="font-family: Courier, New"&gt;ExecuteSelect&lt;/span&gt; method has completed, the data-bound control that originally made the request will be able to commence with data binding.  Other methods such as &lt;span style="font-family: Courier, New"&gt;ExecuteInsert&lt;/span&gt; need to be overridden as appropriate for the data source control, based upon whether or not the control support such actions.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Design-time Support&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;The DataSourceDesigner base class&lt;/u&gt;&lt;br /&gt;
The base class &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.design.datasourcedesigner.aspx"&gt;&lt;span style="font-family: Courier, New"&gt;DataSourceDesigner&lt;/span&gt;&lt;/a&gt; is a fairly thin class that essentially specifies the view for the data source designer as well as a couple of extra information attributes that are used in the design-time experience.
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;The DesignerDataSourceView base class&lt;/u&gt;&lt;br /&gt;
The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.design.designerdatasourceview.aspx"&gt;&lt;span style="font-family: Courier, New"&gt;DesignerDataSourceView&lt;/span&gt;&lt;/a&gt; base class is used to derive the view class that will provide the bulk of the design-time support for your custom control.  It is from within your designer data source view class that you will return properties such as the schema or list of fields that describe the currently configured data source for the control.  This is a complex concept to visualize right away, however consider that the &lt;span style="font-family: Courier, New"&gt;ObjectDataSource&lt;/span&gt; control uses reflection to determine the list of fields that exist upon the object type that is currently configured within the control.  It is this list of fields that is used to populate the dialogs within the design-time view of the control.  Other methods such as &lt;span style="font-family: Courier, New"&gt;GetDesignTimeData&lt;/span&gt; should be overridden to, in that example, return the data that is used to populate the design-time view of the control.  In the case of the grid-view control (not a data source but a similar paradigm) this is the sample data that is displayed that looks like "abc" in each of several sample rows.
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/68.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/17/68.aspx</guid>
            <pubDate>Wed, 17 Oct 2007 23:59:46 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/17/68.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/68.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 7 - State Management</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/67.aspx</link>
            <description>&lt;p&gt;
&lt;b&gt;Session Management&lt;/b&gt;&lt;br /&gt;
In much the same way as the configuration management class was written, a session management class can be written to encapsulate access to session variables.  This allows for first-class properties to be used when writing to and reading from session.  This provides for Intellisense when working with session variables as well as garnering the advantage of receiving compile-time errors when mistakes are made while architecting the session management class.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Page Request Life Cycle&lt;/b&gt;&lt;br /&gt;
The following diagram was shared by Paul because the workshop had ended a little early.  It's a picture I've had in my mind ever since I started developing ASP.NET pages, but I thought that it might be of interest to others so I wanted to recreate it and post it here:
&lt;/p&gt;
&lt;p&gt;
&lt;img border="0" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part7/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part7-PageRequestLifeCycle.jpg" /&gt;
&lt;/p&gt;
&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/67.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/67.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 21:43:50 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/67.aspx#feedback</comments>
            <slash:comments>28</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/67.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 6 - Skins and Themes</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/66.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Skins &amp;amp; Themes&lt;/strong&gt;&lt;br /&gt;
Styling complex controls such as Calendars and GridViews can be very difficult because of the way in which they render.  To address this problem, Microsoft developed the concept of skins and themes.  Skins and themes can be thought of as a server-side version of style sheets. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Skins&lt;/strong&gt;&lt;br /&gt;
Skin files have a .skin file extension.  They live in the "App_Themes" folder.  There are two types of control skins: default skins and named skins.  Default skins apply to all controls of the same type when a Theme is applied to a page.  Default skins do not have a SkinID attribute.  Named skins have a SkinID attribute set and do not automatically apply to controls when a Theme is applied. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Themes&lt;/strong&gt;&lt;br /&gt;
Themes are special folders that contain .skin files.  The name of the folder dictates the name of the theme.  The @Page directive has an attribute named Theme within which a named theme can be specified.  To programmatically set the theme for a page, override the &lt;span style="FONT-FAMILY: Courier, New"&gt;OnPreInit&lt;/span&gt; event handler and set &lt;span style="FONT-FAMILY: Courier, New"&gt;base.Theme = "MyTheme";&lt;/span&gt;.  Alternatively the theme can be specified in the web.config file using the following syntax:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;&amp;lt;system.web&amp;gt;&lt;br /&gt;
  &amp;lt;pages theme="MyTheme"/&amp;gt;&lt;br /&gt;
&amp;lt;/system.web&amp;gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme-specific Images&lt;/strong&gt;&lt;br /&gt;
Consider that you are developing a multi-branded site whereby the branding logos that a user sees within a banner area are different for each user.  A user from company A wants to see a different banner image than a user from company B despite the fact that they are actually browsing the same site.  One solution to this problem is to use theme-specific images.  Create a folder beneath the theme folder called &lt;span style="FONT-FAMILY: Courier, New"&gt;Images&lt;/span&gt; and place the brand-specific images for that theme into that folder.  Define a skin file for the images called Images.skin and within that skin file define a skin with named IDs for each of the branding images.  The skin can define any of the regular attributes for a server control, including the image path and alternate text.  Within the actual web form markup, specify only:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;&amp;lt;asp:Image ID="imgMainLogo" SkinID="MainLogoSkin" runat="server" /&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This allows the skin to specify the path for the image, and even more importantly allows the skin to specify a relative path to the &lt;span style="FONT-FAMILY: Courier, New"&gt;Images&lt;/span&gt; directory that we created within the theme directory.  Now by choosing a different theme for the page, the branding images displayed on that page will also change.  This is a really neat way to encapsulate branding changes within the theme and means that branding specific code is reduced to the single line of code that applies the appropriate theme. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/66.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/66.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 21:43:07 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/66.aspx#feedback</comments>
            <slash:comments>109</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/66.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 5 - CSS</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/65.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Structure versus Design&lt;/strong&gt;&lt;br /&gt;
The &lt;em&gt;structure&lt;/em&gt; of a web page is the physical HTML elements (not the server controls) as opposed to the &lt;em&gt;design&lt;/em&gt; which is the application of styles such as color, font size, or setting whether some text is bold.  Cascading style sheets provide a mechanism for separating the structure of a page from its design.  This is desirable because it removes duplication within the structure of a page.  Fixing errors with styles that are declared inline with the structure of a page can be very time consuming: i.e. if a &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: blue"&gt;blue&lt;/span&gt;&lt;/span&gt; is declared on every td (table cell) within a page and the business decides that they all need to be &lt;span style="COLOR: red"&gt;red&lt;/span&gt;, the tag must be updated for every table cell in the page.  Instead, if a style sheet is used to define that all &lt;span style="FONT-FAMILY: Courier, New"&gt;td&lt;/span&gt; elements have &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: blue"&gt;blue&lt;/span&gt;&lt;/span&gt;, then the update only needs to be performed in one location. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overriding Styles&lt;/strong&gt;&lt;br /&gt;
Cascading style sheets get their name from the fact that they have a cascading inheritance model.  If two style sheets or inline styles define style information upon the same element, the last style in the list will take precedence.  What this means is that if a style sheet named global.css defines a style of &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: blue"&gt;blue&lt;/span&gt;&lt;/span&gt; on the &lt;span style="FONT-FAMILY: Courier, New"&gt;td&lt;/span&gt; element, but an inline style on a page that includes global.css also defines &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: red"&gt;red&lt;/span&gt;&lt;/span&gt; on the &lt;span style="FONT-FAMILY: Courier, New"&gt;td&lt;/span&gt; element, then the &lt;span style="FONT-FAMILY: Courier, New"&gt;td&lt;/span&gt; element will be rendered based upon which style came last in the page.  If the global.css file is included before the inline style on the page, then the &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: red"&gt;red&lt;/span&gt;&lt;/span&gt; style will be applied, otherwise if the global.css file is included after the inline style then the &lt;span style="FONT-FAMILY: Courier, New"&gt;color=&lt;span style="COLOR: blue"&gt;blue&lt;/span&gt;&lt;/span&gt; style will be applied. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-MedDistance.jpg"&gt;&lt;img alt="" border="0" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-MedDistance_Thumbnail.jpg" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Different style types&lt;/strong&gt;&lt;br /&gt;
There are different style types that can be defined:&lt;br /&gt;
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Element styles are applied directly to certain html elements: i.e. &lt;span style="FONT-FAMILY: Courier, New"&gt;td { color=&lt;span style="COLOR: red"&gt;red&lt;/span&gt; }&lt;/span&gt; &lt;/li&gt;
    &lt;li&gt;Identifier styles are applied to elements with a particular id: i.e. &lt;span style="FONT-FAMILY: Courier, New"&gt;#divContainer { color=&lt;span style="COLOR: red"&gt;red&lt;/span&gt; }&lt;/span&gt; &lt;/li&gt;
    &lt;li&gt;Class styles are applied to elements with a particular class: i.e. &lt;span style="FONT-FAMILY: Courier, New"&gt;.myClass { color=&lt;span style="COLOR: red"&gt;red&lt;/span&gt; }&lt;/span&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;u&gt;Element Styles&lt;/u&gt;&lt;br /&gt;
Element styles are appropriate for situations where a particular style needs to be applied to all elements of a particular type.  This can be used to satisfy requirements like "All table cells must have green text within them."  The most typical use of element styles is for padding, margins, spacing, and other spacial based layout requirements.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Identifier Styles&lt;/u&gt;&lt;br /&gt;
Identifier styles are appropriate when controls with a particular identifier needs some aesthetic manipulation.  This type of style application is used most rarely.  Identifier based styles are quite restrictive to apply by virtue of the fact that they are only applied to elements with a particular identifier.&lt;br /&gt;&lt;br /&gt;
&lt;u&gt;Class Styles&lt;/u&gt;&lt;br /&gt;
Class styles are applied to elements with a particular css class specified upon them.  This is a very common form of style application because it allows a library of styles to be developed ahead of time and then leveraged during the development of the application.  Developers of a page can then choose to use one of the styles from this library to apply design to their elements.  If the library of styles is managed by a design department within the company, that department can retain control of the style information for that known class, allowing them to update the styles for the application without incurring additional work for the developers. 
&lt;p&gt;&lt;a href="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-FullHall.jpg"&gt;&lt;img alt="" border="0" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-FullHall_Thumbnail.jpg" /&gt;&lt;/a&gt;  &lt;a href="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-Close.jpg"&gt;&lt;img alt="" border="0" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part5-Close_Thumbnail.jpg" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shorthand Style Definitions&lt;/strong&gt;&lt;br /&gt;
Certain styles can be written in shorthand.  For example, consider the following definition for an all around margin of twelve pixels:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;margin-left: 12px;&lt;br /&gt;
margin-top: 12px;&lt;br /&gt;
margin-right: 12px;&lt;br /&gt;
margin-bottom: 12px; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This can be rewritten in shorthand as:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;margin: 12px 12px 12px 12px; &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
However, this can cause problems because not all browsers interpret the shorthand versions of the style definitions correctly.  It is safest to define styles using the long-hand versions. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/65.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/65.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 21:42:15 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/65.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/65.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 4 - Exception Handling</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/64.aspx</link>
            <description>&lt;p&gt;
&lt;b&gt;Exception Providers&lt;/b&gt;&lt;br /&gt;
Exception providers can be used to publish exception information to a variety of sources.  This is useful because user's of an application often fail to capture exception information when they encounter a failure.  To address this, an ExceptionManager class could be developed to publish exception information to a collection of subscribers.  These subscribers might be common destinations such as the event log, a table in a database, a file on disk, or an email address.  When an exception is caught, something along the lines of:&lt;br /&gt;
&lt;span style="font-family: Courier, New"&gt;
try {&lt;br /&gt;
    &lt;i&gt;... some code ...&lt;/i&gt;&lt;br /&gt;
}&lt;br /&gt;
catch (System.Exception ex) {&lt;br /&gt;
    ExceptionManager.Publish(ex);&lt;br /&gt;
}
&lt;/span&gt;&lt;br /&gt;
could be used to invoke the functionality of a &lt;span style="font-family: Courier, New"&gt;ExceptionManager&lt;/span&gt; class.  The purpose of this is to capture that information whether or not the user chooses to report the problem and furthermore irrespective of whether that user captures all of the relevant information from the exception.  A very mature version of this kind of idea is visible in most &lt;a href="http://www.microsoft.com"&gt;Microsoft&lt;/a&gt; applications with the familiar "Send Error Report" dialog.  Whenever a Microsoft application encounters an unexpected error, a full report is prepared and saved to disk.  The application then asks for permission to transmit the information about this error report to Microsoft.  This allows a knowledge-base of known exception situations to be constructed in an automated fashion.  Futhermore, if user's contact Microsoft about specific failures in their application, the mechanism for capturing the exception information is in place, even if that user typically clicks the "Don't Send" button.  The information can still be captured when the user decides that they want to enlist the help of Microsoft to diagnose the problem.  The exception handling and publishing provider model presented here is a very simplified version of that idea.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;How is the provider model appropriate?&lt;/b&gt;&lt;br /&gt;
The ExceptionManager queries a configuration file to determine the list of exception publishers that are currently active.  Each configured publisher is dynamically instantiated based upon the provider implementation that it cites in its configuration element.  Because each publisher provider implements a known interface, say IExceptionInformationPublisher, the ExceptionManager class can call the methods on that interface to pass the exception information to each implemented publisher.  Continuing the example above, assume that the IExceptionInformationPublisher interface contained a method with signature Publish(Exception ex), the ExceptionManager would call that method upon each publisher.  The publishers then know how to process and publish that exception information to their specific destination.  The complexities of writing to the event log are thus abstracted into that particular publisher provider's implementation, isolating those details not only from the application itself but also from the ExceptionManager class.
&lt;/p&gt;
&lt;p&gt;
This leads to an exception information publishing framework with a configurable list of destinations for that information.  If one of the publishers fails to record the information, including the user as a publisher, there is a good chance that some of the other publishers will succeed and the exception information will still be captured.  This can be an invaluable tool for debugging and correcting errors within an application.
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;
NOTE: Astute readers will realize that log4net comes with a lot of this functionality already built in and integrating log4net with an application will allow exception information to be published to a similar list of sources.  While correct, it is important to remember that this is an instructional example.  Log4net uses a provider model to provide its listener architecture, this example demonstrates how a provider model can be implemented.
&lt;/i&gt;
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/64.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/64.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 17:32:49 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/64.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/64.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 3 - Example Providers</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/63.aspx</link>
            <description>&lt;p&gt;
&lt;b&gt;Encapsulating ADO.NET&lt;/b&gt;&lt;br /&gt;
A couple of real world examples of providers that are useful in almost every application are that of an encapsulated data access layer and a configuration management component.  Data access layers use providers to perform dependency injection, allowing for multiple different implementations of a set of data access interfaces, with each implementation exposing functionality to communicate with different data sources.  This is a fairly common form of encapsulation that many developers are already familiar with implementing, but there are still many areas in which the correct provider and package design can return many architectural, maintenance, and extensibility benefits.  Providers should be completely decoupled from the data access layer proper, as should the interfaces that define the actual data adapters and classes with which a consuming layer will interact.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;Configuration Management Provider&lt;/b&gt;&lt;br /&gt;
One of the purposes of building a custom configuration management provider is to allow for settings to be stored in different locations.  By abstracting the location away from configuration querying, the business choices about where to store configuration information can change without causing high maintenance expense within the application itself.  A dependency injection (dynamic class loading) methodology is used to instantiate a configuration management provider class at runtime, allowing the provider to be switch based upon a configuration setting in the .NET configuration filesfile.  While that may make it sound as though the abstraction has been broken, remember that only the configuration management implementation is being stored in the .NET configuration file, in only one place.  This is a nice single layer abstraction of the configuration strategy and removes reliance upon the .NET config files, locations, and structures.  The argument for this is to allow for a business to choose to, for example, switch to storing configuration settings in the registry based upon the result of a security audit that declared file-system based configuration files as unsecure.  Because the configuration manager that is used to manage the configured provider list is also configured within the .NET configuration files, even that manager can be changed out cheaply and easily at a later date in the project if business decisions require such a change.  It is important to understand that this is a good balance and trade off from over-engineering.  Simple abstraction is not an over-engineered solution.  Authoring a second configuration manager "just in case it's needed" would be an over-engineered solution.  Providing the hooks for extensibility is simply good architecture and this kind of planning will save many projects from &lt;i&gt;show-stopper&lt;/i&gt; changes that classically would cause engineering nightmares.  The extensibility and flexibility of a well abstracted architecture allows engineers to adapt to technology and business changes by planning for the &lt;i&gt;possibility&lt;/i&gt; of such changes ahead of time.
&lt;/p&gt;
&lt;p&gt;
&lt;b&gt;OnDeserializeUnrecognizedAttribute&lt;/b&gt;&lt;br /&gt;
One great idea I was able to glean from a section of today's talk on custom configuration section handlers was that of the &lt;a href="http://msdn2.microsoft.com/en-us/library/system.configuration.configurationelement.ondeserializeunrecognizedattribute.aspx"&gt;OnDeserializeUnrecognizedAttribute&lt;/a&gt; method.  This is a virtual method that can be overridden from within a custom configuration section handler that will be invoked when an unrecognized attribute is encountered in a configuration element.  This allows for a custom configuration section to use proprietary attributes without requiring those attributes to be added to the recognized schema proper.  An example of this is with the configuration for a set of connection string storage locations.  Nearly all of the locations, whether file, database, smart card, or registry, have the same list of basic attributes.  However, the registry might have additional proprietary attributes for the hive and keypath.  It is not ideal to have to add these attributes to the schema that will contain only null values for every other source.  In this case, it is ideal to let the OnDeserializeUnrecognizedAttribute method handle those two attributes and write a small amount of custom code in that method to retrieve the values from the configuration element.
&lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/63.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/63.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 17:15:04 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/63.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/63.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 2 - Custom Providers</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/62.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Custom Providers&lt;/strong&gt;&lt;br /&gt;
The second part of the discussion is opening with a discussion of custom provider development.  This is of great interest to me as my recent work with the &lt;a href="http://martinfowler.com/eaaDev/ModelViewPresenter.html"&gt;Model View Presenter&lt;/a&gt; pattern has caused me to research and implement &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;dependency injection&lt;/a&gt; for many of the layers of my application.  The current product that I'm working on is implementing the MVP pattern and is using dependency injection to dynamically load a data layer at run time.  There is a need within the product to use a different data access layer assembly for the administrative tools than for the public side of the application.  The murky details behind this decision (which I shall leave aside) are to do with the deployment environment and maintenance cycles of the applications going forward.  There are a few mechanisms for achieving this dynamic load, however I've yet to find conclusive evidence that one method is preferable. &lt;/p&gt;
&lt;p&gt;The idea behind dependency injection is improve the following fairly typical line of code:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;MyClass myClass = new MyClass(); &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;One potential drawback in this line is that the physical class &lt;span style="FONT-FAMILY: Courier, New"&gt;MyClass&lt;/span&gt; has been hard-coded as the only implementation that can exist for &lt;span style="FONT-FAMILY: Courier, New"&gt;myClass&lt;/span&gt;.  If &lt;span style="FONT-FAMILY: Courier, New"&gt;MyClass&lt;/span&gt; implements an interface &lt;span style="FONT-FAMILY: Courier, New"&gt;IMyClass&lt;/span&gt; then it might be desirable in the code to switch out the implementation of the interface &lt;span style="FONT-FAMILY: Courier, New"&gt;IMyClass&lt;/span&gt; that is being used.  The example du jour is switching out an MS SQL data access library for an Oracle data access library.  In that example, both implement the same interface but the application wishes to decide which library to use at runtime via a configuration setting.  This is a common problem in applications that wish to implement several version of a library than perform very similar but ultimately different tasks.  The provider model is based around this need. &lt;/p&gt;
&lt;p&gt;The suggested methodology presented in this talk is to use:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;Type myType = Type.GetType("MyNamespace.MyClassName");&lt;br /&gt;
IMyClass myClass = System.Activator.CreateInstance(myType);&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The theory here is that &lt;span style="FONT-FAMILY: Courier, New"&gt;Type.GetType&lt;/span&gt; returns an object that describes the type to be created.  The &lt;span style="FONT-FAMILY: Courier, New"&gt;System.Activator.CreateInstance&lt;/span&gt; line creates a concrete instance of the requested class except by this mechanism the class has been created using a string name versus a hard-coded class name.  This methodology works for classes that exist within the same assembly, however will not work for classes that exist outside of this assembly.  There is an extension to this will work for classes outside of this assembly. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dynamically Loading Assemblies&lt;/strong&gt;&lt;br /&gt;
In order to extend this methodology to work for classes that are in other assemblies, there is a need to first load that assembly.  This is achieved via the following methodology:&lt;br /&gt;
&lt;span style="FONT-FAMILY: Courier, New"&gt;Assembly asm = Assembly.LoadFile(MyAssemblyFileName);&lt;br /&gt;
IMyClass myClass = asm.CreateInstance(MyClassName);&lt;br /&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The basic change here is that now the concrete class instance is created from the assembly reference versus &lt;span style="FONT-FAMILY: Courier, New"&gt;System.Activator&lt;/span&gt;.  This allows the dyanamically loaded class to reside in a separate assembly.  Now we have the ability to specify which data access layer library is being used within the application at run-time.  All calls within the application are made against the &lt;span style="FONT-FAMILY: Courier, New"&gt;IMyClass&lt;/span&gt; interface, but the implementations now differ based upon the physical data access library that is loaded at run-time. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interface Isolation&lt;/strong&gt;&lt;br /&gt;
Finally, interfaces are isolated into a separate assembly from either (any) of the concrete implementations of that interface.  The reason for this is that we do not want to require a reference from the main application to either of the implementations of the interface.  Such a reference would defeat the purpose of the exercise as it would again tie the application directly to a particular implementation.  Instead the main application references only the assembly that contains the interface.  Now any implementation of that interface can be used from within the main application by dynamically instantiating the implementation using the mechanism above. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/62.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/62.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 17:14:12 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/62.aspx#feedback</comments>
            <slash:comments>45</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/62.aspx</wfw:commentRss>
        </item>
        <item>
            <title>VSLive! Day One - Architecting ASP.NET Applications Part 1</title>
            <link>http://blogs.sftsrc.com/stuart/archive/2007/10/16/61.aspx</link>
            <description>&lt;p&gt;&lt;strong&gt;Getting Situated&lt;/strong&gt;&lt;br /&gt;
For the preconference, I decided to attend &lt;a href="http://www.paulsheriffinnercircle.com/PublicSite/PublicDefault.aspx"&gt;Paul Sherrif's&lt;/a&gt; talk on &lt;a href="http://www.ftponline.com/conferences/vslive/2007/lasvegas/workshops.aspx"&gt;Architecting ASP.NET Applications&lt;/a&gt;.  Fortunately, I was able to get to the room about an hour early and find one of the few seats situated close to a power outlet.  I really didn't want to have to transfer my notes from paper to my laptop later; I'd rather just type them out directly! &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;N-Tier Development Benefits&lt;/strong&gt;&lt;br /&gt;
The workshop has begun with a discussion of n-tier development; the benefits of logically separating services into different libraries and isolating functionality into discreet sections.  The advantages of this approach are that the maintenance and extension of your application are vastly simplified.  Refactoring common methods into reusable libraries minimizes the amount of work involved in fixing bugs because the buggy code needs only be fixed in one location.  Adapting to large-scale architectural changes in the application is also easier if a modular development model is adopted.  Switching out small components to adapt to technology shifts is far easier than making global code changes.  This means that large-scale changes can be handled cheaply and quickly.  The majority of the application libraries do not need to be run through a quality assurance cycle because they were not changed when the maintenance was performed.  Only the new library needs to be tested in addition to running a full integration test, which is still far cheaper that re-testing the entire system.  The following is a table detailing the suggested areas of isolation for an ASP.NET application:&lt;br /&gt;
&lt;/p&gt;
&lt;table bordercolor="#000000" cellspacing="2" cellpadding="2" border="1"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt;Business Rules&lt;/td&gt;
            &lt;td&gt;User Interface&lt;/td&gt;
            &lt;td&gt;Configuration Management&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Data Access Service&lt;/td&gt;
            &lt;td&gt;Exception Management&lt;/td&gt;
            &lt;td&gt;Security Management&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt;Data Layer&lt;/td&gt;
            &lt;td&gt;User Tracking&lt;/td&gt;
            &lt;td&gt;Log Management&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;a href="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1.jpg"&gt;&lt;img border="0" alt="" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1_Thumbnail.jpg" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Configuration Management&lt;/strong&gt;&lt;br /&gt;
As opposed to using the &lt;span style="FONT-FAMILY: Courier, New"&gt;System.Configuration.ConfigurationManager.AppSettings["MyConfigItem"]&lt;/span&gt; approach for reading settings, a custom AppConfigManager class can be built that isolates access to configuration settings into static properties on that class.  The argument for this architecture is that when and if the access mechanism for configuration settings changes in future versions of .NET, the changes will be isolated to only the AppConfigManager class.  This is a valid argument because the mechanism for reading configuration settings changed from .NET 1.1 to .NET 2.0.  In .NET 1.1 we used &lt;span style="FONT-FAMILY: Courier, New"&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.configuration.configurationsettings.aspx"&gt;System.Configuration.ConfigurationSettings&lt;/a&gt;&lt;/span&gt;, however in .NET 2.0 we are encouraged to use &lt;span style="FONT-FAMILY: Courier, New"&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx"&gt;System.Configuration.ConfigurationManager&lt;/a&gt;&lt;/span&gt; instead.  Encapsulating application configuration settings is an architecture I've considered several times before but there is something that always makes me balk at the idea of a class full of statics.  The difference here, which I like, is that a sound justification exists and that the statics aren't just returning constants.  Instead the static is returning a value using the &lt;span style="font-face: Courier, New"&gt;System.Configuration.ConfigurationManager.AppSettings["MyConfigItem"]&lt;/span&gt; mechanism.  This does have the nice effect of isolating the final method of configuration management from the rest of the code in the application.  Should the mechanism for accessing configuration settings change in the future, only the AppConfigManager wrapper class will need to be updated. &lt;/p&gt;
&lt;p&gt;I could be wrong, but I think Paul just compared using Intellisense to "using the force" ala Star Wars: &amp;lt;sigh&amp;gt;.  At least the humor hasn't changed since the last conference I attended.  Actually, so far the guy has been pretty funny so I'll give him a break. &lt;/p&gt;
&lt;p&gt;&lt;img border="0" alt="" src="http://www.stuartthompson.net/subtextblog/images/stuartthompson_net/subtextblog/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1/10-14-2007-VSLiveDayOne-ArchitectingASPNETApplications-Part1-LukeVader.jpg" /&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Custom Collection Classes&lt;/strong&gt;&lt;br /&gt;
The major philosophical question that has arisen so far is whether or not to use custom collection classes when transacting between a data layer and a business tier or user interface layer.  The code samples presented use &lt;a href="http://msdn2.microsoft.com/en-us/library/system.data.datatable.aspx"&gt;&lt;span style="FONT-FAMILY: Courier, New"&gt;DataTable&lt;/span&gt;&lt;/a&gt; instances.  The argument presented is that a &lt;span style="font-face: Courier, New"&gt;DataTable&lt;/span&gt; is actually analogous to a custom collection class as it has proprietary column names within it that correspond to the unique properties and data types of the business object being modeled.  The only concession offered in the workshop is that this does open a potential window for failure if Microsoft decided to drop support for the &lt;span style="font-face: Courier, New"&gt;DataTable&lt;/span&gt; class in favor of a superior class. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Code Generation&lt;/strong&gt;&lt;br /&gt;
For a while now I have separated data adapter classes from object builder classes.  The data adapter classes are responsible for executing sql commands to a database and either writing or reading common data collection classes; such as &lt;a href="http://msdn2.microsoft.com/en-us/library/system.data.idatareader.aspx"&gt;IDataReader&lt;/a&gt;.  The builder classes are responsible for digesting those data collections and building concrete objects from them.  This allows for a nice separation between data interaction and data digestion.  However, I've always written both classes by hand.  They do not present a large chunk of work and I have usually disregarded the cost of coding such small functional classes as being negligible.  Code generation is something that has been suggested for these classes in the past, but I have often found that building the required code generation framework can be just as expensive as writing the classes that are needed.  However, the argument being presented in this workshop for code generation is that if the data builder level classes and stored procedures are generated then schema level changes are reflected more quickly.  This is an interesting advantage to note in the argument for using code generation for parts of the data layer. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deriving Business Rule Objects&lt;/strong&gt;&lt;br /&gt;
The next part of this discussion addresses a second common problem with code generation, that of custom rule application.  A code generator can easily intuit the basic rules that need to be enforced for objects built from a schema, for example that required fields are populated.  However, a code generator cannot easily imply that a &lt;em&gt;cost&lt;/em&gt; field needs to be between certain threshold values.  To address this problem, Paul suggests that a custom business rule object be derived from the generated data class.  The data class implements validation as virtual methods that can be overridden in the custom business class.  The overridden method can then apply the additional validation to enforce proprietary business rules. &lt;/p&gt;&lt;img src="http://blogs.sftsrc.com/stuart/aggbug/61.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Stuart Thompson</dc:creator>
            <guid>http://blogs.sftsrc.com/stuart/archive/2007/10/16/61.aspx</guid>
            <pubDate>Tue, 16 Oct 2007 17:13:33 GMT</pubDate>
            <comments>http://blogs.sftsrc.com/stuart/archive/2007/10/16/61.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://blogs.sftsrc.com/stuart/comments/commentRss/61.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>